github.com/emc-advanced-dev/unik@v0.0.0-20190717152701-a58d3e8e33b7/pkg/providers/vsphere/run_instance.go (about) 1 package vsphere 2 3 import ( 4 "github.com/sirupsen/logrus" 5 "github.com/emc-advanced-dev/pkg/errors" 6 "github.com/solo-io/unik/pkg/providers/common" 7 "github.com/solo-io/unik/pkg/types" 8 "github.com/layer-x/layerx-commons/lxhttpclient" 9 "strings" 10 "time" 11 ) 12 13 func (p *VsphereProvider) RunInstance(params types.RunInstanceParams) (_ *types.Instance, err error) { 14 logrus.WithFields(logrus.Fields{ 15 "image-id": params.ImageId, 16 "mounts": params.MntPointsToVolumeIds, 17 "env": params.Env, 18 }).Infof("running instance %s", params.Name) 19 20 if _, err := p.GetInstance(params.Name); err == nil { 21 return nil, errors.New("instance with name "+params.Name+" already exists. virtualbox provider requires unique names for instances", nil) 22 } 23 24 image, err := p.GetImage(params.ImageId) 25 if err != nil { 26 return nil, errors.New("getting image", err) 27 } 28 29 if err := common.VerifyMntsInput(p, image, params.MntPointsToVolumeIds); err != nil { 30 return nil, errors.New("invalid mapping for volume", err) 31 } 32 33 instanceDir := getInstanceDatastoreDir(params.Name) 34 35 portsUsed := []int{} 36 37 c := p.getClient() 38 39 defer func() { 40 if err != nil { 41 if params.NoCleanup { 42 logrus.Warnf("because --no-cleanup flag was provided, not cleaning up failed instance %s001", params.Name) 43 return 44 } 45 logrus.WithError(err).Warnf("error encountered, ensuring vm and disks are destroyed") 46 c.PowerOffVm(params.Name) 47 for _, portUsed := range portsUsed { 48 c.DetachDisk(params.Name, portUsed, image.RunSpec.StorageDriver) 49 } 50 c.DestroyVm(params.Name) 51 c.Rmdir(instanceDir) 52 } 53 }() 54 55 logrus.Debugf("creating vsphere vm") 56 57 //if not set, use default 58 if params.InstanceMemory <= 0 { 59 params.InstanceMemory = image.RunSpec.DefaultInstanceMemory 60 } 61 62 if err := c.CreateVm(params.Name, params.InstanceMemory, image.RunSpec.VsphereNetworkType, p.config.NetworkLabel); err != nil { 63 return nil, errors.New("creating vm", err) 64 } 65 66 logrus.Debugf("powering on vm to assign mac addr") 67 if err := c.PowerOnVm(params.Name); err != nil { 68 return nil, errors.New("failed to power on vm to assign mac addr", err) 69 } 70 71 vm, err := c.GetVm(params.Name) 72 if err != nil { 73 return nil, errors.New("failed to retrieve vm info after create", err) 74 } 75 76 macAddr := "" 77 if vm.Config.Hardware.Device != nil { 78 for _, device := range vm.Config.Hardware.Device { 79 if len(device.MacAddress) > 0 { 80 macAddr = device.MacAddress 81 break 82 } 83 } 84 } 85 if macAddr == "" { 86 logrus.WithFields(logrus.Fields{"vm": vm}).Warnf("vm found, cannot identify mac addr") 87 return nil, errors.New("could not find mac addr on vm", nil) 88 } 89 if err := c.PowerOffVm(params.Name); err != nil { 90 return nil, errors.New("failed to power off vm after retrieving mac addr", err) 91 } 92 93 logrus.Debugf("copying base boot vmdk to instance dir") 94 instanceBootImagePath := instanceDir + "/boot.vmdk" 95 if err := c.CopyFile(getImageDatastorePath(image.Name), instanceBootImagePath); err != nil { 96 return nil, errors.New("copying base boot.vmdk", err) 97 } 98 if err := c.CopyFile(strings.TrimSuffix(getImageDatastorePath(image.Name), ".vmdk")+"-flat.vmdk", strings.TrimSuffix(instanceBootImagePath, ".vmdk")+"-flat.vmdk"); err != nil { 99 return nil, errors.New("copying base boot-flat.vmdk", err) 100 } 101 if err := c.AttachDisk(params.Name, instanceBootImagePath, 0, image.RunSpec.StorageDriver); err != nil { 102 return nil, errors.New("attaching boot vol to instance", err) 103 } 104 105 for mntPoint, volumeId := range params.MntPointsToVolumeIds { 106 volume, err := p.GetVolume(volumeId) 107 if err != nil { 108 return nil, errors.New("getting volume", err) 109 } 110 controllerPort, err := common.GetControllerPortForMnt(image, mntPoint) 111 if err != nil { 112 return nil, errors.New("getting controller port for mnt point", err) 113 } 114 if err := c.AttachDisk(params.Name, getVolumeDatastorePath(volume.Name), controllerPort, image.RunSpec.StorageDriver); err != nil { 115 return nil, errors.New("attaching disk to vm", err) 116 } 117 portsUsed = append(portsUsed, controllerPort) 118 } 119 120 instanceListenerIp, err := common.GetInstanceListenerIp(instanceListenerPrefix, timeout) 121 if err != nil { 122 return nil, errors.New("failed to retrieve instance listener ip. is unik instance listener running?", err) 123 } 124 125 logrus.Debugf("sending env to listener") 126 if _, _, err := lxhttpclient.Post(instanceListenerIp+":3000", "/set_instance_env?mac_address="+macAddr, nil, params.Env); err != nil { 127 return nil, errors.New("sending instance env to listener", err) 128 } 129 130 logrus.Debugf("powering on vm") 131 if err := c.PowerOnVm(params.Name); err != nil { 132 return nil, errors.New("powering on vm", err) 133 } 134 135 instanceId := vm.Config.UUID 136 137 instance := &types.Instance{ 138 Id: instanceId, 139 Name: params.Name, 140 State: types.InstanceState_Pending, 141 IpAddress: "", 142 Infrastructure: types.Infrastructure_VSPHERE, 143 ImageId: image.Id, 144 Created: time.Now(), 145 } 146 147 if err := p.state.ModifyInstances(func(instances map[string]*types.Instance) error { 148 instances[instance.Id] = instance 149 return nil 150 }); err != nil { 151 return nil, errors.New("modifying instance map in state", err) 152 } 153 154 logrus.WithField("instance", instance).Infof("instance created successfully") 155 156 return instance, nil 157 }