Merge "deploy/gce: fix project label, check project id exists"

This commit is contained in:
mpl 2015-01-27 22:00:37 +00:00 committed by Gerrit Code Review
commit ad8b72d1d9
2 changed files with 55 additions and 15 deletions

View File

@ -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)

View File

@ -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 = `
<p> {{.Help.genCert}} </p>
<table border=0 cellpadding=3>
<tr><td align=right>Project name</td><td><input name="project" size=50 value=""></td></tr>
<tr><td align=right>Project ID</td><td><input name="project" size=50 value=""></td></tr>
<tr><td align=right><a href="{{.Help.domainName}}">Domain name</a></td><td><input name="hostname" size=50 value=""></td></tr>
<tr><td align=right><a href="{{.Help.zones}}">Zone</a></td><td><input name="zone" size=50 value="{{.Defaults.zone}}"></td></tr>
<tr><td align=right>Instance name</td><td><input name="name" size=50 value="{{.Defaults.name}}"></td></tr>