// serveOldInstance looks on GCE for an instance such as defined in depl.Conf, and if // found, serves the appropriate page depending on whether the instance is usable. It does // not serve anything if the instance is not found. func (h *DeployHandler) serveOldInstance(w http.ResponseWriter, br blob.Ref, depl *Deployer) (found bool) { inst, err := depl.Get() if err != nil { // TODO(mpl,bradfitz): log or do something more // drastic if the error is something other than // instance not found. return false } var sigs map[string]string cert, _, err := depl.getInstalledTLS() if err == nil { sigs, err = httputil.CertFingerprints(cert) if err != nil { err = fmt.Errorf("could not get fingerprints of certificate: %v", err) } } if err != nil { h.logger.Printf("Instance (%v, %v, %v) already exists, but error getting its certificate: %v", depl.Conf.Project, depl.Conf.Name, depl.Conf.Zone, err) h.serveErrorPage(w, fmt.Errorf("Instance already running at %v. You need to manually delete the old one before creating a new one.", addr(inst)), helpDeleteInstance, ) return true } var existPassword string for _, item := range inst.Metadata.Items { if item.Key == "camlistore-password" { existPassword = *(item.Value) } } if depl.Conf.Password != "" && existPassword != depl.Conf.Password { h.logger.Printf("Instance (%v, %v, %v) already exists, but with different password", depl.Conf.Project, depl.Conf.Name, depl.Conf.Zone) h.serveErrorPage(w, fmt.Errorf("Instance already running at %v. You need to manually delete the old one before creating a new one.", addr(inst)), helpDeleteInstance, ) return true } h.logger.Printf("Reusing existing instance for (%v, %v, %v)", depl.Conf.Project, depl.Conf.Name, depl.Conf.Zone) if err := h.recordState(br, &creationState{ InstConf: br, InstAddr: addr(inst), CertFingerprintSHA1: sigs["SHA-1"], CertFingerprintSHA256: sigs["SHA-256"], Exists: true, }); err != nil { h.logger.Printf("Could not record creation state for %v: %v", br, err) h.serveErrorPage(w, fmt.Errorf("An error occurred while recording the state of your instance. %v", fileIssue(br.String()))) return true } h.serveProgress(w, br) return true }
// setupHTTPS uploads to the configuration bucket the certificate and key used by the // instance for HTTPS. It generates them if d.Conf.CertFile or d.Conf.KeyFile is not defined. // It should be called after setBuckets. func (d *Deployer) setupHTTPS(storageService *storage.Service) error { installedCert, _, err := d.getInstalledTLS() if err != nil && err != os.ErrNotExist { return err } if err == nil { sigs, err := httputil.CertFingerprints(installedCert) if err != nil { return fmt.Errorf("could not get fingerprints of certificate: %v", err) } d.certFingerprints = sigs if Verbose { d.Printf("Reusing existing certificate with fingerprint %v", sigs["SHA-256"]) } return nil } var cert, key io.ReadCloser if d.Conf.CertFile != "" && d.Conf.KeyFile != "" { // Note: it is not a bug that we do not set d.certFingerprint in that case, because only // the wizard template cares about d.certFingerprint, and we never get here with the wizard // - but only with camdeploy. cert, err = os.Open(d.Conf.CertFile) if err != nil { return err } defer cert.Close() key, err = os.Open(d.Conf.KeyFile) if err != nil { return err } defer key.Close() } else { if Verbose { d.Printf("Generating self-signed certificate for %v ...", d.Conf.Hostname) } certBytes, keyBytes, err := httputil.GenSelfTLS(d.Conf.Hostname) if err != nil { return fmt.Errorf("error generating certificates: %v", err) } sigs, err := httputil.CertFingerprints(certBytes) if err != nil { return fmt.Errorf("could not get fingerprints of certificate: %v", err) } d.certFingerprints = sigs if Verbose { d.Printf("Wrote certificate with SHA-256 fingerprint %s", sigs["SHA-256"]) } cert = ioutil.NopCloser(bytes.NewReader(certBytes)) key = ioutil.NopCloser(bytes.NewReader(keyBytes)) } if Verbose { d.Print("Uploading certificate and key...") } _, err = storageService.Objects.Insert(d.Conf.bucketBase(), &storage.Object{Name: path.Join(configDir, certFilename())}).Media(cert).Do() if err != nil { return fmt.Errorf("cert upload failed: %v", err) } _, err = storageService.Objects.Insert(d.Conf.bucketBase(), &storage.Object{Name: path.Join(configDir, keyFilename())}).Media(key).Do() if err != nil { return fmt.Errorf("key upload failed: %v", err) } return nil }