From 0e31e41767666f17ab4bad33fec25c20837db3fd Mon Sep 17 00:00:00 2001 From: mpl Date: Tue, 27 Jan 2015 18:06:07 +0100 Subject: [PATCH] deploy/gce: fix project label, check project id exists Issue #571 Also moved the "file an issue" msg appending to sooner, so I can do a proper error type check, instead of a lame string contents check. Also fixed progress msg as per Aaron suggestion. Change-Id: Ifa31a8d58cdf20d5068b4db4f7ab0370633bbd34 --- pkg/deploy/gce/deploy.go | 49 +++++++++++++++++++++++++++++++++++---- pkg/deploy/gce/handler.go | 21 +++++++++-------- 2 files changed, 55 insertions(+), 15 deletions(-) diff --git a/pkg/deploy/gce/deploy.go b/pkg/deploy/gce/deploy.go index 90b69b63e..39ad0166d 100644 --- a/pkg/deploy/gce/deploy.go +++ b/pkg/deploy/gce/deploy.go @@ -147,11 +147,6 @@ func (e instanceExistsError) Error() string { return msg } -func isInstanceExistsError(errMsg string) bool { - return strings.Contains(errMsg, "some instance(s) already exist as (") && - strings.Contains(errMsg, "), you need to delete them first.") -} - // projectHasInstance checks for all the possible zones if there's already an instance for the project. // It returns the name of the zone at the first instance it finds, if any. func (d *Deployer) projectHasInstance() (zone string, err error) { @@ -203,9 +198,53 @@ func (d *Deployer) projectHasInstance() (zone string, err error) { } } +type projectIDError struct { + id string + cause error +} + +func (e projectIDError) Error() string { + if e.id == "" { + panic("projectIDError without an id") + } + if e.cause != nil { + return fmt.Sprintf("project ID error for %v: %v", e.id, e.cause) + } + return fmt.Sprintf("project ID error for %v", e.id) +} + +func (d *Deployer) checkProjectID() error { + // TODO(mpl): cache the computeService in Deployer, instead of recreating a new one everytime? + s, err := compute.New(d.Cl) + if err != nil { + return projectIDError{ + id: d.Conf.Project, + cause: err, + } + } + project, err := compute.NewProjectsService(s).Get(d.Conf.Project).Do() + if err != nil { + return projectIDError{ + id: d.Conf.Project, + cause: err, + } + } + if project.Name != d.Conf.Project { + return projectIDError{ + id: d.Conf.Project, + cause: fmt.Errorf("project ID do not match: got %q, wanted %q", project.Name, d.Conf.Project), + } + } + return nil +} + // Create sets up and starts a Google Compute Engine instance as defined in d.Conf. It // creates the necessary Google Storage buckets beforehand. func (d *Deployer) Create(ctx *context.Context) (*compute.Instance, error) { + if err := d.checkProjectID(); err != nil { + return nil, err + } + computeService, _ := compute.New(d.Cl) storageService, _ := storage.New(d.Cl) diff --git a/pkg/deploy/gce/handler.go b/pkg/deploy/gce/handler.go index db1b53a4a..cd3569401 100644 --- a/pkg/deploy/gce/handler.go +++ b/pkg/deploy/gce/handler.go @@ -328,7 +328,14 @@ func (h *DeployHandler) serveCallback(w http.ResponseWriter, r *http.Request) { } if err != nil { h.Printf("could not create instance: %v", err) - state.Err = fmt.Sprintf("%v", err) + switch e := err.(type) { + case instanceExistsError: + state.Err = fmt.Sprintf("%v %v", e, helpDeleteInstance) + case projectIDError: + state.Err = fmt.Sprintf("%v", e) + default: + state.Err = fmt.Sprintf("%v. %v", err, fileIssue(br.String())) + } } else { state.InstAddr = addr(inst) state.Success = true @@ -428,13 +435,7 @@ func (h *DeployHandler) serveInstanceState(w http.ResponseWriter, r *http.Reques } if state.Err != "" { // No need to log that error here since we're already doing it in serveCallback - errMsg := fmt.Sprintf("An error occurred while creating your instance: %q. ", state.Err) - if isInstanceExistsError(state.Err) { - errMsg += helpDeleteInstance - } else { - errMsg += fileIssue(br) - } - h.serveError(w, errors.New(errMsg)) + h.serveError(w, fmt.Errorf("An error occurred while creating your instance: %q. ", state.Err)) return } if state.Success || state.Exists { @@ -754,7 +755,7 @@ var tplHTML = ` img.src = {{.Piggygif}}; var msg = document.createElement('span'); - msg.innerHTML = 'Please wait (up to a couple of minutes) while piggy creates your instance...'; + msg.innerHTML = 'Please wait (up to a couple of minutes) while we create your instance...'; msg.style.boxSizing = 'border-box'; msg.style.color = '#444'; msg.style.display = 'block'; @@ -849,7 +850,7 @@ var tplHTML = `

{{.Help.genCert}}

- +
Project name
Project ID
Domain name
Zone
Instance name