github.com/emc-advanced-dev/unik@v0.0.0-20190717152701-a58d3e8e33b7/pkg/providers/qemu/stage.go (about) 1 package qemu 2 3 import ( 4 "os" 5 "path/filepath" 6 "time" 7 8 "github.com/sirupsen/logrus" 9 "github.com/emc-advanced-dev/pkg/errors" 10 unikos "github.com/solo-io/unik/pkg/os" 11 "github.com/solo-io/unik/pkg/providers/common" 12 "github.com/solo-io/unik/pkg/types" 13 ) 14 15 func (p *QemuProvider) 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("failed to remove previously existing image", err) 28 } 29 } 30 } 31 } 32 imagePath := getImagePath(params.Name) 33 logrus.Debugf("making directory: %s", filepath.Dir(imagePath)) 34 if err := os.MkdirAll(filepath.Dir(imagePath), 0777); err != nil { 35 return nil, errors.New("creating directory for boot image", err) 36 } 37 defer func() { 38 if err != nil && !params.NoCleanup { 39 os.RemoveAll(filepath.Dir(imagePath)) 40 } 41 }() 42 43 kernelPath := filepath.Join(filepath.Dir(params.RawImage.LocalImagePath), "program.bin") 44 if _, err := os.Stat(kernelPath); os.IsNotExist(err) { 45 logrus.Debugf("program.bin does not exist, assuming classic bootloader") 46 if err := unikos.CopyFile(params.RawImage.LocalImagePath, getImagePath(params.Name)); err != nil { 47 return nil, errors.New("copying bootable image to image dir", err) 48 } 49 } else { 50 logrus.WithField("raw-image", params.RawImage).Infof("creating boot volume from raw image") 51 if err := common.ConvertRawImage(params.RawImage.StageSpec.ImageFormat, types.ImageFormat_QCOW2, params.RawImage.LocalImagePath, imagePath); err != nil { 52 return nil, errors.New("converting raw image to qcow2", err) 53 } 54 55 kernelFile := filepath.Join(filepath.Dir(params.RawImage.LocalImagePath), "program.bin") 56 if err := unikos.CopyFile(kernelFile, getKernelPath(params.Name)); err != nil { 57 return nil, errors.New("copying kernel file to image dir", err) 58 } 59 60 cmdlineFile := filepath.Join(filepath.Dir(params.RawImage.LocalImagePath), "cmdline") 61 if err := unikos.CopyFile(cmdlineFile, getCmdlinePath(params.Name)); err != nil { 62 return nil, errors.New("copying cmdline file to image dir", err) 63 } 64 } 65 66 imagePathInfo, err := os.Stat(imagePath) 67 if err != nil { 68 return nil, errors.New("statting raw image file", err) 69 } 70 sizeMb := imagePathInfo.Size() >> 20 71 72 logrus.WithFields(logrus.Fields{ 73 "name": params.Name, 74 "id": params.Name, 75 "size": sizeMb, 76 }).Infof("copying raw boot image") 77 78 image := &types.Image{ 79 Id: params.Name, 80 Name: params.Name, 81 RunSpec: params.RawImage.RunSpec, 82 StageSpec: params.RawImage.StageSpec, 83 SizeMb: sizeMb, 84 Infrastructure: types.Infrastructure_QEMU, 85 Created: time.Now(), 86 } 87 88 if err := p.state.ModifyImages(func(images map[string]*types.Image) error { 89 images[params.Name] = image 90 return nil 91 }); err != nil { 92 return nil, errors.New("modifying image map in state", err) 93 } 94 95 logrus.WithFields(logrus.Fields{"image": image}).Infof("image created succesfully") 96 return image, nil 97 }