Skip to content

Commit

Permalink
Merge pull request #13953 from ashley-cui/mach
Browse files Browse the repository at this point in the history
Allow changing of CPUs, Memory, and Disk Size
  • Loading branch information
openshift-merge-robot authored Apr 27, 2022
2 parents 9133a6d + e7390f3 commit 60d6cc8
Show file tree
Hide file tree
Showing 8 changed files with 419 additions and 62 deletions.
60 changes: 57 additions & 3 deletions cmd/podman/machine/set.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
package machine

import (
"fmt"
"os"

"github.com/containers/common/pkg/completion"
"github.com/containers/podman/v4/cmd/podman/registry"
"github.com/containers/podman/v4/pkg/machine"
Expand All @@ -23,9 +26,17 @@ var (
)

var (
setOpts = machine.SetOptions{}
setFlags = SetFlags{}
setOpts = machine.SetOptions{}
)

type SetFlags struct {
CPUs uint64
DiskSize uint64
Memory uint64
Rootful bool
}

func init() {
registry.Commands = append(registry.Commands, registry.CliCommand{
Command: setCmd,
Expand All @@ -34,7 +45,32 @@ func init() {
flags := setCmd.Flags()

rootfulFlagName := "rootful"
flags.BoolVar(&setOpts.Rootful, rootfulFlagName, false, "Whether this machine should prefer rootful container execution")
flags.BoolVar(&setFlags.Rootful, rootfulFlagName, false, "Whether this machine should prefer rootful container execution")

cpusFlagName := "cpus"
flags.Uint64Var(
&setFlags.CPUs,
cpusFlagName, 0,
"Number of CPUs",
)
_ = setCmd.RegisterFlagCompletionFunc(cpusFlagName, completion.AutocompleteNone)

diskSizeFlagName := "disk-size"
flags.Uint64Var(
&setFlags.DiskSize,
diskSizeFlagName, 0,
"Disk size in GB",
)

_ = setCmd.RegisterFlagCompletionFunc(diskSizeFlagName, completion.AutocompleteNone)

memoryFlagName := "memory"
flags.Uint64VarP(
&setFlags.Memory,
memoryFlagName, "m", 0,
"Memory in MB",
)
_ = setCmd.RegisterFlagCompletionFunc(memoryFlagName, completion.AutocompleteNone)
}

func setMachine(cmd *cobra.Command, args []string) error {
Expand All @@ -53,5 +89,23 @@ func setMachine(cmd *cobra.Command, args []string) error {
return err
}

return vm.Set(vmName, setOpts)
if cmd.Flags().Changed("rootful") {
setOpts.Rootful = &setFlags.Rootful
}
if cmd.Flags().Changed("cpus") {
setOpts.CPUs = &setFlags.CPUs
}
if cmd.Flags().Changed("memory") {
setOpts.Memory = &setFlags.Memory
}
if cmd.Flags().Changed("disk-size") {
setOpts.DiskSize = &setFlags.DiskSize
}

setErrs, lasterr := vm.Set(vmName, setOpts)
for _, err := range setErrs {
fmt.Fprintf(os.Stderr, "%v\n", err)
}

return lasterr
}
20 changes: 16 additions & 4 deletions docs/source/markdown/podman-machine-set.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,29 @@ podman\-machine\-set - Sets a virtual machine setting

## DESCRIPTION

Sets an updatable virtual machine setting.

Options mirror values passed to `podman machine init`. Only a limited
subset can be changed after machine initialization.
Change a machine setting.

## OPTIONS

#### **--cpus**=*number*

Number of CPUs.
Only supported for QEMU machines.

#### **--disk-size**=*number*

Size of the disk for the guest VM in GB.
Can only be increased. Only supported for QEMU machines.

#### **--help**

Print usage statement.

#### **--memory**, **-m**=*number*

Memory (in MB).
Only supported for QEMU machines.

#### **--rootful**=*true|false*

Whether this machine should prefer rootful (`true`) or rootless (`false`)
Expand Down
7 changes: 5 additions & 2 deletions pkg/machine/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,10 @@ type ListResponse struct {
}

type SetOptions struct {
Rootful bool
CPUs *uint64
DiskSize *uint64
Memory *uint64
Rootful *bool
}

type SSHOptions struct {
Expand All @@ -118,7 +121,7 @@ type InspectOptions struct{}
type VM interface {
Init(opts InitOptions) (bool, error)
Remove(name string, opts RemoveOptions) (string, func() error, error)
Set(name string, opts SetOptions) error
Set(name string, opts SetOptions) ([]error, error)
SSH(name string, opts SSHOptions) error
Start(name string, opts StartOptions) error
State(bypass bool) (Status, error)
Expand Down
43 changes: 43 additions & 0 deletions pkg/machine/e2e/config_set.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package e2e

import (
"strconv"
)

type setMachine struct {
cpus *uint
diskSize *uint
memory *uint

cmd []string
}

func (i *setMachine) buildCmd(m *machineTestBuilder) []string {
cmd := []string{"machine", "set"}
if i.cpus != nil {
cmd = append(cmd, "--cpus", strconv.Itoa(int(*i.cpus)))
}
if i.diskSize != nil {
cmd = append(cmd, "--disk-size", strconv.Itoa(int(*i.diskSize)))
}
if i.memory != nil {
cmd = append(cmd, "--memory", strconv.Itoa(int(*i.memory)))
}
cmd = append(cmd, m.name)
i.cmd = cmd
return cmd
}

func (i *setMachine) withCPUs(num uint) *setMachine {
i.cpus = &num
return i
}
func (i *setMachine) withDiskSize(size uint) *setMachine {
i.diskSize = &size
return i
}

func (i *setMachine) withMemory(num uint) *setMachine {
i.memory = &num
return i
}
139 changes: 139 additions & 0 deletions pkg/machine/e2e/set_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
package e2e

import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

var _ = Describe("podman machine set", func() {
var (
mb *machineTestBuilder
testDir string
)

BeforeEach(func() {
testDir, mb = setup()
})
AfterEach(func() {
teardown(originalHomeDir, testDir, mb)
})

It("set machine cpus", func() {
name := randomString(12)
i := new(initMachine)
session, err := mb.setName(name).setCmd(i.withImagePath(mb.imagePath)).run()
Expect(err).To(BeNil())
Expect(session.ExitCode()).To(Equal(0))

set := setMachine{}
setSession, err := mb.setName(name).setCmd(set.withCPUs(2)).run()
Expect(err).To(BeNil())
Expect(setSession.ExitCode()).To(Equal(0))

s := new(startMachine)
startSession, err := mb.setCmd(s).run()
Expect(err).To(BeNil())
Expect(startSession.ExitCode()).To(Equal(0))

ssh2 := sshMachine{}
sshSession2, err := mb.setName(name).setCmd(ssh2.withSSHComand([]string{"lscpu", "|", "grep", "\"CPU(s):\"", "|", "head", "-1"})).run()
Expect(err).To(BeNil())
Expect(sshSession2.ExitCode()).To(Equal(0))
Expect(sshSession2.outputToString()).To(ContainSubstring("2"))

})

It("increase machine disk size", func() {
name := randomString(12)
i := new(initMachine)
session, err := mb.setName(name).setCmd(i.withImagePath(mb.imagePath)).run()
Expect(err).To(BeNil())
Expect(session.ExitCode()).To(Equal(0))

set := setMachine{}
setSession, err := mb.setName(name).setCmd(set.withDiskSize(102)).run()
Expect(err).To(BeNil())
Expect(setSession.ExitCode()).To(Equal(0))

s := new(startMachine)
startSession, err := mb.setCmd(s).run()
Expect(err).To(BeNil())
Expect(startSession.ExitCode()).To(Equal(0))

ssh2 := sshMachine{}
sshSession2, err := mb.setName(name).setCmd(ssh2.withSSHComand([]string{"sudo", "fdisk", "-l", "|", "grep", "Disk"})).run()
Expect(err).To(BeNil())
Expect(sshSession2.ExitCode()).To(Equal(0))
Expect(sshSession2.outputToString()).To(ContainSubstring("102 GiB"))
})

It("decrease machine disk size should fail", func() {
name := randomString(12)
i := new(initMachine)
session, err := mb.setName(name).setCmd(i.withImagePath(mb.imagePath)).run()
Expect(err).To(BeNil())
Expect(session.ExitCode()).To(Equal(0))

set := setMachine{}
setSession, _ := mb.setName(name).setCmd(set.withDiskSize(50)).run()
// TODO seems like stderr is not being returned; re-enabled when fixed
// Expect(err).To(BeNil())
Expect(setSession.ExitCode()).To(Not(Equal(0)))
})

It("set machine ram", func() {

name := randomString(12)
i := new(initMachine)
session, err := mb.setName(name).setCmd(i.withImagePath(mb.imagePath)).run()
Expect(err).To(BeNil())
Expect(session.ExitCode()).To(Equal(0))

set := setMachine{}
setSession, err := mb.setName(name).setCmd(set.withMemory(4000)).run()
Expect(err).To(BeNil())
Expect(setSession.ExitCode()).To(Equal(0))

s := new(startMachine)
startSession, err := mb.setCmd(s).run()
Expect(err).To(BeNil())
Expect(startSession.ExitCode()).To(Equal(0))

ssh2 := sshMachine{}
sshSession2, err := mb.setName(name).setCmd(ssh2.withSSHComand([]string{"cat", "/proc/meminfo", "|", "numfmt", "--field", "2", "--from-unit=Ki", "--to-unit=Mi", "|", "sed", "'s/ kB/M/g'", "|", "grep", "MemTotal"})).run()
Expect(err).To(BeNil())
Expect(sshSession2.ExitCode()).To(Equal(0))
Expect(sshSession2.outputToString()).To(ContainSubstring("3824"))
})

It("no settings should change if no flags", func() {
name := randomString(12)
i := new(initMachine)
session, err := mb.setName(name).setCmd(i.withImagePath(mb.imagePath)).run()
Expect(err).To(BeNil())
Expect(session.ExitCode()).To(Equal(0))

set := setMachine{}
setSession, err := mb.setName(name).setCmd(&set).run()
Expect(err).To(BeNil())
Expect(setSession.ExitCode()).To(Equal(0))

s := new(startMachine)
startSession, err := mb.setCmd(s).run()
Expect(err).To(BeNil())
Expect(startSession.ExitCode()).To(Equal(0))

ssh2 := sshMachine{}
sshSession2, err := mb.setName(name).setCmd(ssh2.withSSHComand([]string{"lscpu", "|", "grep", "\"CPU(s):\"", "|", "head", "-1"})).run()
Expect(err).To(BeNil())
Expect(sshSession2.ExitCode()).To(Equal(0))
Expect(sshSession2.outputToString()).To(ContainSubstring("1"))

ssh3 := sshMachine{}
sshSession3, err := mb.setName(name).setCmd(ssh3.withSSHComand([]string{"sudo", "fdisk", "-l", "|", "grep", "Disk"})).run()
Expect(err).To(BeNil())
Expect(sshSession3.ExitCode()).To(Equal(0))
Expect(sshSession3.outputToString()).To(ContainSubstring("100 GiB"))
})

})
Loading

0 comments on commit 60d6cc8

Please sign in to comment.