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  }