func (this *OpenStack) PlanList() ([]*lobster.Plan, error) { var plans []*lobster.Plan flavorPager := flavors.ListDetail(this.ComputeClient, flavors.ListOpts{}) err := flavorPager.EachPage(func(page pagination.Page) (bool, error) { flavorList, err := flavors.ExtractFlavors(page) if err != nil { return false, err } for _, flavor := range flavorList { plans = append(plans, &lobster.Plan{ Name: flavor.Name, Ram: flavor.RAM, Cpu: flavor.VCPUs, Storage: flavor.Disk, Identification: flavor.ID, }) } return true, nil }) if err != nil { return nil, err } return plans, nil }
func (os *OpenStack) ListFlavors() ([]*compute.Flavor, error) { var flavorList []*compute.Flavor flavorPager := flavors.ListDetail(os.ComputeClient, flavors.ListOpts{}) err := flavorPager.EachPage(func(page pagination.Page) (bool, error) { pageFlavors, err := flavors.ExtractFlavors(page) if err != nil { return false, err } for _, flavor := range pageFlavors { flavorList = append(flavorList, &compute.Flavor{ ID: flavor.ID, Name: flavor.Name, MemoryMB: flavor.RAM, NumCores: flavor.VCPUs, DiskGB: flavor.Disk, }) } return true, nil }) if err != nil { return nil, err } else { return flavorList, 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 }