github.com/emc-advanced-dev/unik@v0.0.0-20190717152701-a58d3e8e33b7/pkg/providers/photon/stage.go (about) 1 package photon 2 3 import ( 4 "io/ioutil" 5 "os" 6 "path/filepath" 7 "time" 8 9 "github.com/sirupsen/logrus" 10 "github.com/emc-advanced-dev/pkg/errors" 11 "github.com/solo-io/unik/pkg/providers/common" 12 "github.com/solo-io/unik/pkg/types" 13 "github.com/vmware/photon-controller-go-sdk/photon" 14 ) 15 16 func createVmdk(params types.StageImageParams, workVmdk func(file string) (string, error)) (string, int64, error) { 17 18 localVmdkDir, err := ioutil.TempDir("", "vmdkdir.") 19 if err != nil { 20 return "", 0, errors.New("creating tmp file", err) 21 } 22 defer os.RemoveAll(localVmdkDir) 23 localVmdkFile := filepath.Join(localVmdkDir, "boot.vmdk") 24 25 logrus.WithField("raw-image", params.RawImage).Infof("creating boot volume from raw image") 26 if err := common.ConvertRawToNewVmdk(params.RawImage.LocalImagePath, localVmdkFile); err != nil { 27 return "", 0, errors.New("converting raw image to vmdk", err) 28 } 29 30 rawImageFile, err := os.Stat(localVmdkFile) 31 if err != nil { 32 return "", 0, errors.New("statting raw image file", err) 33 } 34 sizeMb := rawImageFile.Size() >> 20 35 36 logrus.WithFields(logrus.Fields{ 37 "name": params.Name, 38 "id": params.Name, 39 "size": sizeMb, 40 }).Infof("importing base vmdk for unikernel image") 41 42 imgId, err := workVmdk(localVmdkFile) 43 return imgId, sizeMb, err 44 45 } 46 47 func (p *PhotonProvider) Stage(params types.StageImageParams) (_ *types.Image, err error) { 48 images, err := p.ListImages() 49 if err != nil { 50 return nil, errors.New("retrieving image list for existing image", err) 51 } 52 for _, image := range images { 53 if image.Name == params.Name { 54 if !params.Force { 55 return nil, errors.New("an image already exists with name '"+params.Name+"', try again with --force", nil) 56 } else { 57 logrus.WithField("image", image).Warnf("force: deleting previous image with name " + params.Name) 58 if err := p.DeleteImage(image.Id, true); err != nil { 59 logrus.Warn(errors.New("failed removing previously existing image", err)) 60 } 61 } 62 } 63 } 64 65 // create vmdk 66 imgId, sizeMb, err := createVmdk(params, func(vmdkFile string) (string, error) { 67 options := &photon.ImageCreateOptions{ 68 ReplicationType: "EAGER", 69 } 70 task, err := p.client.Images.CreateFromFile(vmdkFile, options) 71 if err != nil { 72 return "", errors.New("error creating photon image", err) 73 } 74 75 task, err = p.waitForTaskSuccess(task) 76 if err != nil { 77 return "", errors.New("error waiting for task creating photon image", err) 78 } 79 80 return task.Entity.ID, nil 81 }) 82 if err != nil { 83 return nil, errors.New("importing base boot.vmdk to photon", err) 84 } 85 86 // upload images 87 image := &types.Image{ 88 Id: imgId, 89 Name: params.Name, 90 StageSpec: params.RawImage.StageSpec, 91 RunSpec: params.RawImage.RunSpec, 92 SizeMb: sizeMb, 93 Infrastructure: types.Infrastructure_PHOTON, 94 Created: time.Now(), 95 } 96 97 if err := p.state.ModifyImages(func(images map[string]*types.Image) error { 98 images[params.Name] = image 99 return nil 100 }); err != nil { 101 return nil, errors.New("modifying image map in state", err) 102 } 103 104 logrus.WithFields(logrus.Fields{"image": image}).Infof("image created succesfully") 105 return image, nil 106 }