Add --quiet and --no-info flags to podman machine start

Add quiet and no-info flags to podman machine start.
No-info suppresses helpful informational tips
Quiet suppresses machine start progress output, as well as informational
tips.

Signed-off-by: Ashley Cui <acui@redhat.com>
This commit is contained in:
Ashley Cui
2022-10-13 19:36:18 -04:00
parent c75b05996d
commit dd98e3cc64
8 changed files with 134 additions and 60 deletions

View File

@ -14,7 +14,7 @@ import (
var ( var (
startCmd = &cobra.Command{ startCmd = &cobra.Command{
Use: "start [MACHINE]", Use: "start [options] [MACHINE]",
Short: "Start an existing machine", Short: "Start an existing machine",
Long: "Start a managed virtual machine ", Long: "Start a managed virtual machine ",
PersistentPreRunE: rootlessOnly, PersistentPreRunE: rootlessOnly,
@ -23,6 +23,7 @@ var (
Example: `podman machine start myvm`, Example: `podman machine start myvm`,
ValidArgsFunction: autocompleteMachine, ValidArgsFunction: autocompleteMachine,
} }
startOpts = machine.StartOptions{}
) )
func init() { func init() {
@ -30,6 +31,13 @@ func init() {
Command: startCmd, Command: startCmd,
Parent: machineCmd, Parent: machineCmd,
}) })
flags := startCmd.Flags()
noInfoFlagName := "no-info"
flags.BoolVar(&startOpts.NoInfo, noInfoFlagName, false, "Suppress informational tips")
quietFlagName := "quiet"
flags.BoolVarP(&startOpts.Quiet, quietFlagName, "q", false, "Suppress machine starting status output")
} }
func start(_ *cobra.Command, args []string) error { func start(_ *cobra.Command, args []string) error {
@ -37,6 +45,9 @@ func start(_ *cobra.Command, args []string) error {
err error err error
vm machine.VM vm machine.VM
) )
startOpts.NoInfo = startOpts.Quiet || startOpts.NoInfo
vmName := defaultMachineName vmName := defaultMachineName
if len(args) > 0 && len(args[0]) > 0 { if len(args) > 0 && len(args[0]) > 0 {
vmName = args[0] vmName = args[0]
@ -58,8 +69,10 @@ func start(_ *cobra.Command, args []string) error {
} }
return fmt.Errorf("cannot start VM %s. VM %s is currently running or starting: %w", vmName, activeName, machine.ErrMultipleActiveVM) return fmt.Errorf("cannot start VM %s. VM %s is currently running or starting: %w", vmName, activeName, machine.ErrMultipleActiveVM)
} }
if !startOpts.Quiet {
fmt.Printf("Starting machine %q\n", vmName) fmt.Printf("Starting machine %q\n", vmName)
if err := vm.Start(vmName, machine.StartOptions{}); err != nil { }
if err := vm.Start(vmName, startOpts); err != nil {
return err return err
} }
fmt.Printf("Machine %q started successfully\n", vmName) fmt.Printf("Machine %q started successfully\n", vmName)

View File

@ -28,6 +28,14 @@ Only one Podman managed VM can be active at a time. If a VM is already running,
Print usage statement. Print usage statement.
#### **--no-info**
Suppress informational tips.
#### **--quiet**, **-q**
Suppress machine starting status output.
## EXAMPLES ## EXAMPLES
``` ```

View File

@ -114,7 +114,11 @@ type SSHOptions struct {
Username string Username string
Args []string Args []string
} }
type StartOptions struct{}
type StartOptions struct {
NoInfo bool
Quiet bool
}
type StopOptions struct{} type StopOptions struct{}

View File

@ -4,6 +4,8 @@ type startMachine struct {
/* /*
No command line args other than a machine vm name (also not required) No command line args other than a machine vm name (also not required)
*/ */
quiet bool
noInfo bool
} }
func (s startMachine) buildCmd(m *machineTestBuilder) []string { func (s startMachine) buildCmd(m *machineTestBuilder) []string {
@ -11,5 +13,21 @@ func (s startMachine) buildCmd(m *machineTestBuilder) []string {
if len(m.name) > 0 { if len(m.name) > 0 {
cmd = append(cmd, m.name) cmd = append(cmd, m.name)
} }
if s.quiet {
cmd = append(cmd, "--quiet")
}
if s.noInfo {
cmd = append(cmd, "--no-info")
}
return cmd return cmd
} }
func (s startMachine) withQuiet() startMachine {
s.quiet = true
return s
}
func (s startMachine) withNoInfo() startMachine {
s.noInfo = true
return s
}

View File

@ -33,5 +33,25 @@ var _ = Describe("podman machine start", func() {
Expect(err).To(BeNil()) Expect(err).To(BeNil())
Expect(ec).To(BeZero()) Expect(ec).To(BeZero())
Expect(info[0].State).To(Equal(machine.Running)) Expect(info[0].State).To(Equal(machine.Running))
stop := new(stopMachine)
stopSession, err := mb.setCmd(stop).run()
Expect(err).To(BeNil())
Expect(stopSession).To(Exit(0))
// suppress output
startSession, err = mb.setCmd(s.withNoInfo()).run()
Expect(err).To(BeNil())
Expect(startSession).To(Exit(0))
Expect(startSession.outputToString()).ToNot(ContainSubstring("API forwarding"))
stopSession, err = mb.setCmd(stop).run()
Expect(err).To(BeNil())
Expect(stopSession).To(Exit(0))
startSession, err = mb.setCmd(s.withQuiet()).run()
Expect(err).To(BeNil())
Expect(startSession).To(Exit(0))
Expect(len(startSession.outputToStringSlice())).To(Equal(1))
}) })
}) })

View File

@ -34,7 +34,6 @@ var _ = Describe("podman machine stop", func() {
Expect(session).To(Exit(0)) Expect(session).To(Exit(0))
stop := new(stopMachine) stop := new(stopMachine)
// Removing a running machine should fail
stopSession, err := mb.setCmd(stop).run() stopSession, err := mb.setCmd(stop).run()
Expect(err).To(BeNil()) Expect(err).To(BeNil())
Expect(stopSession).To(Exit(0)) Expect(stopSession).To(Exit(0))

View File

@ -467,7 +467,7 @@ func (v *MachineVM) Set(_ string, opts machine.SetOptions) ([]error, error) {
} }
// Start executes the qemu command line and forks it // Start executes the qemu command line and forks it
func (v *MachineVM) Start(name string, _ machine.StartOptions) error { func (v *MachineVM) Start(name string, opts machine.StartOptions) error {
var ( var (
conn net.Conn conn net.Conn
err error err error
@ -613,7 +613,11 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
} }
} }
defer cmd.Process.Release() //nolint:errcheck defer cmd.Process.Release() //nolint:errcheck
if !opts.Quiet {
fmt.Println("Waiting for VM ...") fmt.Println("Waiting for VM ...")
}
socketPath, err := getRuntimeDir() socketPath, err := getRuntimeDir()
if err != nil { if err != nil {
return err return err
@ -659,7 +663,9 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
} }
} }
for _, mount := range v.Mounts { for _, mount := range v.Mounts {
if !opts.Quiet {
fmt.Printf("Mounting volume... %s:%s\n", mount.Source, mount.Target) fmt.Printf("Mounting volume... %s:%s\n", mount.Source, mount.Target)
}
// create mountpoint directory if it doesn't exist // create mountpoint directory if it doesn't exist
// because / is immutable, we have to monkey around with permissions // because / is immutable, we have to monkey around with permissions
// if we dont mount in /home or /mnt // if we dont mount in /home or /mnt
@ -692,7 +698,7 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
} }
} }
v.waitAPIAndPrintInfo(forwardState, forwardSock) v.waitAPIAndPrintInfo(forwardState, forwardSock, opts.NoInfo)
return nil return nil
} }
@ -1439,7 +1445,7 @@ func waitAndPingAPI(sock string) {
} }
} }
func (v *MachineVM) waitAPIAndPrintInfo(forwardState apiForwardingState, forwardSock string) { func (v *MachineVM) waitAPIAndPrintInfo(forwardState apiForwardingState, forwardSock string, noInfo bool) {
suffix := "" suffix := ""
if v.Name != machine.DefaultMachineName { if v.Name != machine.DefaultMachineName {
suffix = " " + v.Name suffix = " " + v.Name
@ -1467,6 +1473,8 @@ func (v *MachineVM) waitAPIAndPrintInfo(forwardState apiForwardingState, forward
} }
waitAndPingAPI(forwardSock) waitAndPingAPI(forwardSock)
if !noInfo {
if !v.Rootful { if !v.Rootful {
fmt.Printf("\nThis machine is currently configured in rootless mode. If your containers\n") fmt.Printf("\nThis machine is currently configured in rootless mode. If your containers\n")
fmt.Printf("require root permissions (e.g. ports < 1024), or if you run into compatibility\n") fmt.Printf("require root permissions (e.g. ports < 1024), or if you run into compatibility\n")
@ -1501,6 +1509,7 @@ func (v *MachineVM) waitAPIAndPrintInfo(forwardState apiForwardingState, forward
fmt.Printf("\n\texport DOCKER_HOST='unix://%s'\n\n", forwardSock) fmt.Printf("\n\texport DOCKER_HOST='unix://%s'\n\n", forwardSock)
} }
} }
}
// update returns the content of the VM's // update returns the content of the VM's
// configuration file in json // configuration file in json

View File

@ -577,7 +577,7 @@ func configureSystem(v *MachineVM, dist string) error {
return nil return nil
} }
func configureProxy(dist string, useProxy bool) error { func configureProxy(dist string, useProxy bool, quiet bool) error {
if !useProxy { if !useProxy {
_ = wslInvoke(dist, "sh", "-c", clearProxySettings) _ = wslInvoke(dist, "sh", "-c", clearProxySettings)
return nil return nil
@ -598,8 +598,9 @@ func configureProxy(dist string, useProxy bool) error {
if exitErr, isExit := err.(*exec.ExitError); isExit && exitErr.ExitCode() != 42 { if exitErr, isExit := err.(*exec.ExitError); isExit && exitErr.ExitCode() != 42 {
return fmt.Errorf("%v: %w", failMessage, err) return fmt.Errorf("%v: %w", failMessage, err)
} }
if !quiet {
fmt.Println("Installing proxy support") fmt.Println("Installing proxy support")
}
_ = wslPipe(proxyConfigSetup, dist, "sh", "-c", _ = wslPipe(proxyConfigSetup, dist, "sh", "-c",
"cat > /usr/local/bin/proxyinit; chmod 755 /usr/local/bin/proxyinit") "cat > /usr/local/bin/proxyinit; chmod 755 /usr/local/bin/proxyinit")
@ -981,14 +982,14 @@ func (v *MachineVM) Set(_ string, opts machine.SetOptions) ([]error, error) {
return setErrors, v.writeConfig() return setErrors, v.writeConfig()
} }
func (v *MachineVM) Start(name string, _ machine.StartOptions) error { func (v *MachineVM) Start(name string, opts machine.StartOptions) error {
if v.isRunning() { if v.isRunning() {
return fmt.Errorf("%q is already running", name) return fmt.Errorf("%q is already running", name)
} }
dist := toDist(name) dist := toDist(name)
useProxy := setupWslProxyEnv() useProxy := setupWslProxyEnv()
if err := configureProxy(dist, useProxy); err != nil { if err := configureProxy(dist, useProxy, opts.Quiet); err != nil {
return err return err
} }
@ -997,7 +998,7 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
return fmt.Errorf("the WSL bootstrap script failed: %w", err) return fmt.Errorf("the WSL bootstrap script failed: %w", err)
} }
if !v.Rootful { if !v.Rootful && !opts.NoInfo {
fmt.Printf("\nThis machine is currently configured in rootless mode. If your containers\n") fmt.Printf("\nThis machine is currently configured in rootless mode. If your containers\n")
fmt.Printf("require root permissions (e.g. ports < 1024), or if you run into compatibility\n") fmt.Printf("require root permissions (e.g. ports < 1024), or if you run into compatibility\n")
fmt.Printf("issues with non-podman clients, you can switch using the following command: \n") fmt.Printf("issues with non-podman clients, you can switch using the following command: \n")
@ -1010,6 +1011,7 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
} }
globalName, pipeName, err := launchWinProxy(v) globalName, pipeName, err := launchWinProxy(v)
if !opts.NoInfo {
if err != nil { if err != nil {
fmt.Fprintln(os.Stderr, "API forwarding for Docker API clients is not available due to the following startup failures.") fmt.Fprintln(os.Stderr, "API forwarding for Docker API clients is not available due to the following startup failures.")
fmt.Fprintf(os.Stderr, "\t%s\n", err.Error()) fmt.Fprintf(os.Stderr, "\t%s\n", err.Error())
@ -1028,6 +1030,7 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
fmt.Printf("\nAlternatively terminate the other process and restart podman machine.\n") fmt.Printf("\nAlternatively terminate the other process and restart podman machine.\n")
} }
} }
}
_, _, err = v.updateTimeStamps(true) _, _, err = v.updateTimeStamps(true)
return err return err