github.com/emc-advanced-dev/unik@v0.0.0-20190717152701-a58d3e8e33b7/pkg/providers/photon/run_instance.go (about) 1 package photon 2 3 import ( 4 "strings" 5 "time" 6 7 "github.com/sirupsen/logrus" 8 "github.com/emc-advanced-dev/pkg/errors" 9 "github.com/solo-io/unik/pkg/providers/common" 10 "github.com/solo-io/unik/pkg/types" 11 "github.com/vmware/photon-controller-go-sdk/photon" 12 ) 13 14 func getMemMb(flavor *photon.Flavor) float64 { 15 for _, quotaItem := range flavor.Cost { 16 if quotaItem.Key == "vm.memory" { 17 machineMem := quotaItem.Value 18 switch quotaItem.Unit { 19 case "GB": 20 machineMem *= 1024 21 case "MB": 22 machineMem *= 1 23 case "KB": 24 machineMem /= 1024 25 default: 26 logrus.WithFields(logrus.Fields{"flavor": flavor.Name, "quotaItem": quotaItem}).Infof("unknown unit for mem") 27 return -1 28 } 29 } 30 } 31 logrus.WithField("flavor", flavor.Name).Infof("no vm.memory found") 32 33 return -1 34 35 } 36 37 func (p *PhotonProvider) getUnikFlavor(kind string) (*photon.Flavor, error) { 38 options := &photon.FlavorGetOptions{ 39 Kind: kind, 40 Name: "", 41 } 42 flavorList, err := p.client.Flavors.GetAll(options) 43 if err != nil { 44 return nil, err 45 } 46 for _, f := range flavorList.Items { 47 if strings.Contains(f.Name, "unik-") { 48 return &f, nil 49 } 50 } 51 52 return nil, errors.New("No flavor found", nil) 53 } 54 55 func (p *PhotonProvider) RunInstance(params types.RunInstanceParams) (_ *types.Instance, err error) { 56 logrus.WithFields(logrus.Fields{ 57 "image-id": params.ImageId, 58 "mounts": params.MntPointsToVolumeIds, 59 "env": params.Env, 60 }).Infof("running instance %s", params.Name) 61 62 if _, err := p.GetInstance(params.Name); err == nil { 63 return nil, errors.New("instance with name "+params.Name+" already exists. virtualbox provider requires unique names for instances", nil) 64 } 65 66 image, err := p.GetImage(params.ImageId) 67 if err != nil { 68 return nil, errors.New("getting image", err) 69 } 70 71 if err := common.VerifyMntsInput(p, image, params.MntPointsToVolumeIds); err != nil { 72 return nil, errors.New("invalid mapping for volume", err) 73 } 74 75 vmflavor, err := p.getUnikFlavor("vm") 76 if err != nil { 77 return nil, errors.New("can't get vm flavor", err) 78 } 79 80 diskflavor, err := p.getUnikFlavor("ephemeral-disk") 81 if err != nil { 82 return nil, errors.New("can't get disk flavor", err) 83 } 84 85 disk := photon.AttachedDisk{ 86 Flavor: diskflavor.Name, 87 Kind: "ephemeral-disk", 88 Name: "bootdisk-" + image.Id, 89 BootDisk: true, 90 } 91 92 vmspec := &photon.VmCreateSpec{ 93 Flavor: vmflavor.Name, 94 SourceImageID: image.Id, 95 Name: params.Name, 96 Affinities: nil, 97 AttachedDisks: []photon.AttachedDisk{disk}, 98 Environment: params.Env, 99 } 100 101 task, err := p.client.Projects.CreateVM(p.projectId, vmspec) 102 103 if err != nil { 104 return nil, errors.New("Creating vm", err) 105 } 106 107 task, err = p.waitForTaskSuccess(task) 108 109 if err != nil { 110 return nil, errors.New("Waiting for create vm", err) 111 } 112 113 // TODO: not sure we can use instance listener for photon.. 114 instanceIp := "" 115 // TODO: add infrastructure id? 116 117 instance := &types.Instance{ 118 Id: task.Entity.ID, 119 Name: params.Name, 120 State: types.InstanceState_Pending, 121 IpAddress: instanceIp, 122 Infrastructure: types.Infrastructure_PHOTON, 123 ImageId: image.Id, 124 Created: time.Now(), 125 } 126 127 if err := p.state.ModifyInstances(func(instances map[string]*types.Instance) error { 128 instances[instance.Id] = instance 129 return nil 130 }); err != nil { 131 return nil, errors.New("modifying instance map in state", err) 132 } 133 134 logrus.WithField("instance", instance).Infof("instance created successfully") 135 136 return instance, p.StartInstance(instance.Id) 137 }