github.com/emc-advanced-dev/unik@v0.0.0-20190717152701-a58d3e8e33b7/pkg/providers/vsphere/stage.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  	"io/ioutil"
     9  	"os"
    10  	"path/filepath"
    11  	"strings"
    12  	"time"
    13  )
    14  
    15  func (p *VsphereProvider) Stage(params types.StageImageParams) (_ *types.Image, err error) {
    16  	images, err := p.ListImages()
    17  	if err != nil {
    18  		return nil, errors.New("retrieving image list for existing image", err)
    19  	}
    20  	for _, image := range images {
    21  		if image.Name == params.Name {
    22  			if !params.Force {
    23  				return nil, errors.New("an image already exists with name '"+params.Name+"', try again with --force", nil)
    24  			} else {
    25  				logrus.WithField("image", image).Warnf("force: deleting previous image with name " + params.Name)
    26  				if err := p.DeleteImage(image.Id, true); err != nil {
    27  					logrus.Warn(errors.New("failed removing previously existing image", err))
    28  				}
    29  			}
    30  		}
    31  	}
    32  	c := p.getClient()
    33  	vsphereImageDir := getImageDatastoreDir(params.Name)
    34  	if err := c.Mkdir(vsphereImageDir); err != nil && !strings.Contains(err.Error(), "exists") {
    35  		return nil, errors.New("creating vsphere directory for image", err)
    36  	}
    37  	defer func() {
    38  		if err != nil {
    39  			logrus.WithError(err).Warnf("creating image failed, cleaning up image on datastore")
    40  			c.Rmdir(vsphereImageDir)
    41  		}
    42  	}()
    43  
    44  	localVmdkDir, err := ioutil.TempDir("", "vmdkdir.")
    45  	if err != nil {
    46  		return nil, errors.New("creating tmp file", err)
    47  	}
    48  	defer os.RemoveAll(localVmdkDir)
    49  	localVmdkFile := filepath.Join(localVmdkDir, "boot.vmdk")
    50  
    51  	logrus.WithField("raw-image", params.RawImage).Infof("creating boot volume from raw image")
    52  	if err := common.ConvertRawImage(params.RawImage.StageSpec.ImageFormat, types.ImageFormat_VMDK, params.RawImage.LocalImagePath, localVmdkFile); err != nil {
    53  		return nil, errors.New("converting raw image to vmdk", err)
    54  	}
    55  
    56  	rawImageFile, err := os.Stat(localVmdkFile)
    57  	if err != nil {
    58  		return nil, errors.New("statting raw image file", err)
    59  	}
    60  	sizeMb := rawImageFile.Size() >> 20
    61  
    62  	logrus.WithFields(logrus.Fields{
    63  		"name":           params.Name,
    64  		"id":             params.Name,
    65  		"size":           sizeMb,
    66  		"datastore-path": vsphereImageDir,
    67  	}).Infof("importing base vmdk for unikernel image")
    68  
    69  	if err := c.ImportVmdk(localVmdkFile, vsphereImageDir); err != nil {
    70  		return nil, errors.New("importing base boot.vmdk to vsphere datastore", err)
    71  	}
    72  
    73  	image := &types.Image{
    74  		Id:             params.Name,
    75  		Name:           params.Name,
    76  		StageSpec:      params.RawImage.StageSpec,
    77  		RunSpec:        params.RawImage.RunSpec,
    78  		SizeMb:         sizeMb,
    79  		Infrastructure: types.Infrastructure_VSPHERE,
    80  		Created:        time.Now(),
    81  	}
    82  
    83  	err = p.state.ModifyImages(func(images map[string]*types.Image) error {
    84  		images[params.Name] = image
    85  		return nil
    86  	})
    87  	if err != nil {
    88  		return nil, errors.New("modifying image map in state", err)
    89  	}
    90  
    91  	logrus.WithFields(logrus.Fields{"image": image}).Infof("image created succesfully")
    92  	return image, nil
    93  }