github.com/emc-advanced-dev/unik@v0.0.0-20190717152701-a58d3e8e33b7/pkg/providers/openstack/run_instance.go (about) 1 package openstack 2 3 import ( 4 "github.com/sirupsen/logrus" 5 "github.com/emc-advanced-dev/pkg/errors" 6 "github.com/solo-io/unik/pkg/types" 7 "github.com/rackspace/gophercloud" 8 "github.com/rackspace/gophercloud/openstack/compute/v2/servers" 9 "time" 10 ) 11 12 const DEFAULT_INSTANCE_DISKMB int = 10 * 1024 // 10 GB 13 14 func (p *OpenstackProvider) RunInstance(params types.RunInstanceParams) (_ *types.Instance, err error) { 15 // return nil, errors.New("not yet supportded for openstack", nil) 16 17 logrus.WithFields(logrus.Fields{ 18 "image-id": params.ImageId, 19 "mounts": params.MntPointsToVolumeIds, 20 "env": params.Env, 21 }).Infof("running instance %s", params.Name) 22 23 clientNova, err := p.newClientNova() 24 if err != nil { 25 return nil, err 26 } 27 28 image, err := p.GetImage(params.ImageId) 29 if err != nil { 30 return nil, errors.New("failed to get image", err) 31 } 32 33 // If not set, use default. 34 if params.InstanceMemory <= 0 { 35 params.InstanceMemory = image.RunSpec.DefaultInstanceMemory 36 } 37 38 // Pick flavor. 39 minDiskMB := image.RunSpec.MinInstanceDiskMB 40 if minDiskMB <= 0 { 41 // TODO(miha-plesko): raise error here, since compiler should set MinInstanceDiskMB. 42 // This commit adds field MinInstanceDiskMB to the RunSpec, but ATM non of the existing 43 // compilers actually set it (so it's always zero). This field should be set at compile time 44 // since only then compiler is actually aware of the logical size of the disk. 45 // Raise error here after compiler is updated. 46 minDiskMB = DEFAULT_INSTANCE_DISKMB 47 } 48 flavor, err := pickFlavor(clientNova, minDiskMB, params.InstanceMemory) 49 if err != nil { 50 return nil, errors.New("failed to pick flavor", err) 51 } 52 53 // Run instance. 54 serverId, err := launchServer(clientNova, params.Name, flavor.Name, image.Name, p.config.NetworkUUID) 55 if err != nil { 56 return nil, errors.New("failed to run instance", err) 57 } 58 59 instance := &types.Instance{ 60 Id: serverId, 61 Name: params.Name, 62 State: types.InstanceState_Pending, 63 Infrastructure: types.Infrastructure_OPENSTACK, 64 ImageId: image.Id, 65 Created: time.Now(), 66 } 67 68 // Update state. 69 if err := p.state.ModifyInstances(func(instances map[string]*types.Instance) error { 70 instances[instance.Id] = instance 71 return nil 72 }); err != nil { 73 return nil, errors.New("failed to modify instance map in state", err) 74 } 75 76 logrus.WithFields(logrus.Fields{"instance": instance}).Infof("instance created succesfully") 77 78 return instance, nil 79 } 80 81 // launchServer launches single server of given image and returns it's id. 82 func launchServer(clientNova *gophercloud.ServiceClient, name, flavorName, imageName, networkUUID string) (string, error) { 83 resp := servers.Create(clientNova, servers.CreateOpts{ 84 Name: name, 85 FlavorName: flavorName, 86 ImageName: imageName, 87 Networks: []servers.Network{ 88 servers.Network{UUID: networkUUID}, 89 }, 90 }) 91 92 if resp.Err != nil { 93 return "", resp.Err 94 } 95 96 server, err := resp.Extract() 97 return server.ID, err 98 }