func (cl *cloudLaunch) instanceDisk() *compute.AttachedDisk { imageURL, err := gceutil.CoreOSImageURL(cl.oauthClient) if err != nil { log.Fatalf("error looking up latest CoreOS stable image: %v", err) } diskName := cl.instName() + "-coreos-stateless-pd" var diskType string if cl.SSD { diskType = cl.projectAPIURL() + "/zones/" + cl.zone() + "/diskTypes/pd-ssd" } return &compute.AttachedDisk{ AutoDelete: true, Boot: true, Type: "PERSISTENT", InitializeParams: &compute.AttachedDiskInitializeParams{ DiskName: diskName, SourceImage: imageURL, DiskSizeGb: 50, DiskType: diskType, }, } }
// createInstance starts the creation of the Compute Engine instance and waits for the // result of the creation operation. It should be called after setBuckets and setupHTTPS. func (d *Deployer) createInstance(computeService *compute.Service, ctx context.Context) error { coreosImgURL, err := gceutil.CoreOSImageURL(d.Client) if err != nil { return fmt.Errorf("error looking up latest CoreOS stable image: %v", err) } prefix := projectsAPIURL + d.Conf.Project machType := prefix + "/zones/" + d.Conf.Zone + "/machineTypes/" + d.Conf.Machine config := cloudConfig(d.Conf) instance := &compute.Instance{ Name: d.Conf.Name, Description: "Camlistore server", MachineType: machType, Disks: []*compute.AttachedDisk{ { AutoDelete: true, Boot: true, Type: "PERSISTENT", InitializeParams: &compute.AttachedDiskInitializeParams{ DiskName: d.Conf.Name + "-coreos-stateless-pd", SourceImage: coreosImgURL, }, }, }, Tags: &compute.Tags{ Items: []string{"http-server", "https-server"}, }, Metadata: &compute.Metadata{ Items: []*compute.MetadataItems{ { Key: "camlistore-username", Value: googleapi.String(camliUsername), }, { Key: "camlistore-password", Value: googleapi.String(randPassword()), }, { Key: "camlistore-blob-dir", Value: googleapi.String("gs://" + d.Conf.blobDir), }, { Key: "camlistore-config-dir", Value: googleapi.String("gs://" + d.Conf.configDir), }, { Key: "user-data", Value: googleapi.String(config), }, }, }, NetworkInterfaces: []*compute.NetworkInterface{ &compute.NetworkInterface{ AccessConfigs: []*compute.AccessConfig{ &compute.AccessConfig{ Type: "ONE_TO_ONE_NAT", Name: "External NAT", }, }, Network: prefix + "/global/networks/default", }, }, ServiceAccounts: []*compute.ServiceAccount{ { Email: "default", Scopes: []string{ logging.Scope, compute.DevstorageFullControlScope, compute.ComputeScope, "https://www.googleapis.com/auth/sqlservice", "https://www.googleapis.com/auth/sqlservice.admin", }, }, }, } if d.Conf.Hostname != "" && d.Conf.Hostname != "localhost" { instance.Metadata.Items = append(instance.Metadata.Items, &compute.MetadataItems{ Key: "camlistore-hostname", Value: googleapi.String(d.Conf.Hostname), }) } const localMySQL = false // later if localMySQL { instance.Disks = append(instance.Disks, &compute.AttachedDisk{ AutoDelete: false, Boot: false, Type: "PERSISTENT", InitializeParams: &compute.AttachedDiskInitializeParams{ DiskName: "camlistore-mysql-index-pd", DiskSizeGb: 4, }, }) } if Verbose { d.Print("Creating instance...") } op, err := computeService.Instances.Insert(d.Conf.Project, d.Conf.Zone, instance).Do() if err != nil { return fmt.Errorf("failed to create instance: %v", err) } opName := op.Name if Verbose { d.Printf("Created. Waiting on operation %v", opName) } OpLoop: for { select { case <-ctx.Done(): return ctx.Err() default: } time.Sleep(2 * time.Second) op, err := computeService.ZoneOperations.Get(d.Conf.Project, d.Conf.Zone, opName).Do() if err != nil { return fmt.Errorf("failed to get op %s: %v", opName, err) } switch op.Status { case "PENDING", "RUNNING": if Verbose { d.Printf("Waiting on operation %v", opName) } continue case "DONE": if op.Error != nil { for _, operr := range op.Error.Errors { d.Printf("Error: %+v", operr) } return fmt.Errorf("failed to start.") } if Verbose { d.Printf("Success. %+v", op) } break OpLoop default: return fmt.Errorf("unknown status %q: %+v", op.Status, op) } } return nil }