diff --git a/pkg/machine/e2e/proxy_test.go b/pkg/machine/e2e/proxy_test.go index eb48e40f99..b83cf4509c 100644 --- a/pkg/machine/e2e/proxy_test.go +++ b/pkg/machine/e2e/proxy_test.go @@ -2,6 +2,7 @@ package e2e_test import ( "os" + "path/filepath" "github.com/containers/podman/v5/pkg/machine/define" . "github.com/onsi/ginkgo/v2" @@ -23,29 +24,30 @@ var _ = Describe("podman machine proxy settings propagation", func() { }) It("ssh to running machine and check proxy settings", func() { - // TODO the proxy test is currently failing on applehv. FIX ME - skipIfVmtype(define.AppleHvVirt, "TODO: this test fails on applehv") + defer func() { + os.Unsetenv("HTTP_PROXY") + os.Unsetenv("HTTPS_PROXY") + os.Unsetenv("SSL_CERT_DIR") + os.Unsetenv("SSL_CERT_FILE") + }() + + certFileDir := GinkgoT().TempDir() + certDir := GinkgoT().TempDir() + certFile := filepath.Join(certFileDir, "cert1") + err := os.WriteFile(certFile, []byte("cert1 content\n"), os.ModePerm) + Expect(err).ToNot(HaveOccurred()) + err = os.WriteFile(filepath.Join(certDir, "cert2"), []byte("cert2 content\n"), os.ModePerm) + Expect(err).ToNot(HaveOccurred()) + + os.Setenv("SSL_CERT_FILE", certFile) + os.Setenv("SSL_CERT_DIR", certDir) - // https://github.com/containers/podman/issues/20129 - if testProvider.VMType() == define.HyperVVirt { - Skip("proxy settings not yet supported") - } name := randomString() i := new(initMachine) session, err := mb.setName(name).setCmd(i.withImagePath(mb.imagePath)).run() Expect(err).ToNot(HaveOccurred()) Expect(session).To(Exit(0)) - defer func() { - httpProxyEnv := os.Getenv("HTTP_PROXY") - httpsProxyEnv := os.Getenv("HTTPS_PROXY") - if httpProxyEnv != "" { - os.Unsetenv("HTTP_PROXY") - } - if httpsProxyEnv != "" { - os.Unsetenv("HTTPS_PROXY") - } - }() proxyURL := "http://abcdefghijklmnopqrstuvwxyz-proxy" os.Setenv("HTTP_PROXY", proxyURL) os.Setenv("HTTPS_PROXY", proxyURL) @@ -65,5 +67,52 @@ var _ = Describe("podman machine proxy settings propagation", func() { Expect(err).ToNot(HaveOccurred()) Expect(sshSession).To(Exit(0)) Expect(sshSession.outputToString()).To(ContainSubstring(proxyURL)) + + // SSL_CERT not implemented for WSL + if !isVmtype(define.WSLVirt) { + sshSession, err = mb.setName(name).setCmd(sshProxy.withSSHCommand([]string{"printenv", "SSL_CERT_DIR", "SSL_CERT_FILE"})).run() + Expect(err).ToNot(HaveOccurred()) + Expect(sshSession).To(Exit(0)) + Expect(string(sshSession.Out.Contents())).To(Equal(define.UserCertsTargetPath + "\n" + define.UserCertsTargetPath + "/cert1" + "\n")) + + sshSession, err = mb.setName(name).setCmd(sshProxy.withSSHCommand([]string{"cat", "$SSL_CERT_DIR/cert2", "$SSL_CERT_FILE"})).run() + Expect(err).ToNot(HaveOccurred()) + Expect(sshSession).To(Exit(0)) + Expect(string(sshSession.Out.Contents())).To(Equal("cert2 content\ncert1 content\n")) + } + + stop := new(stopMachine) + stopSession, err := mb.setName(name).setCmd(stop).run() + Expect(err).ToNot(HaveOccurred()) + Expect(stopSession).To(Exit(0)) + + // Now update proxy env, lets use some special vars to make sure our scripts can handle it + proxy1 := "http:// some special @;\" here" + proxy2 := "https://abc :£$%6 : |\"\"" + os.Setenv("HTTP_PROXY", proxy1) + os.Setenv("HTTPS_PROXY", proxy2) + + // changing SSL_CERT vars should not have an effect + os.Setenv("SSL_CERT_FILE", "/tmp/1") + os.Setenv("SSL_CERT_DIR", "/tmp") + + // start it again should update the proxies + startSession, err = mb.setName(name).setCmd(s).run() + Expect(err).ToNot(HaveOccurred()) + Expect(startSession).To(Exit(0)) + + sshSession, err = mb.setName(name).setCmd(sshProxy.withSSHCommand([]string{"printenv", "HTTP_PROXY", "HTTPS_PROXY"})).run() + Expect(err).ToNot(HaveOccurred()) + Expect(sshSession).To(Exit(0)) + Expect(string(sshSession.Out.Contents())).To(Equal(proxy1 + "\n" + proxy2 + "\n")) + + // SSL_CERT not implemented for WSL + if !isVmtype(define.WSLVirt) { + // SSL_CERT... must still be the same as before + sshSession, err = mb.setName(name).setCmd(sshProxy.withSSHCommand([]string{"cat", "$SSL_CERT_DIR/cert2", "$SSL_CERT_FILE"})).run() + Expect(err).ToNot(HaveOccurred()) + Expect(sshSession).To(Exit(0)) + Expect(string(sshSession.Out.Contents())).To(Equal("cert2 content\ncert1 content\n")) + } }) }) diff --git a/pkg/machine/ignition/ignition.go b/pkg/machine/ignition/ignition.go index 1b337783c5..432d0bb8ee 100644 --- a/pkg/machine/ignition/ignition.go +++ b/pkg/machine/ignition/ignition.go @@ -8,6 +8,7 @@ import ( "io/fs" "net/url" "os" + "path" "path/filepath" "github.com/containers/podman/v5/pkg/machine/define" @@ -178,46 +179,6 @@ ExecStart= ExecStart=-/usr/sbin/agetty --autologin root --noclear %I $TERM ` - // This service gets environment variables that are provided - // through qemu fw_cfg and then sets them into systemd/system.conf.d, - // profile.d and environment.d files - // - // Currently, it is used for propagating - // proxy settings e.g. HTTP_PROXY and others, on a start avoiding - // a need of re-creating/re-initiating a VM - - envset := parser.NewUnitFile() - envset.Add("Unit", "Description", "Environment setter from QEMU FW_CFG") - - envset.Add("Service", "Type", "oneshot") - envset.Add("Service", "RemainAfterExit", "yes") - envset.Add("Service", "Environment", "FWCFGRAW=/sys/firmware/qemu_fw_cfg/by_name/opt/com.coreos/environment/raw") - envset.Add("Service", "Environment", "SYSTEMD_CONF=/etc/systemd/system.conf.d/default-env.conf") - envset.Add("Service", "Environment", "ENVD_CONF=/etc/environment.d/default-env.conf") - envset.Add("Service", "Environment", "PROFILE_CONF=/etc/profile.d/default-env.sh") - envset.Add("Service", "ExecStart", `/usr/bin/bash -c '/usr/bin/test -f ${FWCFGRAW} &&\ - echo "[Manager]\n#Got from QEMU FW_CFG\nDefaultEnvironment=$(/usr/bin/base64 -d ${FWCFGRAW} | sed -e "s+|+ +g")\n" > ${SYSTEMD_CONF} ||\ - echo "[Manager]\n#Got nothing from QEMU FW_CFG\n#DefaultEnvironment=\n" > ${SYSTEMD_CONF}'`) - envset.Add("Service", "ExecStart", `/usr/bin/bash -c '/usr/bin/test -f ${FWCFGRAW} && (\ - echo "#Got from QEMU FW_CFG"> ${ENVD_CONF};\ - IFS="|";\ - for iprxy in $(/usr/bin/base64 -d ${FWCFGRAW}); do\ - echo "$iprxy" >> ${ENVD_CONF}; done ) || \ - echo "#Got nothing from QEMU FW_CFG"> ${ENVD_CONF}'`) - envset.Add("Service", "ExecStart", `/usr/bin/bash -c '/usr/bin/test -f ${FWCFGRAW} && (\ - echo "#Got from QEMU FW_CFG"> ${PROFILE_CONF};\ - IFS="|";\ - for iprxy in $(/usr/bin/base64 -d ${FWCFGRAW}); do\ - echo "export $iprxy" >> ${PROFILE_CONF}; done ) || \ - echo "#Got nothing from QEMU FW_CFG"> ${PROFILE_CONF}'`) - envset.Add("Service", "ExecStartPost", "/usr/bin/systemctl daemon-reload") - - envset.Add("Install", "WantedBy", "sysinit.target") - envsetFile, err := envset.ToString() - if err != nil { - return err - } - ignSystemd := Systemd{ Units: []Unit{ { @@ -261,16 +222,6 @@ ExecStart=-/usr/sbin/agetty --autologin root --noclear %I $TERM }, } - // Only qemu has the qemu firmware environment setting - if ign.VMType == define.QemuVirt { - qemuUnit := Unit{ - Enabled: BoolToPtr(true), - Name: "envset-fwcfg.service", - Contents: &envsetFile, - } - ignSystemd.Units = append(ignSystemd.Units, qemuUnit) - } - if ign.NetRecover { contents, err := GetNetRecoveryUnitFile().ToString() if err != nil { @@ -582,23 +533,29 @@ Delegate=memory pids cpu io certFiles = getCerts(filepath.Join(userHome, ".config/docker/certs.d"), true) files = append(files, certFiles...) - if sslCertFile, ok := os.LookupEnv("SSL_CERT_FILE"); ok { - if _, err := os.Stat(sslCertFile); err == nil { - certFiles = getCerts(sslCertFile, false) + sslCertFileName, ok := os.LookupEnv(sslCertFile) + if ok { + if _, err := os.Stat(sslCertFileName); err == nil { + certFiles = getCerts(sslCertFileName, false) files = append(files, certFiles...) } else { - logrus.Warnf("Invalid path in SSL_CERT_FILE: %q", err) + logrus.Warnf("Invalid path in %s: %q", sslCertFile, err) } } - if sslCertDir, ok := os.LookupEnv("SSL_CERT_DIR"); ok { - if _, err := os.Stat(sslCertDir); err == nil { - certFiles = getCerts(sslCertDir, true) + sslCertDirName, ok := os.LookupEnv(sslCertDir) + if ok { + if _, err := os.Stat(sslCertDirName); err == nil { + certFiles = getCerts(sslCertDirName, true) files = append(files, certFiles...) } else { - logrus.Warnf("Invalid path in SSL_CERT_DIR: %q", err) + logrus.Warnf("Invalid path in %s: %q", sslCertDir, err) } } + if sslCertFileName != "" || sslCertDirName != "" { + // If we copied certs via env then also make the to set the env in the VM. + files = append(files, getSSLEnvironmentFiles(sslCertFileName, sslCertDirName)...) + } files = append(files, File{ Node: Node{ @@ -686,16 +643,18 @@ func getCerts(certsDir string, isDir bool) []File { return files } -func prepareCertFile(path string, name string) (File, error) { - b, err := os.ReadFile(path) +func prepareCertFile(fpath string, name string) (File, error) { + b, err := os.ReadFile(fpath) if err != nil { logrus.Warnf("Unable to read cert file %v", err) return File{}, err } - targetPath := filepath.Join(define.UserCertsTargetPath, name) + // Note path is required here as we always create a path for the linux VM + // even when the client run on windows so we cannot use filepath. + targetPath := path.Join(define.UserCertsTargetPath, name) - logrus.Debugf("Copying cert file from '%s' to '%s'.", path, targetPath) + logrus.Debugf("Copying cert file from '%s' to '%s'.", fpath, targetPath) file := File{ Node: Node{ @@ -714,6 +673,57 @@ func prepareCertFile(path string, name string) (File, error) { return file, nil } +const ( + systemdSSLConf = "/etc/systemd/system.conf.d/podman-machine-ssl.conf" + envdSSLConf = "/etc/environment.d/podman-machine-ssl.conf" + profileSSLConf = "/etc/profile.d/podman-machine-ssl.sh" + sslCertFile = "SSL_CERT_FILE" + sslCertDir = "SSL_CERT_DIR" +) + +func getSSLEnvironmentFiles(sslFileName, sslDirName string) []File { + systemdFileContent := "[Manager]\n" + envdFileContent := "" + profileFileContent := "" + if sslFileName != "" { + // certs are written to UserCertsTargetPath see prepareCertFile() + // Note the mix of path/filepath is intentional and required, we want to get the name of + // a path on the client (i.e. windows) but then join to linux path that will be used inside the VM. + env := fmt.Sprintf("%s=%q\n", sslCertFile, path.Join(define.UserCertsTargetPath, filepath.Base(sslFileName))) + systemdFileContent += "DefaultEnvironment=" + env + envdFileContent += env + profileFileContent += "export " + env + } + if sslDirName != "" { + // certs are written to UserCertsTargetPath see prepareCertFile() + env := fmt.Sprintf("%s=%q\n", sslCertDir, define.UserCertsTargetPath) + systemdFileContent += "DefaultEnvironment=" + env + envdFileContent += env + profileFileContent += "export " + env + } + return []File{ + getSSLFile(systemdSSLConf, systemdFileContent), + getSSLFile(envdSSLConf, envdFileContent), + getSSLFile(profileSSLConf, profileFileContent), + } +} + +func getSSLFile(path, content string) File { + return File{ + Node: Node{ + Group: GetNodeGrp("root"), + Path: path, + User: GetNodeUsr("root"), + }, + FileEmbedded1: FileEmbedded1{ + Contents: Resource{ + Source: EncodeDataURLPtr(content), + }, + Mode: IntToPtr(0644), + }, + } +} + func getLinks(usrName string) []Link { return []Link{{ Node: Node{ diff --git a/pkg/machine/proxyenv/env.go b/pkg/machine/proxyenv/env.go new file mode 100644 index 0000000000..1b358ad72a --- /dev/null +++ b/pkg/machine/proxyenv/env.go @@ -0,0 +1,57 @@ +package proxyenv + +import ( + "fmt" + "io" + "os" + "strings" + + "github.com/containers/common/libnetwork/etchosts" + "github.com/containers/common/pkg/config" + "github.com/containers/podman/v5/pkg/machine" + "github.com/containers/podman/v5/pkg/machine/vmconfigs" + "github.com/sirupsen/logrus" +) + +const proxySetupScriptTemplate = `#!/bin/bash + +SYSTEMD_CONF=/etc/systemd/system.conf.d/default-env.conf +ENVD_CONF=/etc/environment.d/default-env.conf +PROFILE_CONF=/etc/profile.d/default-env.sh + +mkdir -p /etc/profile.d /etc/environment.d /etc/systemd/system.conf.d/ +rm -f $SYSTEMD_CONF $ENVD_CONF $PROFILE_CONF + +echo "[Manager]" >> $SYSTEMD_CONF +for proxy in %s; do + printf "DefaultEnvironment=%%q\n" "$proxy" >> $SYSTEMD_CONF + printf "%%q\n" "$proxy" >> $ENVD_CONF + printf "export %%q\n" "$proxy" >> $PROFILE_CONF +done + +systemctl daemon-reload +` + +func getProxyScript(isWSL bool) io.Reader { + var envs []string + for _, key := range config.ProxyEnv { + if value, ok := os.LookupEnv(key); ok { + // WSL does not use host.containers.internal as valid name for the VM. + if !isWSL { + value = strings.ReplaceAll(value, "127.0.0.1", etchosts.HostContainersInternal) + value = strings.ReplaceAll(value, "localhost", etchosts.HostContainersInternal) + } + // %q to quote the value correctly + envs = append(envs, fmt.Sprintf("%q", key+"="+value)) + } + } + + script := fmt.Sprintf(proxySetupScriptTemplate, strings.Join(envs, " ")) + logrus.Tracef("Final environment variable setup script: %s", script) + return strings.NewReader(script) +} + +func ApplyProxies(mc *vmconfigs.MachineConfig) error { + return machine.CommonSSHWithStdin("root", mc.SSH.IdentityPath, mc.Name, mc.SSH.Port, []string{"/usr/bin/bash"}, + getProxyScript(mc.WSLHypervisor != nil)) +} diff --git a/pkg/machine/qemu/command/command.go b/pkg/machine/qemu/command/command.go index b795d73b41..6d25b19c59 100644 --- a/pkg/machine/qemu/command/command.go +++ b/pkg/machine/qemu/command/command.go @@ -107,11 +107,6 @@ func (q *QemuCmd) SetDisplay(display string) { *q = append(*q, "-display", display) } -// SetPropagatedHostEnvs adds options that propagate SSL and proxy settings -func (q *QemuCmd) SetPropagatedHostEnvs() { - *q = PropagateHostEnv(*q) -} - func (q *QemuCmd) Build() []string { return *q } diff --git a/pkg/machine/qemu/command/command_test.go b/pkg/machine/qemu/command/command_test.go deleted file mode 100644 index 9967d850db..0000000000 --- a/pkg/machine/qemu/command/command_test.go +++ /dev/null @@ -1,96 +0,0 @@ -//go:build !darwin - -package command - -import ( - "encoding/base64" - "fmt" - "strings" - "testing" - - "github.com/containers/common/libnetwork/etchosts" - "github.com/containers/podman/v5/pkg/machine/define" - "github.com/stretchr/testify/assert" -) - -func TestPropagateHostEnv(t *testing.T) { - tests := map[string]struct { - value string - expect string - }{ - "HTTP_PROXY": { - "proxy", - "equal", - }, - "ftp_proxy": { - "domain.com:8888", - "equal", - }, - "FTP_PROXY": { - "proxy", - "equal", - }, - "NO_PROXY": { - "localaddress", - "equal", - }, - "HTTPS_PROXY": { - "", - "unset", - }, - "no_proxy": { - "", - "unset", - }, - "http_proxy": { - "127.0.0.1:8888", - fmt.Sprintf("%s:8888", etchosts.HostContainersInternal), - }, - "https_proxy": { - "localhost:8888", - fmt.Sprintf("%s:8888", etchosts.HostContainersInternal), - }, - "SSL_CERT_FILE": { - "/some/f=oo.cert", - fmt.Sprintf("%s/f=oo.cert", define.UserCertsTargetPath), - }, - "SSL_CERT_DIR": { - "/some/my/certs", - define.UserCertsTargetPath, - }, - } - - for key, item := range tests { - t.Setenv(key, item.value) - } - - cmdLine := PropagateHostEnv(make([]string, 0)) - - assert.Len(t, cmdLine, 2) - assert.Equal(t, "-fw_cfg", cmdLine[0]) - tokens := strings.Split(cmdLine[1], ",string=") - decodeString, err := base64.StdEncoding.DecodeString(tokens[1]) - assert.NoError(t, err) - - // envsRawArr looks like: ["BAR=\"bar\"", "FOO=\"foo\""] - envsRawArr := strings.Split(string(decodeString), "|") - // envs looks like: {"BAR": "bar", "FOO": "foo"} - envs := make(map[string]string) - for _, env := range envsRawArr { - key, value, _ := strings.Cut(env, "=") - envs[key] = strings.Trim(value, "\"") - } - - for key, test := range tests { - switch test.expect { - case "equal": - assert.Equal(t, envs[key], test.value) - case "unset": - if _, ok := envs[key]; ok { - t.Errorf("env %s should not be set", key) - } - default: - assert.Equal(t, envs[key], test.expect) - } - } -} diff --git a/pkg/machine/qemu/command/helpers.go b/pkg/machine/qemu/command/helpers.go deleted file mode 100644 index c763770b9b..0000000000 --- a/pkg/machine/qemu/command/helpers.go +++ /dev/null @@ -1,60 +0,0 @@ -//go:build !darwin - -package command - -import ( - "encoding/base64" - "fmt" - "os" - "path/filepath" - "strings" - - "github.com/containers/common/libnetwork/etchosts" - "github.com/containers/common/pkg/config" - "github.com/containers/podman/v5/pkg/machine/define" -) - -func GetProxyVariables() map[string]string { - proxyOpts := make(map[string]string) - for _, variable := range config.ProxyEnv { - if value, ok := os.LookupEnv(variable); ok { - if value == "" { - continue - } - - v := strings.ReplaceAll(value, "127.0.0.1", etchosts.HostContainersInternal) - v = strings.ReplaceAll(v, "localhost", etchosts.HostContainersInternal) - proxyOpts[variable] = v - } - } - return proxyOpts -} - -// PropagateHostEnv is here for providing the ability to propagate -// proxy and SSL settings (e.g. HTTP_PROXY and others) on a start -// and avoid a need of re-creating/re-initiating a VM -func PropagateHostEnv(cmdLine QemuCmd) QemuCmd { - varsToPropagate := make([]string, 0) - - for k, v := range GetProxyVariables() { - varsToPropagate = append(varsToPropagate, fmt.Sprintf("%s=%q", k, v)) - } - - if sslCertFile, ok := os.LookupEnv("SSL_CERT_FILE"); ok { - pathInVM := filepath.Join(define.UserCertsTargetPath, filepath.Base(sslCertFile)) - varsToPropagate = append(varsToPropagate, fmt.Sprintf("%s=%q", "SSL_CERT_FILE", pathInVM)) - } - - if _, ok := os.LookupEnv("SSL_CERT_DIR"); ok { - varsToPropagate = append(varsToPropagate, fmt.Sprintf("%s=%q", "SSL_CERT_DIR", define.UserCertsTargetPath)) - } - - if len(varsToPropagate) > 0 { - prefix := "name=opt/com.coreos/environment,string=" - envVarsJoined := strings.Join(varsToPropagate, "|") - fwCfgArg := prefix + base64.StdEncoding.EncodeToString([]byte(envVarsJoined)) - return append(cmdLine, "-fw_cfg", fwCfgArg) - } - - return cmdLine -} diff --git a/pkg/machine/qemu/stubber.go b/pkg/machine/qemu/stubber.go index bcb8803e59..3f5d340d11 100644 --- a/pkg/machine/qemu/stubber.go +++ b/pkg/machine/qemu/stubber.go @@ -170,8 +170,6 @@ func (q *QEMUStubber) StartVM(mc *vmconfigs.MachineConfig) (func() error, func() cmdLine := q.Command - cmdLine.SetPropagatedHostEnvs() - // Disable graphic window when not in debug mode // Done in start, so we're not suck with the debug level we used on init if !logrus.IsLevelEnabled(logrus.DebugLevel) { diff --git a/pkg/machine/shim/host.go b/pkg/machine/shim/host.go index 03a979af2d..6d94ad6f65 100644 --- a/pkg/machine/shim/host.go +++ b/pkg/machine/shim/host.go @@ -12,6 +12,7 @@ import ( "github.com/containers/podman/v5/pkg/machine/connection" machineDefine "github.com/containers/podman/v5/pkg/machine/define" "github.com/containers/podman/v5/pkg/machine/ignition" + "github.com/containers/podman/v5/pkg/machine/proxyenv" "github.com/containers/podman/v5/pkg/machine/vmconfigs" "github.com/containers/podman/v5/utils" "github.com/hashicorp/go-multierror" @@ -414,6 +415,10 @@ func Start(mc *vmconfigs.MachineConfig, mp vmconfigs.VMProvider, _ *machineDefin return errors.New(msg) } + if err := proxyenv.ApplyProxies(mc); err != nil { + return err + } + // mount the volumes to the VM if err := mp.MountVolumesToVM(mc, opts.Quiet); err != nil { return err diff --git a/pkg/machine/ssh.go b/pkg/machine/ssh.go index 7a66984cf2..de5fd9aee8 100644 --- a/pkg/machine/ssh.go +++ b/pkg/machine/ssh.go @@ -2,6 +2,8 @@ package machine import ( "fmt" + "io" + "os" "os/exec" "strconv" @@ -12,14 +14,18 @@ import ( // and a port // TODO This should probably be taught about an machineconfig to reduce input func CommonSSH(username, identityPath, name string, sshPort int, inputArgs []string) error { - return commonSSH(username, identityPath, name, sshPort, inputArgs, false) + return commonSSH(username, identityPath, name, sshPort, inputArgs, false, os.Stdin) } func CommonSSHSilent(username, identityPath, name string, sshPort int, inputArgs []string) error { - return commonSSH(username, identityPath, name, sshPort, inputArgs, true) + return commonSSH(username, identityPath, name, sshPort, inputArgs, true, os.Stdin) } -func commonSSH(username, identityPath, name string, sshPort int, inputArgs []string, silent bool) error { +func CommonSSHWithStdin(username, identityPath, name string, sshPort int, inputArgs []string, stdin io.Reader) error { + return commonSSH(username, identityPath, name, sshPort, inputArgs, false, stdin) +} + +func commonSSH(username, identityPath, name string, sshPort int, inputArgs []string, silent bool, stdin io.Reader) error { sshDestination := username + "@localhost" port := strconv.Itoa(sshPort) interactive := true @@ -40,7 +46,7 @@ func commonSSH(username, identityPath, name string, sshPort int, inputArgs []str logrus.Debugf("Executing: ssh %v\n", args) if !silent { - if err := setupIOPassthrough(cmd, interactive); err != nil { + if err := setupIOPassthrough(cmd, interactive, stdin); err != nil { return err } } diff --git a/pkg/machine/ssh_unix.go b/pkg/machine/ssh_unix.go index 17e5acd06f..620969814d 100644 --- a/pkg/machine/ssh_unix.go +++ b/pkg/machine/ssh_unix.go @@ -3,12 +3,13 @@ package machine import ( + "io" "os" "os/exec" ) -func setupIOPassthrough(cmd *exec.Cmd, interactive bool) error { - cmd.Stdin = os.Stdin +func setupIOPassthrough(cmd *exec.Cmd, interactive bool, stdin io.Reader) error { + cmd.Stdin = stdin cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr diff --git a/pkg/machine/ssh_windows.go b/pkg/machine/ssh_windows.go index 3440dc1687..cf44023ff1 100644 --- a/pkg/machine/ssh_windows.go +++ b/pkg/machine/ssh_windows.go @@ -8,8 +8,8 @@ import ( "github.com/sirupsen/logrus" ) -func setupIOPassthrough(cmd *exec.Cmd, interactive bool) error { - cmd.Stdin = os.Stdin +func setupIOPassthrough(cmd *exec.Cmd, interactive bool, stdin io.Reader) error { + cmd.Stdin = stdin if interactive { cmd.Stdout = os.Stdout diff --git a/pkg/machine/wsl/declares.go b/pkg/machine/wsl/declares.go index fe0061218e..a1f13ae310 100644 --- a/pkg/machine/wsl/declares.go +++ b/pkg/machine/wsl/declares.go @@ -175,43 +175,6 @@ SocketMode=0660 SocketGroup=wheel ` -const proxyConfigSetup = `#!/bin/bash - -SYSTEMD_CONF=/etc/systemd/system.conf.d/default-env.conf -ENVD_CONF=/etc/environment.d/default-env.conf -PROFILE_CONF=/etc/profile.d/default-env.sh - -IFS="|" -read proxies - -mkdir -p /etc/profile.d /etc/environment.d /etc/systemd/system.conf.d/ -rm -f $SYSTEMD_CONF -for proxy in $proxies; do - output+="$proxy " -done -echo "[Manager]" >> $SYSTEMD_CONF -echo -ne "DefaultEnvironment=" >> $SYSTEMD_CONF - -echo $output >> $SYSTEMD_CONF -rm -f $ENVD_CONF -for proxy in $proxies; do - echo "$proxy" >> $ENVD_CONF -done -rm -f $PROFILE_CONF -for proxy in $proxies; do - echo "export $proxy" >> $PROFILE_CONF -done -` - -const proxyConfigAttempt = `if [ -f /usr/local/bin/proxyinit ]; \ -then /usr/local/bin/proxyinit; \ -else exit 42; \ -fi` - -const clearProxySettings = `rm -f /etc/systemd/system.conf.d/default-env.conf \ - /etc/environment.d/default-env.conf \ - /etc/profile.d/default-env.sh` - const wslInstallError = `Could not %s. See previous output for any potential failure details. If you can not resolve the issue, and rerunning fails, try the "wsl --install" process outlined in the following article: diff --git a/pkg/machine/wsl/machine.go b/pkg/machine/wsl/machine.go index f869bc8b65..26f16a66ec 100644 --- a/pkg/machine/wsl/machine.go +++ b/pkg/machine/wsl/machine.go @@ -244,41 +244,6 @@ func setupPodmanDockerSock(dist string, rootful bool) error { return nil } -func configureProxy(dist string, useProxy bool, quiet bool) error { - if !useProxy { - _ = wslInvoke(dist, "sh", "-c", clearProxySettings) - return nil - } - var content string - for i, key := range config.ProxyEnv { - if value, _ := os.LookupEnv(key); len(value) > 0 { - var suffix string - if i < (len(config.ProxyEnv) - 1) { - suffix = "|" - } - content = fmt.Sprintf("%s%s=\"%s\"%s", content, key, value, suffix) - } - } - - if err := wslPipe(content, dist, "sh", "-c", proxyConfigAttempt); err != nil { - const failMessage = "Failure creating proxy configuration" - if exitErr, isExit := err.(*exec.ExitError); isExit && exitErr.ExitCode() != 42 { - return fmt.Errorf("%v: %w", failMessage, err) - } - if !quiet { - fmt.Println("Installing proxy support") - } - _ = wslPipe(proxyConfigSetup, dist, "sh", "-c", - "cat > /usr/local/bin/proxyinit; chmod 755 /usr/local/bin/proxyinit") - - if err = wslPipe(content, dist, "/usr/local/bin/proxyinit"); err != nil { - return fmt.Errorf("%v: %w", failMessage, err) - } - } - - return nil -} - func enableUserLinger(mc *vmconfigs.MachineConfig, dist string) error { lingerCmd := "mkdir -p /var/lib/systemd/linger; touch /var/lib/systemd/linger/" + mc.SSH.RemoteUsername if err := wslInvoke(dist, "sh", "-c", lingerCmd); err != nil { @@ -317,11 +282,6 @@ func installScripts(dist string) error { return fmt.Errorf("could not create bootstrap script for guest OS: %w", err) } - if err := wslPipe(proxyConfigSetup, dist, "sh", "-c", - "cat > /usr/local/bin/proxyinit; chmod 755 /usr/local/bin/proxyinit"); err != nil { - return fmt.Errorf("could not create proxyinit script for guest OS: %w", err) - } - return nil } diff --git a/pkg/machine/wsl/stubber.go b/pkg/machine/wsl/stubber.go index fb58b3ca6a..e1d6b483d3 100644 --- a/pkg/machine/wsl/stubber.go +++ b/pkg/machine/wsl/stubber.go @@ -204,14 +204,8 @@ func (w WSLStubber) PostStartNetworking(mc *vmconfigs.MachineConfig, noInfo bool } func (w WSLStubber) StartVM(mc *vmconfigs.MachineConfig) (func() error, func() error, error) { - useProxy := setupWslProxyEnv() dist := machine.ToDist(mc.Name) - // TODO Quiet is hard set to false: follow up - if err := configureProxy(dist, useProxy, false); err != nil { - return nil, nil, err - } - // TODO The original code checked to see if the SSH port was actually open and re-assigned if it was // we could consider this but it should be higher up the stack // if !machine.IsLocalPortAvailable(v.Port) {