summaryrefslogtreecommitdiff
path: root/pkg/machine/qemu
diff options
context:
space:
mode:
authorAshley Cui <acui@redhat.com>2022-04-21 09:09:49 -0400
committerAshley Cui <acui@redhat.com>2022-04-27 13:56:14 -0400
commite7390f30b95daf90c0f32e8cf963dce3f8d5cf9d (patch)
treec0b962e598a1643f6f91cfd365c04cf0dc2a2d86 /pkg/machine/qemu
parent5ac00a7287e4a9e6292f4a6ca5dfa9a02e5ca907 (diff)
downloadpodman-e7390f30b95daf90c0f32e8cf963dce3f8d5cf9d.tar.gz
podman-e7390f30b95daf90c0f32e8cf963dce3f8d5cf9d.tar.bz2
podman-e7390f30b95daf90c0f32e8cf963dce3f8d5cf9d.zip
Allow changing of CPUs, Memory, and Disk Size
Allow podman machine set to change CPUs, Memory and Disk size of a QEMU machine after its been created. Disk size can only be increased. If one setting fails to be changed, the other settings will still be applied. Signed-off-by: Ashley Cui <acui@redhat.com>
Diffstat (limited to 'pkg/machine/qemu')
-rw-r--r--pkg/machine/qemu/machine.go138
-rw-r--r--pkg/machine/qemu/machine_test.go17
2 files changed, 118 insertions, 37 deletions
diff --git a/pkg/machine/qemu/machine.go b/pkg/machine/qemu/machine.go
index 969acb760..f53edc7b9 100644
--- a/pkg/machine/qemu/machine.go
+++ b/pkg/machine/qemu/machine.go
@@ -391,25 +391,9 @@ func (v *MachineVM) Init(opts machine.InitOptions) (bool, error) {
if err != nil {
return false, err
}
- // Resize the disk image to input disk size
- // only if the virtualdisk size is less than
- // the given disk size
- if opts.DiskSize<<(10*3) > originalDiskSize {
- // Find the qemu executable
- cfg, err := config.Default()
- if err != nil {
- return false, err
- }
- resizePath, err := cfg.FindHelperBinary("qemu-img", true)
- if err != nil {
- return false, err
- }
- resize := exec.Command(resizePath, []string{"resize", v.getImageFile(), strconv.Itoa(int(opts.DiskSize)) + "G"}...)
- resize.Stdout = os.Stdout
- resize.Stderr = os.Stderr
- if err := resize.Run(); err != nil {
- return false, errors.Errorf("resizing image: %q", err)
- }
+
+ if err := v.resizeDisk(opts.DiskSize, originalDiskSize>>(10*3)); err != nil {
+ return false, err
}
// If the user provides an ignition file, we need to
// copy it into the conf dir
@@ -433,14 +417,14 @@ func (v *MachineVM) Init(opts machine.InitOptions) (bool, error) {
return err == nil, err
}
-func (v *MachineVM) Set(_ string, opts machine.SetOptions) error {
- if v.Rootful == opts.Rootful {
- return nil
- }
+func (v *MachineVM) Set(_ string, opts machine.SetOptions) ([]error, error) {
+ // If one setting fails to be applied, the others settings will not fail and still be applied.
+ // The setting(s) that failed to be applied will have its errors returned in setErrors
+ var setErrors []error
state, err := v.State(false)
if err != nil {
- return err
+ return setErrors, err
}
if state == machine.Running {
@@ -448,26 +432,45 @@ func (v *MachineVM) Set(_ string, opts machine.SetOptions) error {
if v.Name != machine.DefaultMachineName {
suffix = " " + v.Name
}
- return errors.Errorf("cannot change setting while the vm is running, run 'podman machine stop%s' first", suffix)
+ return setErrors, errors.Errorf("cannot change settings while the vm is running, run 'podman machine stop%s' first", suffix)
}
- changeCon, err := machine.AnyConnectionDefault(v.Name, v.Name+"-root")
- if err != nil {
- return err
+ if opts.Rootful != nil && v.Rootful != *opts.Rootful {
+ if err := v.setRootful(*opts.Rootful); err != nil {
+ setErrors = append(setErrors, errors.Wrapf(err, "failed to set rootful option"))
+ } else {
+ v.Rootful = *opts.Rootful
+ }
}
- if changeCon {
- newDefault := v.Name
- if opts.Rootful {
- newDefault += "-root"
- }
- if err := machine.ChangeDefault(newDefault); err != nil {
- return err
+ if opts.CPUs != nil && v.CPUs != *opts.CPUs {
+ v.CPUs = *opts.CPUs
+ v.editCmdLine("-smp", strconv.Itoa(int(v.CPUs)))
+ }
+
+ if opts.Memory != nil && v.Memory != *opts.Memory {
+ v.Memory = *opts.Memory
+ v.editCmdLine("-m", strconv.Itoa(int(v.Memory)))
+ }
+
+ if opts.DiskSize != nil && v.DiskSize != *opts.DiskSize {
+ if err := v.resizeDisk(*opts.DiskSize, v.DiskSize); err != nil {
+ setErrors = append(setErrors, errors.Wrapf(err, "failed to resize disk"))
+ } else {
+ v.DiskSize = *opts.DiskSize
}
}
- v.Rootful = opts.Rootful
- return v.writeConfig()
+ err = v.writeConfig()
+ if err != nil {
+ setErrors = append(setErrors, err)
+ }
+
+ if len(setErrors) > 0 {
+ return setErrors, setErrors[0]
+ }
+
+ return setErrors, nil
}
// Start executes the qemu command line and forks it
@@ -1464,3 +1467,64 @@ func (v *MachineVM) getImageFile() string {
func (v *MachineVM) getIgnitionFile() string {
return v.IgnitionFilePath.GetPath()
}
+
+//resizeDisk increases the size of the machine's disk in GB.
+func (v *MachineVM) resizeDisk(diskSize uint64, oldSize uint64) error {
+ // Resize the disk image to input disk size
+ // only if the virtualdisk size is less than
+ // the given disk size
+ if diskSize < oldSize {
+ return errors.Errorf("new disk size must be larger than current disk size: %vGB", oldSize)
+ }
+
+ // Find the qemu executable
+ cfg, err := config.Default()
+ if err != nil {
+ return err
+ }
+ resizePath, err := cfg.FindHelperBinary("qemu-img", true)
+ if err != nil {
+ return err
+ }
+ resize := exec.Command(resizePath, []string{"resize", v.getImageFile(), strconv.Itoa(int(diskSize)) + "G"}...)
+ resize.Stdout = os.Stdout
+ resize.Stderr = os.Stderr
+ if err := resize.Run(); err != nil {
+ return errors.Errorf("resizing image: %q", err)
+ }
+
+ return nil
+}
+
+func (v *MachineVM) setRootful(rootful bool) error {
+ changeCon, err := machine.AnyConnectionDefault(v.Name, v.Name+"-root")
+ if err != nil {
+ return err
+ }
+
+ if changeCon {
+ newDefault := v.Name
+ if rootful {
+ newDefault += "-root"
+ }
+ err := machine.ChangeDefault(newDefault)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (v *MachineVM) editCmdLine(flag string, value string) {
+ found := false
+ for i, val := range v.CmdLine {
+ if val == flag {
+ found = true
+ v.CmdLine[i+1] = value
+ break
+ }
+ }
+ if !found {
+ v.CmdLine = append(v.CmdLine, []string{flag, value}...)
+ }
+}
diff --git a/pkg/machine/qemu/machine_test.go b/pkg/machine/qemu/machine_test.go
new file mode 100644
index 000000000..62ca6068a
--- /dev/null
+++ b/pkg/machine/qemu/machine_test.go
@@ -0,0 +1,17 @@
+package qemu
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/require"
+)
+
+func TestEditCmd(t *testing.T) {
+ vm := new(MachineVM)
+ vm.CmdLine = []string{"command", "-flag", "value"}
+
+ vm.editCmdLine("-flag", "newvalue")
+ vm.editCmdLine("-anotherflag", "anothervalue")
+
+ require.Equal(t, vm.CmdLine, []string{"command", "-flag", "newvalue", "-anotherflag", "anothervalue"})
+}