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  }