func (cs *CloudStack) CreateInstance(instance *compute.Instance) (*compute.Instance, error) { if instance.Image.ID == "" { return nil, errors.New("instance image ID must be set") } flavorID, err := common.GetMatchingFlavorID(cs, &instance.Flavor) if err != nil { return nil, err } parts := strings.Split(flavorID, "/") if len(parts) != 2 { return nil, fmt.Errorf("invalid service / disk offering: %s", flavorID) } opts := api.DeployVirtualMachineOptions{ ServiceOffering: parts[0], DiskOffering: parts[1], Template: instance.Image.ID, Network: instance.NetworkID, Name: instance.Name, } id, jobid, err := cs.client.DeployVirtualMachine(&opts) if err != nil { return nil, err } return &compute.Instance{ ID: id, Name: instance.Name, JobID: jobid, }, nil }
func (do *DigitalOcean) ResizeInstance(instanceID string, flavor *compute.Flavor) error { flavorID, err := common.GetMatchingFlavorID(do, flavor) if err != nil { return err } return do.doAction(instanceID, func(id int) (*godo.Action, *godo.Response, error) { return do.client.DropletActions.Resize(id, flavorID, true) }) }
func (lobster *Lobster) ResizeInstance(instanceID string, flavor *compute.Flavor) error { flavorID, err := common.GetMatchingFlavorID(lobster, flavor) if err != nil { return err } flavorIDInt, err := strconv.Atoi(flavorID) if err != nil { return fmt.Errorf("invalid flavor ID: %s", flavorID) } return lobster.instanceAction(instanceID, func(id int) error { return lobster.client.VmResize(id, flavorIDInt) }) }
func (lobster *Lobster) CreateInstance(instance *compute.Instance) (*compute.Instance, error) { if instance.PublicKey.ID == "" && len(instance.PublicKey.Key) > 0 { return common.KeypairServiceCreateWrapper(lobster, lobster, instance) } imageID, err := common.GetMatchingImageID(lobster, &instance.Image) if err != nil { return nil, err } flavorID, err := common.GetMatchingFlavorID(lobster, &instance.Flavor) if err != nil { return nil, err } imageIDInt, err := strconv.Atoi(imageID) if err != nil { return nil, fmt.Errorf("invalid image ID: %s", imageID) } flavorIDInt, err := strconv.Atoi(flavorID) if err != nil { return nil, fmt.Errorf("invalid flavor ID: %s", flavorID) } name := instance.Name if name == "" { name = DEFAULT_NAME } var clientOptions api.VmCreateOptions if instance.PublicKey.ID != "" { clientOptions.KeyId, err = strconv.Atoi(instance.PublicKey.ID) if err != nil { return nil, fmt.Errorf("invalid key ID: %s", instance.PublicKey.ID) } } vmID, err := lobster.client.VmCreate(name, flavorIDInt, imageIDInt, &clientOptions) if err != nil { return nil, err } else { return &compute.Instance{ ID: strconv.Itoa(vmID), }, nil } }
func (ln *Linode) findMatchingPlan(flavor *compute.Flavor) (*linode.Plan, error) { flavorID, err := common.GetMatchingFlavorID(ln, flavor) if err != nil { return nil, err } planID, err := strconv.Atoi(flavorID) if err != nil { return nil, fmt.Errorf("invalid flavor ID %s", flavorID) } plans, err := ln.client.ListPlans() if err != nil { return nil, fmt.Errorf("failed to list plans") } for _, plan := range plans { if plan.ID == planID { return plan, nil } } return nil, fmt.Errorf("could not find plan with id=%d", planID) }
func (ln *LunaNode) CreateInstance(instance *compute.Instance) (*compute.Instance, error) { imageID, err := common.GetMatchingImageID(ln, &instance.Image) if err != nil { return nil, err } flavorID, err := common.GetMatchingFlavorID(ln, &instance.Flavor) if err != nil { return nil, err } imageIDInt, err := strconv.Atoi(imageID) if err != nil { return nil, fmt.Errorf("invalid image ID: %s", imageID) } flavorIDInt, err := strconv.Atoi(flavorID) if err != nil { return nil, fmt.Errorf("invalid flavor ID: %s", flavorID) } region := instance.Region if region == "" { region = DEFAULT_REGION } name := instance.Name if name == "" { name = DEFAULT_NAME } vmId, err := ln.api.VmCreateImage(region, name, flavorIDInt, imageIDInt) if err != nil { return nil, err } else { return &compute.Instance{ ID: fmt.Sprintf("%d", vmId), }, nil } }
func (vt *Vultr) CreateInstance(instance *compute.Instance) (*compute.Instance, error) { if instance.PublicKey.ID == "" && len(instance.PublicKey.Key) > 0 { return common.KeypairServiceCreateWrapper(vt, vt, instance) } imageID, err := common.GetMatchingImageID(vt, &instance.Image) if err != nil { return nil, err } flavorID, err := common.GetMatchingFlavorID(vt, &instance.Flavor) if err != nil { return nil, err } flavorIDInt, err := strconv.Atoi(flavorID) if err != nil { return nil, fmt.Errorf("invalid flavor ID: %s", flavorID) } name := instance.Name if name == "" { name = DEFAULT_NAME } serverOptions := &vultr.ServerOptions{ PrivateNetworking: instance.Detail("private_networking", "yes") == "yes", IPV6: instance.Detail("ipv6", "yes") == "yes", AutoBackups: instance.Detail("auto_backups", "no") == "yes", DontNotifyOnActivate: instance.Detail("dont_notify_on_activate", "no") == "yes", } imageParts := strings.SplitN(imageID, ":", 2) if len(imageParts) != 2 { return nil, fmt.Errorf("malformed image ID: missing colon") } if imageParts[0] == "iso" { customOSID, err := vt.findOSByName("Custom") if err != nil { return nil, fmt.Errorf("failed to get custom OS for creation from ISO: %v", err) } serverOptions.OS = customOSID serverOptions.ISO, _ = strconv.Atoi(imageParts[1]) } else if imageParts[0] == "os" { serverOptions.OS, _ = strconv.Atoi(imageParts[1]) } else if imageParts[0] == "snapshot" { snapshotOSID, err := vt.findOSByName("Snapshot") if err != nil { return nil, fmt.Errorf("failed to get snapshot OS for creation from snapshot: %v", err) } serverOptions.OS = snapshotOSID serverOptions.Snapshot = imageParts[1] } else if imageParts[0] == "app" { appOSID, err := vt.findOSByName("Application") if err != nil { return nil, fmt.Errorf("failed to get application OS for creation from application: %v", err) } serverOptions.OS = appOSID serverOptions.Application, _ = strconv.Atoi(imageParts[1]) } else { return nil, fmt.Errorf("invalid image type " + imageParts[0]) } if instance.PublicKey.ID != "" { serverOptions.SSHKey = instance.PublicKey.ID } region := DEFAULT_REGION if instance.Region != "" { region = instance.Region } regionID, err := vt.findRegion(region) if err != nil { return nil, fmt.Errorf("failed to identify region ID: %v", err) } server, err := vt.client.CreateServer(name, regionID, flavorIDInt, serverOptions) if err != nil { return nil, err } else { return &compute.Instance{ ID: server.ID, }, nil } }
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 } }