summaryrefslogtreecommitdiff
path: root/pkg/machine/qemu/machine.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/machine/qemu/machine.go')
-rw-r--r--pkg/machine/qemu/machine.go82
1 files changed, 68 insertions, 14 deletions
diff --git a/pkg/machine/qemu/machine.go b/pkg/machine/qemu/machine.go
index fe155750f..fdb528a86 100644
--- a/pkg/machine/qemu/machine.go
+++ b/pkg/machine/qemu/machine.go
@@ -12,9 +12,8 @@ import (
"strconv"
"time"
- "github.com/containers/podman/v3/utils"
-
"github.com/containers/podman/v3/pkg/machine"
+ "github.com/containers/podman/v3/utils"
"github.com/containers/storage/pkg/homedir"
"github.com/digitalocean/go-qemu/qmp"
"github.com/pkg/errors"
@@ -83,7 +82,7 @@ func NewMachine(opts machine.InitOptions) (machine.VM, error) {
return nil, err
}
vm.QMPMonitor = monitor
- cmd = append(cmd, []string{"-qmp", monitor.Network + ":/" + monitor.Address + ",server,nowait"}...)
+ cmd = append(cmd, []string{"-qmp", monitor.Network + ":/" + monitor.Address + ",server=on,wait=off"}...)
// Add network
cmd = append(cmd, "-nic", "user,model=virtio,hostfwd=tcp::"+strconv.Itoa(vm.Port)+"-:22")
@@ -96,7 +95,7 @@ func NewMachine(opts machine.InitOptions) (machine.VM, error) {
// Add serial port for readiness
cmd = append(cmd, []string{
"-device", "virtio-serial",
- "-chardev", "socket,path=" + virtualSocketPath + ",server,nowait,id=" + vm.Name + "_ready",
+ "-chardev", "socket,path=" + virtualSocketPath + ",server=on,wait=off,id=" + vm.Name + "_ready",
"-device", "virtserialport,chardev=" + vm.Name + "_ready" + ",name=org.fedoraproject.port.0"}...)
vm.CmdLine = cmd
return vm, nil
@@ -135,15 +134,29 @@ func (v *MachineVM) Init(opts machine.InitOptions) error {
jsonFile := filepath.Join(vmConfigDir, v.Name) + ".json"
v.IdentityPath = filepath.Join(sshDir, v.Name)
- dd, err := machine.NewFcosDownloader(vmtype, v.Name)
- if err != nil {
- return err
+ // The user has provided an alternate image which can be a file path
+ // or URL.
+ if len(opts.ImagePath) > 0 {
+ g, err := machine.NewGenericDownloader(vmtype, v.Name, opts.ImagePath)
+ if err != nil {
+ return err
+ }
+ v.ImagePath = g.Get().LocalUncompressedFile
+ if err := g.DownloadImage(); err != nil {
+ return err
+ }
+ } else {
+ // Get the image as usual
+ dd, err := machine.NewFcosDownloader(vmtype, v.Name)
+ if err != nil {
+ return err
+ }
+ v.ImagePath = dd.Get().LocalUncompressedFile
+ if err := dd.DownloadImage(); err != nil {
+ return err
+ }
}
- v.ImagePath = dd.Get().LocalUncompressedFile
- if err := dd.DownloadImage(); err != nil {
- return err
- }
// Add arch specific options including image location
v.CmdLine = append(v.CmdLine, v.addArchOptions()...)
@@ -171,10 +184,20 @@ func (v *MachineVM) Init(opts machine.InitOptions) error {
return err
}
+ originalDiskSize, err := getDiskSize(v.ImagePath)
+ if err != nil {
+ return err
+ }
// Resize the disk image to input disk size
- resize := exec.Command("qemu-img", []string{"resize", v.ImagePath, strconv.Itoa(int(opts.DiskSize)) + "G"}...)
- if err := resize.Run(); err != nil {
- return errors.Errorf("error resizing image: %q", err)
+ // only if the virtualdisk size is less than
+ // the given disk size
+ if opts.DiskSize<<(10*3) > originalDiskSize {
+ resize := exec.Command("qemu-img", []string{"resize", v.ImagePath, strconv.Itoa(int(opts.DiskSize)) + "G"}...)
+ resize.Stdout = os.Stdout
+ resize.Stderr = os.Stderr
+ if err := resize.Run(); err != nil {
+ return errors.Errorf("error resizing image: %q", err)
+ }
}
// Write the ignition file
ign := machine.DynamicIgnition{
@@ -372,3 +395,34 @@ func (v *MachineVM) SSH(name string, opts machine.SSHOptions) error {
return cmd.Run()
}
+
+// executes qemu-image info to get the virtual disk size
+// of the diskimage
+func getDiskSize(path string) (uint64, error) {
+ diskInfo := exec.Command("qemu-img", "info", "--output", "json", path)
+ stdout, err := diskInfo.StdoutPipe()
+ if err != nil {
+ return 0, err
+ }
+ if err := diskInfo.Start(); err != nil {
+ return 0, err
+ }
+ tmpInfo := struct {
+ VirtualSize uint64 `json:"virtual-size"`
+ Filename string `json:"filename"`
+ ClusterSize int64 `json:"cluster-size"`
+ Format string `json:"format"`
+ FormatSpecific struct {
+ Type string `json:"type"`
+ Data map[string]string `json:"data"`
+ }
+ DirtyFlag bool `json:"dirty-flag"`
+ }{}
+ if err := json.NewDecoder(stdout).Decode(&tmpInfo); err != nil {
+ return 0, err
+ }
+ if err := diskInfo.Wait(); err != nil {
+ return 0, err
+ }
+ return tmpInfo.VirtualSize, nil
+}