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