Ignore prompt if stdin not a tty on machine start

When starting a machine and the user has not explicitly passed
-u=true|false AND stdin is a not a tty, we should not prompt to update
connections.

Fixes: #27556

Signed-off-by: Brent Baude <bbaude@redhat.com>
This commit is contained in:
Brent Baude
2025-11-18 10:00:00 -06:00
parent 5c48d02fe8
commit 3d566d85cf
3 changed files with 22 additions and 12 deletions

View File

@@ -7,7 +7,8 @@
When used in conjunction with `podman machine init --now` or `podman machine start`, this option sets the When used in conjunction with `podman machine init --now` or `podman machine start`, this option sets the
associated machine system connection as the default. When using this option, a `-u` or `-update-connection` will associated machine system connection as the default. When using this option, a `-u` or `-update-connection` will
set the value to true. To set this value to false, meaning no change and no prompting, set the value to true. To set this value to false, meaning no change and no prompting,
use `--update-connection=false`. use `--update-connection=false`. If the value is unset and stdin is not a tty, no prompt or update
shall occur.
If the value is set to true, the machine connection will be set as the system default. If the value is set to true, the machine connection will be set as the system default.
If the value is set to false, the system default will be unchanged. If the value is set to false, the system default will be unchanged.

View File

@@ -1,6 +1,7 @@
package e2e_test package e2e_test
import ( import (
"bytes"
"fmt" "fmt"
"net" "net"
"net/url" "net/url"
@@ -135,22 +136,28 @@ var _ = Describe("podman machine start", func() {
}) })
It("start only starts specified machine", func() { It("start only starts specified machine", func() {
i := initMachine{}
startme := randomString()
session, err := mb.setName(startme).setCmd(i.withImage(mb.imagePath)).run()
Expect(err).ToNot(HaveOccurred())
Expect(session).To(Exit(0))
j := initMachine{} j := initMachine{}
dontstartme := randomString() dontstartme := randomString()
session2, err := mb.setName(dontstartme).setCmd(j.withFakeImage(mb)).run() session2, err := mb.setName(dontstartme).setCmd(j.withFakeImage(mb)).run()
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(session2).To(Exit(0)) Expect(session2).To(Exit(0))
i := initMachine{}
startme := randomString()
session, err := mb.setName(startme).setCmd(i.withImage(mb.imagePath)).run()
Expect(err).ToNot(HaveOccurred())
Expect(session).To(Exit(0))
s := &startMachine{} s := &startMachine{}
session3, err := mb.setName(startme).setCmd(s).setTimeout(time.Minute * 10).run() // Provide a buffer as stdin to simulate non-tty input (e.g., piped or redirected stdin)
// When stdin is not a tty, the command should not prompt for connection updates
stdinBuf := bytes.NewBufferString("n\n")
session3, err := mb.setName(startme).setCmd(s).setTimeout(time.Minute * 10).setStdin(stdinBuf).run()
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(session3).Should(Exit(0)) Expect(session3).Should(Exit(0))
// Verify that the prompt message did not appear (no prompting when stdin is not a tty)
combinedOutput := session3.outputToString() + session3.errorToString()
Expect(combinedOutput).ToNot(ContainSubstring("Set the default Podman connection to this machine"), "should not prompt when stdin is not a tty")
inspect := new(inspectMachine) inspect := new(inspectMachine)
inspect = inspect.withFormat("{{.State}}") inspect = inspect.withFormat("{{.State}}")

View File

@@ -29,6 +29,7 @@ import (
"github.com/hashicorp/go-multierror" "github.com/hashicorp/go-multierror"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"go.podman.io/common/pkg/config" "go.podman.io/common/pkg/config"
"golang.org/x/term"
) )
// List is done at the host level to allow for a *possible* future where // List is done at the host level to allow for a *possible* future where
@@ -501,8 +502,11 @@ func Start(mc *vmconfigs.MachineConfig, mp vmconfigs.VMProvider, opts machine.St
// Do not do anything with the system connection if its already // Do not do anything with the system connection if its already
// the default system connection. // the default system connection.
if !conn.Default { if !conn.Default {
// Prompt for system connection update if updateSystemConn != nil {
if updateSystemConn == nil { updateDefaultConnection = *updateSystemConn
} else if term.IsTerminal(int(os.Stdin.Fd())) {
// Prompt for system connection update if there is a terminal
// on stdin
response, err := promptUpdateSystemConn() response, err := promptUpdateSystemConn()
if err != nil { if err != nil {
return err return err
@@ -517,8 +521,6 @@ func Start(mc *vmconfigs.MachineConfig, mp vmconfigs.VMProvider, opts machine.St
fmt.Println("Default system connection will remain unchanged") fmt.Println("Default system connection will remain unchanged")
} }
updateDefaultConnection = response updateDefaultConnection = response
} else {
updateDefaultConnection = *updateSystemConn
} }
} }