func (this *DigitalOcean) VmCreate(vm *lobster.VirtualMachine, options *lobster.VMIVmCreateOptions) (string, error) { password := utils.Uid(16) image, err := this.findImage(options.ImageIdentification) if err != nil { return "", err } plan := vm.Plan.Identification if plan == "" { plan = this.getPlanName(vm.Plan.Ram) } createRequest := &godo.DropletCreateRequest{ Name: vm.Name, Region: this.region, Size: plan, Image: godo.DropletCreateImage{ ID: image.ID, }, IPv6: true, PrivateNetworking: true, UserData: fmt.Sprintf("#cloud-config\nchpasswd:\n list: |\n root:%s\n expire: False\n", password), } droplet, _, err := this.client.Droplets.Create(createRequest) if err != nil { return "", err } else { vm.SetMetadata("password", password) return fmt.Sprintf("%d", droplet.ID), nil } }
func (this *SolusVM) VmInfo(vm *lobster.VirtualMachine) (*lobster.VmInfo, error) { vmIdentificationInt, _ := strconv.Atoi(vm.Identification) apiInfo, err := this.Api.VmInfo(vmIdentificationInt) if err != nil { return nil, err } bwUsed, _ := strconv.ParseInt(strings.Split(apiInfo.Bandwidth, ",")[1], 10, 64) info := lobster.VmInfo{ Ip: apiInfo.Ip, PrivateIp: apiInfo.InternalIps, Status: strings.Title(apiInfo.State), BandwidthUsed: bwUsed, LoginDetails: "username: root; password: "******"password", "unknown"), } if this.VirtType == "openvz" { info.Actions = append(info.Actions, &lobster.VmActionDescriptor{ Action: "tuntap", Name: "TUN/TAP", Description: "Enable or disable TUN/TAP.", Options: map[string]string{ "enable": "On", "disable": "Off", }, }) } return &info, nil }
func (cs *CloudStack) VmInfo(vm *lobster.VirtualMachine) (*lobster.VmInfo, error) { details, err := cs.client.GetVirtualMachine(vm.Identification) if err != nil { return nil, err } status := details.State if status == "Running" { status = "Online" } else if status == "Stopped" { status = "Offline" } info := lobster.VmInfo{ Status: status, LoginDetails: "password: "******"password", "unknown"), } for _, nic := range details.Nics { if ipaddr.IsPrivate(nic.Addr) { info.PrivateIp = nic.Addr } else { info.Ip = nic.Addr } } return &info, nil }
func (cloug *Cloug) VmInfo(vm *lobster.VirtualMachine) (*lobster.VmInfo, error) { instance, err := cloug.service.GetInstance(vm.Identification) if err != nil { return nil, err } username := vm.Metadata("username", instance.Username) if username == "" { username = "******" } password := vm.Metadata("password", instance.Password) if password == "" { password = "******" } return &lobster.VmInfo{ Ip: instance.IP, PrivateIp: instance.PrivateIP, Status: strings.Title(string(instance.Status)), Hostname: instance.Name, BandwidthUsed: instance.BandwidthUsed, LoginDetails: fmt.Sprintf("username: %s; password: %s", username, password), Details: instance.Details, OverrideCapabilities: true, CanVnc: cloug.vncService != nil, CanReimage: cloug.reimageService != nil, CanResize: cloug.resizeService != nil, CanSnapshot: cloug.imageService != nil, CanAddresses: cloug.addressService != nil, }, nil }
func (cloug *Cloug) VmCreate(vm *lobster.VirtualMachine, imageIdentification string) (string, error) { instance, err := cloug.service.CreateInstance(&compute.Instance{ Name: vm.Name, Region: cloug.config.Region, NetworkID: cloug.config.NetworkID, Image: compute.Image{ID: imageIdentification}, Flavor: compute.Flavor{ ID: vm.Plan.Identification, NumCores: vm.Plan.Cpu, DiskGB: vm.Plan.Storage, MemoryMB: vm.Plan.Ram, TransferGB: vm.Plan.Bandwidth, }, }) if err != nil { return "", err } if instance.Username != "" { vm.SetMetadata("username", instance.Username) } if instance.Password != "" { vm.SetMetadata("password", instance.Password) } return instance.ID, nil }
func (this *Linode) VmInfo(vm *lobster.VirtualMachine) (*lobster.VmInfo, error) { linodeID, _ := strconv.Atoi(vm.Identification) linode, err := this.client.GetLinode(linodeID) if err != nil { return nil, err } info := lobster.VmInfo{ Hostname: vm.Name, LoginDetails: "password: "******"password", "unknown"), } if linode.StatusString == "Running" { info.Status = "Online" } else if linode.StatusString == "Powered Off" { info.Status = "Offline" } else { info.Status = linode.StatusString } ips, err := this.client.ListIP(linodeID) if err == nil { for _, ip := range ips { if ip.IsPublic == 1 { info.Ip = ip.Address } else { info.PrivateIp = ip.Address } } } return &info, nil }
func (this *SolusVM) VmCreate(vm *lobster.VirtualMachine, imageIdentification string) (string, error) { name := vm.Name if len(name) < 4 { name += ".example.com" } vmId, password, err := this.Api.VmCreate(this.VirtType, this.NodeGroup, name, imageIdentification, vm.Plan.Ram, vm.Plan.Storage, vm.Plan.Cpu) vm.SetMetadata("password", password) return fmt.Sprintf("%d", vmId), err }
func (this *Fake) saveAddresses(vm *lobster.VirtualMachine, addresses []*lobster.IpAddress) { str := "" for _, address := range addresses { if str != "" { str += "," } str += address.Ip + ":" + address.Hostname } vm.SetMetadata("addresses", str) }
func (this *Linode) VmSnapshot(vm *lobster.VirtualMachine) (string, error) { linodeID, _ := strconv.Atoi(vm.Identification) diskID, err := strconv.Atoi(vm.Metadata("diskid", "")) if err != nil { return "", errors.New("failed to retrieve disk ID from metadata") } imageID, _, err := this.client.ImagizeDisk(linodeID, diskID, "lobster image") if err != nil { return "", err } else { return fmt.Sprintf("image:%d", imageID), nil } }
func (this *DigitalOcean) VmInfo(vm *lobster.VirtualMachine) (*lobster.VmInfo, error) { vmIdentification, _ := strconv.Atoi(vm.Identification) droplet, _, err := this.client.Droplets.Get(vmIdentification) if err != nil { return nil, err } info := lobster.VmInfo{ Hostname: droplet.Name, LoginDetails: "username: root; password: "******"password", "unknown"), } for _, addr4 := range droplet.Networks.V4 { if addr4.Type == "public" { info.Ip = addr4.IPAddress } else if addr4.Type == "private" { info.PrivateIp = addr4.IPAddress } } if droplet.Status == "active" { info.Status = "Online" } else if droplet.Status == "off" { info.Status = "Offline" } else { info.Status = strings.Title(droplet.Status) } // list droplet actions var pendingActions []string actionList, _, err := this.client.Droplets.Actions(droplet.ID, &godo.ListOptions{PerPage: 25}) if err == nil { for _, action := range actionList { if action.Status == "in-progress" { pendingActions = append(pendingActions, action.Type) } } if len(pendingActions) >= 1 { info.Details = make(map[string]string) if len(pendingActions) == 1 { info.Details["Pending action"] = pendingActions[0] } else { info.Details["Pending actions"] = strings.Join(pendingActions, ", ") } } } return &info, nil }
func (this *Fake) VmAddresses(vm *lobster.VirtualMachine) ([]*lobster.IpAddress, error) { var addresses []*lobster.IpAddress for _, addrString := range strings.Split(vm.Metadata("addresses", ""), ",") { addrString = strings.TrimSpace(addrString) if addrString != "" { parts := strings.Split(addrString, ":") ipAddr := &lobster.IpAddress{ Ip: parts[0], PrivateIp: "255.255.255.255", CanRdns: true, } if len(parts) > 1 { ipAddr.Hostname = parts[1] } addresses = append(addresses, ipAddr) } } return addresses, nil }
func (cloug *Cloug) VmInfo(vm *lobster.VirtualMachine) (*lobster.VmInfo, error) { instance, err := cloug.service.GetInstance(vm.Identification) if err != nil { return nil, err } username := vm.Metadata("username", instance.Username) if username == "" { username = "******" } password := vm.Metadata("password", instance.Password) if password == "" { password = "******" } info := &lobster.VmInfo{ Ip: instance.IP, PrivateIp: instance.PrivateIP, Status: strings.Title(string(instance.Status)), Hostname: instance.Name, BandwidthUsed: instance.BandwidthUsed, LoginDetails: fmt.Sprintf("username: %s; password: %s", username, password), Details: instance.Details, OverrideCapabilities: true, CanVnc: cloug.vncService != nil, CanReimage: cloug.reimageService != nil, CanResize: cloug.resizeService != nil, CanSnapshot: cloug.imageService != nil, CanAddresses: cloug.addressService != nil, } for _, action := range instance.Actions { info.Actions = append(info.Actions, &lobster.VmActionDescriptor{ Action: hex.EncodeToString([]byte(action.Label)), Name: action.Label, Description: action.Description, Options: action.Options, }) } return info, nil }
func (cloug *Cloug) VmCreate(vm *lobster.VirtualMachine, options *lobster.VMIVmCreateOptions) (string, error) { tmpl := compute.Instance{ Name: vm.Name, Region: cloug.config.Region, NetworkID: cloug.config.NetworkID, Image: compute.Image{ID: options.ImageIdentification}, Flavor: compute.Flavor{ ID: vm.Plan.Identification, NumCores: vm.Plan.Cpu, DiskGB: vm.Plan.Storage, MemoryMB: vm.Plan.Ram, TransferGB: vm.Plan.Bandwidth, }, } if options.SSHKey.Key != "" { tmpl.PublicKey = compute.PublicKey{ Key: []byte(options.SSHKey.Key), } } tmpl.Details = make(map[string]string) for k, v := range vm.Plan.Metadata { tmpl.Details[k] = v } instance, err := cloug.service.CreateInstance(&tmpl) if err != nil { return "", err } if instance.Username != "" { vm.SetMetadata("username", instance.Username) } if instance.Password != "" { vm.SetMetadata("password", instance.Password) } return instance.ID, nil }
func (this *OpenStack) VmInfo(vm *lobster.VirtualMachine) (*lobster.VmInfo, error) { server, err := servers.Get(this.ComputeClient, vm.Identification).Extract() if err != nil { return nil, err } status := server.Status if status == "ACTIVE" { status = "Online" } else if status == "SHUTOFF" { status = "Offline" } info := lobster.VmInfo{ Status: status, Hostname: server.Name, LoginDetails: "password: "******"password", "unknown"), } servers.ListAddresses(this.ComputeClient, vm.Identification).EachPage(func(page pagination.Page) (bool, error) { addresses, err := servers.ExtractAddresses(page) if err != nil { return false, err } for _, networkAddresses := range addresses { for _, addr := range networkAddresses { if ipaddr.IsPrivate(addr.Address) { info.PrivateIp = addr.Address } else { info.Ip = addr.Address } } } return true, nil }) return &info, nil }
func (cs *CloudStack) VmCreate(vm *lobster.VirtualMachine, imageIdentification string) (string, error) { var serviceOfferingID, diskOfferingID string var err error if vm.Plan.Identification == "" { serviceOfferingID, err = cs.findServiceOffering(vm.Plan.Cpu, vm.Plan.Ram) if err != nil { return "", err } diskOfferingID, err = cs.findDiskOffering(vm.Plan.Storage) if err != nil { return "", err } } else { parts := strings.Split(vm.Plan.Identification, ":") if len(parts) != 2 { return "", errors.New("plan identification does not contain two colon-separated parts") } serviceOfferingID = parts[0] diskOfferingID = parts[1] } id, jobid, err := cs.client.DeployVirtualMachine(serviceOfferingID, diskOfferingID, imageIdentification) if err != nil { return "", err } vm.SetMetadata("password", "pending") go func() { deadline := time.Now().Add(time.Minute) for time.Now().Before(deadline) { time.Sleep(5 * time.Second) result, _ := cs.client.QueryDeployJob(jobid) if result != nil { vm.SetMetadata("password", result.Password) return } } // time limit exceeded vm.SetMetadata("password", "unknown") }() return id, nil }
func (this *Fake) VmCreate(vm *lobster.VirtualMachine, imageIdentification string) (string, error) { this.CountCreate++ vm.SetMetadata("addresses", "127.0.0.1:") return "fake", nil }
func (this *Linode) VmCreate(vm *lobster.VirtualMachine, imageIdentification string) (string, error) { var planID int if vm.Plan.Identification != "" { planID, _ = strconv.Atoi(vm.Plan.Identification) } else { var err error planID, err = this.findMatchingPlan(vm.Plan) if err != nil { return "", err } } kernelID, err := this.findKernel() if err != nil { return "", err } password := utils.Uid(16) // create linode linodeID, err := this.client.CreateLinode(this.datacenterID, planID) if err != nil { return "", err } // create disks totalDiskMB := vm.Plan.Storage * 1024 swapSize := vm.Plan.Ram / 2 diskSize := totalDiskMB - swapSize var diskID int imageParts := strings.SplitN(imageIdentification, ":", 2) if len(imageParts) != 2 { return "", errors.New("malformed image identification: missing colon") } if imageParts[0] == "distribution" { distributionID, _ := strconv.Atoi(imageParts[1]) diskID, _, err = this.client.CreateDiskFromDistribution(linodeID, "lobster", distributionID, diskSize, password, "") if err != nil { this.client.DeleteLinode(linodeID, false) return "", err } } else if imageParts[0] == "image" { imageID, _ := strconv.Atoi(imageParts[1]) diskID, _, err = this.client.CreateDiskFromImage(linodeID, "lobster", imageID, diskSize, password, "") if err != nil { this.client.DeleteLinode(linodeID, false) return "", err } } else { return "", errors.New("invalid image type " + imageParts[0]) } vm.SetMetadata("diskid", fmt.Sprintf("%d", diskID)) vm.SetMetadata("password", password) swapID, _, err := this.client.CreateDisk(linodeID, "lobster-swap", "swap", swapSize, linode.CreateDiskOptions{}) if err != nil { this.client.DeleteLinode(linodeID, false) return "", err } configID, err := this.client.CreateConfig(linodeID, kernelID, fmt.Sprintf("lobster-%d", vm.Id), []int{diskID, swapID}, linode.CreateConfigOptions{}) if err != nil { this.client.DeleteLinode(linodeID, false) return "", err } else { vm.SetMetadata("configid", fmt.Sprintf("%d", configID)) this.client.BootLinode(linodeID) return fmt.Sprintf("%d", linodeID), nil } }
func (this *OpenStack) VmCreate(vm *lobster.VirtualMachine, options *lobster.VMIVmCreateOptions) (string, error) { flavorID := vm.Plan.Identification if flavorID == "" { flavorOpts := flavors.ListOpts{ MinDisk: vm.Plan.Storage, MinRAM: vm.Plan.Ram, } flavorPager := flavors.ListDetail(this.ComputeClient, flavorOpts) var matchFlavor *flavors.Flavor err := flavorPager.EachPage(func(page pagination.Page) (bool, error) { flavorList, err := flavors.ExtractFlavors(page) if err != nil { return false, err } for _, flavor := range flavorList { if flavor.Disk == vm.Plan.Storage && flavor.RAM == vm.Plan.Ram && flavor.VCPUs == vm.Plan.Cpu { matchFlavor = &flavor return false, nil } } return true, nil }) if err != nil { return "", err } else if matchFlavor == nil { return "", errors.New("plan not available in this region") } flavorID = matchFlavor.ID } password := utils.Uid(16) opts := servers.CreateOpts{ Name: vm.Name, ImageRef: options.ImageIdentification, FlavorRef: flavorID, Networks: []servers.Network{{UUID: this.networkId}}, AdminPass: password, UserData: []byte("#cloud-config\npassword: "******"\nchpasswd: { expire: False }\nssh_pwauth: True\n"), } createResult := servers.Create(this.ComputeClient, opts) server, err := createResult.Extract() if err != nil { return "", 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 var freeFloatingIp *floatingip.FloatingIP err := floatingip.List(this.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 == "" { freeFloatingIp = &floatingIp return false, nil } } return true, nil }) if err != nil { log.Printf("OpenStack: error while looking for free floating IP: %s", err.Error()) continue } else if freeFloatingIp == nil { log.Printf("OpenStack: Did not find free floating IP!") continue } // associate it err = floatingip.Associate(this.ComputeClient, server.ID, freeFloatingIp.IP).ExtractErr() if err == nil { break } else { log.Printf("OpenStack: error while associating floating IP: %s", err.Error()) } } }() vm.SetMetadata("password", password) return server.ID, nil }
func (this *Fake) VmCreate(vm *lobster.VirtualMachine, options *lobster.VMIVmCreateOptions) (string, error) { this.CountCreate++ vm.SetMetadata("addresses", "127.0.0.1:") return "fake", nil }