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  }