func (do *DigitalOcean) CreateImage(image *compute.Image) (*compute.Image, error) { if image.SourceInstance != "" { snapshotName := fmt.Sprintf("%s.%s", image.Name, utils.Uid(16)) err := do.doAction(image.SourceInstance, func(id int) (*godo.Action, *godo.Response, error) { return do.client.DropletActions.Snapshot(id, snapshotName) }) if err != nil { return nil, err } else { return &compute.Image{ ID: "snapshot:" + snapshotName, Name: snapshotName, SourceInstance: image.SourceInstance, }, nil } } else if image.SourceURL != "" { return nil, errors.New("fetching image from URL is not supported") } else { return nil, errors.New("neither source instance nor source URL is set") } }
func (os *OpenStack) CreateInstance(instance *compute.Instance) (*compute.Instance, error) { imageID, err := common.GetMatchingImageID(os, &instance.Image) if err != nil { return nil, err } flavorID, err := common.GetMatchingFlavorID(os, &instance.Flavor) if err != nil { return nil, err } password := instance.Password if password == "" { password = utils.Uid(16) } opts := servers.CreateOpts{ Name: instance.Name, ImageRef: imageID, FlavorRef: flavorID, AdminPass: password, UserData: []byte("#cloud-config\npassword: "******"\nchpasswd: { expire: False }\nssh_pwauth: True\n"), AvailabilityZone: instance.Region, } if instance.NetworkID != "" { opts.Networks = []servers.Network{{UUID: instance.NetworkID}} } if opts.Name == "" { opts.Name = DEFAULT_NAME } createResult := servers.Create(os.ComputeClient, opts) server, err := createResult.Extract() if err != nil { return nil, err } // try to associate floating IP with this VM // do asynchronously since it might fail until network port is created go func() { for try := 0; try < 6; try++ { time.Sleep(4 * time.Second) // find a free floating IP, or find the IP matching requested IP var freeFloatingIP *floatingip.FloatingIP err := floatingip.List(os.ComputeClient).EachPage(func(page pagination.Page) (bool, error) { floatingIPs, err := floatingip.ExtractFloatingIPs(page) if err != nil { return false, err } for _, floatingIP := range floatingIPs { if floatingIP.InstanceID == "" && (instance.IP == "" || floatingIP.IP == instance.IP) { freeFloatingIP = &floatingIP return false, nil } } return true, nil }) if err != nil { continue } else if freeFloatingIP == nil { continue } // associate it err = floatingip.Associate(os.ComputeClient, server.ID, freeFloatingIP.IP).ExtractErr() if err == nil { break } } }() return &compute.Instance{ ID: server.ID, Name: server.Name, Status: os.mapInstanceStatus(server.Status), Password: password, }, nil }
func (e *EC2) CreateInstance(instance *compute.Instance) (*compute.Instance, error) { imageID, err := common.GetMatchingImageID(e, &instance.Image) if err != nil { return nil, err } flavorID, err := common.GetMatchingFlavorID(e, &instance.Flavor) if err != nil { return nil, err } region := DEFAULT_REGION if instance.Region != "" { region = instance.Region } svc := e.getService(region) opts := ec2.RunInstancesInput{ ImageId: aws.String(imageID), InstanceType: aws.String(flavorID), MinCount: aws.Int64(1), MaxCount: aws.Int64(1), } password := instance.Password if password == "" { password = utils.Uid(16) } userData := "#cloud-config\npassword: "******"\nchpasswd: { expire: False }\nssh_pwauth: True\n" opts.UserData = aws.String(base64.StdEncoding.EncodeToString([]byte(userData))) if instance.Flavor.DiskGB > 0 { opts.BlockDeviceMappings = []*ec2.BlockDeviceMapping{ { Ebs: &ec2.EbsBlockDevice{ VolumeSize: aws.Int64(int64(instance.Flavor.DiskGB)), DeleteOnTermination: aws.Bool(true), VolumeType: aws.String("gp2"), }, }, } } if len(instance.PublicKey.Key) > 0 { keyName := utils.Uid(8) _, err := svc.ImportKeyPair(&ec2.ImportKeyPairInput{ KeyName: aws.String(keyName), PublicKeyMaterial: instance.PublicKey.Key, }) if err != nil { return nil, fmt.Errorf("failed to import public key: %v", err) } defer svc.DeleteKeyPair(&ec2.DeleteKeyPairInput{ KeyName: aws.String(keyName), }) opts.KeyName = aws.String(keyName) } res, err := svc.RunInstances(&opts) if err != nil { return nil, err } else if len(res.Instances) != 1 { return nil, fmt.Errorf("attempted to provision a single instance, but reservation contains %d instances", len(res.Instances)) } resInstance := res.Instances[0] return &compute.Instance{ ID: encodeID(String(resInstance.InstanceId), region), Status: e.mapInstanceStatus(String(resInstance.State.Name)), Password: password, }, nil }
func (gc *GoogleCompute) CreateInstance(instance *compute.Instance) (*compute.Instance, error) { imageID, err := common.GetMatchingImageID(gc, &instance.Image) if err != nil { return nil, err } flavorID, err := common.GetMatchingFlavorID(gc, &instance.Flavor) if err != nil { return nil, err } name := utils.UidAlphabet(24, []rune("abcdefghijklmnopqrstuvwxyz")) region := instance.Region if region == "" { region = DEFAULT_REGION } apiInstance := gcompute.Instance{ Name: name, MachineType: fmt.Sprintf("zones/%s/machineTypes/%s", region, flavorID), Disks: []*gcompute.AttachedDisk{ &gcompute.AttachedDisk{ AutoDelete: true, Boot: true, Type: "PERSISTENT", InitializeParams: &gcompute.AttachedDiskInitializeParams{ SourceImage: imageID, DiskSizeGb: int64(instance.Flavor.DiskGB), }, }, }, NetworkInterfaces: []*gcompute.NetworkInterface{ &gcompute.NetworkInterface{ Network: "global/networks/default", AccessConfigs: []*gcompute.AccessConfig{ &gcompute.AccessConfig{ Type: "ONE_TO_ONE_NAT", Name: "External NAT", }, }, }, }, } password := instance.Password if password == "" { password = utils.Uid(16) } userData := "#cloud-config\npassword: "******"\nchpasswd: { expire: False }\nssh_pwauth: True\n" apiInstance.Metadata = &gcompute.Metadata{ Items: []*gcompute.MetadataItems{ &gcompute.MetadataItems{ Key: "user-data", Value: &userData, }, }, } operation, err := gc.waitForOperation(gc.service.Instances.Insert(gc.project, region, &apiInstance)) if err != nil { return nil, err } else { return &compute.Instance{ ID: fmt.Sprintf("%s:%s", basename(operation.Zone), name), Password: password, }, nil } }
func (do *DigitalOcean) CreateInstance(instance *compute.Instance) (*compute.Instance, error) { if instance.PublicKey.ID == "" && len(instance.PublicKey.Key) > 0 { return common.KeypairServiceCreateWrapper(do, do, instance) } imageID, err := do.imageID(&instance.Image) if err != nil { return nil, err } flavorID, err := common.GetMatchingFlavorID(do, &instance.Flavor) if err != nil { return nil, err } password := instance.Password if password == "" { password = utils.Uid(16) } createRequest := &godo.DropletCreateRequest{ Name: instance.Name, Region: instance.Region, Size: flavorID, Image: godo.DropletCreateImage{ ID: imageID, }, IPv6: true, PrivateNetworking: true, UserData: fmt.Sprintf("#cloud-config\nchpasswd:\n list: |\n root:%s\n expire: False\n", password), } if createRequest.Name == "" { createRequest.Name = DEFAULT_NAME } if createRequest.Region == "" { createRequest.Region = DEFAULT_REGION } if instance.PublicKey.ID != "" { keyID, err := strconv.Atoi(instance.PublicKey.ID) if err != nil { return nil, fmt.Errorf("invalid key ID") } createRequest.SSHKeys = []godo.DropletCreateSSHKey{godo.DropletCreateSSHKey{ ID: keyID, }} } droplet, _, err := do.client.Droplets.Create(createRequest) if err != nil { return nil, err } else { return &compute.Instance{ ID: fmt.Sprintf("%d", droplet.ID), Name: droplet.Name, Status: do.mapInstanceStatus(droplet.Status), Username: "******", Password: password, }, nil } }
func (ln *Linode) CreateInstance(instance *compute.Instance) (*compute.Instance, error) { imageID, err := common.GetMatchingImageID(ln, &instance.Image) if err != nil { return nil, err } plan, err := ln.findMatchingPlan(&instance.Flavor) if err != nil { return nil, err } kernelID, err := ln.findKernel() if err != nil { return nil, err } password := instance.Password if password == "" { password = utils.Uid(16) } datacenterAbbrev := instance.Region if datacenterAbbrev == "" { datacenterAbbrev = DEFAULT_DATACENTER } datacenterID, err := ln.findDatacenter(datacenterAbbrev) if err != nil { return nil, err } // create linode linodeID, err := ln.client.CreateLinode(datacenterID, plan.ID) if err != nil { return nil, err } // create disks storage := instance.Flavor.DiskGB if storage == 0 { storage = DEFAULT_STORAGE } totalDiskMB := storage * 1024 swapSize := plan.RAM / 2 diskSize := totalDiskMB - swapSize var diskID int imageParts := strings.SplitN(imageID, ":", 2) if len(imageParts) != 2 { return nil, errors.New("malformed image ID: missing colon") } if imageParts[0] == "distribution" { distributionID, _ := strconv.Atoi(imageParts[1]) diskID, _, err = ln.client.CreateDiskFromDistribution(linodeID, "cloug", distributionID, diskSize, password, "") if err != nil { ln.client.DeleteLinode(linodeID, false) return nil, err } } else if imageParts[0] == "image" { imageID, _ := strconv.Atoi(imageParts[1]) diskID, _, err = ln.client.CreateDiskFromImage(linodeID, "cloug", imageID, diskSize, password, "") if err != nil { ln.client.DeleteLinode(linodeID, false) return nil, err } } else { return nil, errors.New("invalid image type " + imageParts[0]) } swapID, _, err := ln.client.CreateDisk(linodeID, "cloug-swap", "swap", swapSize, linode.CreateDiskOptions{}) if err != nil { ln.client.DeleteLinode(linodeID, false) return nil, err } _, err = ln.client.CreateConfig(linodeID, kernelID, "cloug", []int{diskID, swapID}, linode.CreateConfigOptions{}) if err != nil { ln.client.DeleteLinode(linodeID, false) return nil, err } else { ln.client.BootLinode(linodeID) return &compute.Instance{ ID: strconv.Itoa(linodeID), Password: password, }, nil } }