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 (
startCmd = &cobra.Command{
Use: "start [MACHINE]",
Use: "start [options] [MACHINE]",
Short: "Start an existing machine",
Long: "Start a managed virtual machine ",
PersistentPreRunE: rootlessOnly,
@ -23,6 +23,7 @@ var (
Example: `podman machine start myvm`,
ValidArgsFunction: autocompleteMachine,
}
startOpts = machine.StartOptions{}
)
func init() {
@ -30,6 +31,13 @@ func init() {
Command: startCmd,
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 {
@ -37,6 +45,9 @@ func start(_ *cobra.Command, args []string) error {
err error
vm machine.VM
)
startOpts.NoInfo = startOpts.Quiet || startOpts.NoInfo
vmName := defaultMachineName
if len(args) > 0 && len(args[0]) > 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)
}
fmt.Printf("Starting machine %q\n", vmName)
if err := vm.Start(vmName, machine.StartOptions{}); err != nil {
if !startOpts.Quiet {
fmt.Printf("Starting machine %q\n", vmName)
}
if err := vm.Start(vmName, startOpts); err != nil {
return err
}
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.
#### **--no-info**
Suppress informational tips.
#### **--quiet**, **-q**
Suppress machine starting status output.
## EXAMPLES
```

View File

@ -114,7 +114,11 @@ type SSHOptions struct {
Username string
Args []string
}
type StartOptions struct{}
type StartOptions struct {
NoInfo bool
Quiet bool
}
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)
*/
quiet bool
noInfo bool
}
func (s startMachine) buildCmd(m *machineTestBuilder) []string {
@ -11,5 +13,21 @@ func (s startMachine) buildCmd(m *machineTestBuilder) []string {
if len(m.name) > 0 {
cmd = append(cmd, m.name)
}
if s.quiet {
cmd = append(cmd, "--quiet")
}
if s.noInfo {
cmd = append(cmd, "--no-info")
}
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(ec).To(BeZero())
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))
stop := new(stopMachine)
// Removing a running machine should fail
stopSession, err := mb.setCmd(stop).run()
Expect(err).To(BeNil())
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
func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
func (v *MachineVM) Start(name string, opts machine.StartOptions) error {
var (
conn net.Conn
err error
@ -613,7 +613,11 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
}
}
defer cmd.Process.Release() //nolint:errcheck
fmt.Println("Waiting for VM ...")
if !opts.Quiet {
fmt.Println("Waiting for VM ...")
}
socketPath, err := getRuntimeDir()
if err != nil {
return err
@ -659,7 +663,9 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
}
}
for _, mount := range v.Mounts {
fmt.Printf("Mounting volume... %s:%s\n", mount.Source, mount.Target)
if !opts.Quiet {
fmt.Printf("Mounting volume... %s:%s\n", mount.Source, mount.Target)
}
// create mountpoint directory if it doesn't exist
// because / is immutable, we have to monkey around with permissions
// 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
}
@ -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 := ""
if v.Name != machine.DefaultMachineName {
suffix = " " + v.Name
@ -1467,38 +1473,41 @@ func (v *MachineVM) waitAPIAndPrintInfo(forwardState apiForwardingState, forward
}
waitAndPingAPI(forwardSock)
if !v.Rootful {
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("issues with non-podman clients, you can switch using the following command: \n")
fmt.Printf("\n\tpodman machine set --rootful%s\n\n", suffix)
}
fmt.Printf("API forwarding listening on: %s\n", forwardSock)
if forwardState == dockerGlobal {
fmt.Printf("Docker API clients default to this address. You do not need to set DOCKER_HOST.\n\n")
} else {
stillString := "still "
switch forwardState {
case notInstalled:
fmt.Printf("\nThe system helper service is not installed; the default Docker API socket\n")
fmt.Printf("address can't be used by podman. ")
if helper := findClaimHelper(); len(helper) > 0 {
fmt.Printf("If you would like to install it run the\nfollowing commands:\n")
fmt.Printf("\n\tsudo %s install\n", helper)
fmt.Printf("\tpodman machine stop%s; podman machine start%s\n\n", suffix, suffix)
}
case machineLocal:
fmt.Printf("\nAnother process was listening on the default Docker API socket address.\n")
case claimUnsupported:
fallthrough
default:
stillString = ""
if !noInfo {
if !v.Rootful {
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("issues with non-podman clients, you can switch using the following command: \n")
fmt.Printf("\n\tpodman machine set --rootful%s\n\n", suffix)
}
fmt.Printf("You can %sconnect Docker API clients by setting DOCKER_HOST using the\n", stillString)
fmt.Printf("following command in your terminal session:\n")
fmt.Printf("\n\texport DOCKER_HOST='unix://%s'\n\n", forwardSock)
fmt.Printf("API forwarding listening on: %s\n", forwardSock)
if forwardState == dockerGlobal {
fmt.Printf("Docker API clients default to this address. You do not need to set DOCKER_HOST.\n\n")
} else {
stillString := "still "
switch forwardState {
case notInstalled:
fmt.Printf("\nThe system helper service is not installed; the default Docker API socket\n")
fmt.Printf("address can't be used by podman. ")
if helper := findClaimHelper(); len(helper) > 0 {
fmt.Printf("If you would like to install it run the\nfollowing commands:\n")
fmt.Printf("\n\tsudo %s install\n", helper)
fmt.Printf("\tpodman machine stop%s; podman machine start%s\n\n", suffix, suffix)
}
case machineLocal:
fmt.Printf("\nAnother process was listening on the default Docker API socket address.\n")
case claimUnsupported:
fallthrough
default:
stillString = ""
}
fmt.Printf("You can %sconnect Docker API clients by setting DOCKER_HOST using the\n", stillString)
fmt.Printf("following command in your terminal session:\n")
fmt.Printf("\n\texport DOCKER_HOST='unix://%s'\n\n", forwardSock)
}
}
}

View File

@ -577,7 +577,7 @@ func configureSystem(v *MachineVM, dist string) error {
return nil
}
func configureProxy(dist string, useProxy bool) error {
func configureProxy(dist string, useProxy bool, quiet bool) error {
if !useProxy {
_ = wslInvoke(dist, "sh", "-c", clearProxySettings)
return nil
@ -598,8 +598,9 @@ func configureProxy(dist string, useProxy bool) error {
if exitErr, isExit := err.(*exec.ExitError); isExit && exitErr.ExitCode() != 42 {
return fmt.Errorf("%v: %w", failMessage, err)
}
fmt.Println("Installing proxy support")
if !quiet {
fmt.Println("Installing proxy support")
}
_ = wslPipe(proxyConfigSetup, dist, "sh", "-c",
"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()
}
func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
func (v *MachineVM) Start(name string, opts machine.StartOptions) error {
if v.isRunning() {
return fmt.Errorf("%q is already running", name)
}
dist := toDist(name)
useProxy := setupWslProxyEnv()
if err := configureProxy(dist, useProxy); err != nil {
if err := configureProxy(dist, useProxy, opts.Quiet); err != nil {
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)
}
if !v.Rootful {
if !v.Rootful && !opts.NoInfo {
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("issues with non-podman clients, you can switch using the following command: \n")
@ -1010,22 +1011,24 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
}
globalName, pipeName, err := launchWinProxy(v)
if err != nil {
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.Fprintln(os.Stderr, "\nPodman clients are still able to connect.")
} else {
fmt.Printf("API forwarding listening on: %s\n", pipeName)
if globalName {
fmt.Printf("\nDocker API clients default to this address. You do not need to set DOCKER_HOST.\n")
if !opts.NoInfo {
if err != nil {
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.Fprintln(os.Stderr, "\nPodman clients are still able to connect.")
} else {
fmt.Printf("\nAnother process was listening on the default Docker API pipe address.\n")
fmt.Printf("You can still connect Docker API clients by setting DOCKER HOST using the\n")
fmt.Printf("following powershell command in your terminal session:\n")
fmt.Printf("\n\t$Env:DOCKER_HOST = '%s'\n", pipeName)
fmt.Printf("\nOr in a classic CMD prompt:\n")
fmt.Printf("\n\tset DOCKER_HOST = '%s'\n", pipeName)
fmt.Printf("\nAlternatively terminate the other process and restart podman machine.\n")
fmt.Printf("API forwarding listening on: %s\n", pipeName)
if globalName {
fmt.Printf("\nDocker API clients default to this address. You do not need to set DOCKER_HOST.\n")
} else {
fmt.Printf("\nAnother process was listening on the default Docker API pipe address.\n")
fmt.Printf("You can still connect Docker API clients by setting DOCKER HOST using the\n")
fmt.Printf("following powershell command in your terminal session:\n")
fmt.Printf("\n\t$Env:DOCKER_HOST = '%s'\n", pipeName)
fmt.Printf("\nOr in a classic CMD prompt:\n")
fmt.Printf("\n\tset DOCKER_HOST = '%s'\n", pipeName)
fmt.Printf("\nAlternatively terminate the other process and restart podman machine.\n")
}
}
}