From caa2dfe01b2c2439b34b1451bdc71ad5a2e56597 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Mosler?= Date: Wed, 9 Nov 2022 17:29:32 +0100 Subject: [PATCH] podman machine: Propagate SSL_CERT_FILE and SSL_CERT_DIR to systemd environment. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #16041. Signed-off-by: Björn Mosler --- pkg/machine/ignition.go | 33 ++++++++++++------------- pkg/machine/qemu/machine.go | 42 +++++++++++++++++++++++--------- pkg/machine/qemu/machine_test.go | 20 +++++++++++++++ 3 files changed, 65 insertions(+), 30 deletions(-) diff --git a/pkg/machine/ignition.go b/pkg/machine/ignition.go index 39ddce14cd..d317ad1fb0 100644 --- a/pkg/machine/ignition.go +++ b/pkg/machine/ignition.go @@ -24,6 +24,10 @@ import ( https://github.com/openshift/machine-config-operator/blob/master/pkg/server/server.go */ +const ( + UserCertsTargetPath = "/etc/containers/certs.d" +) + // Convenience function to convert int to ptr func intToPtr(i int) *int { return &i @@ -495,24 +499,17 @@ Delegate=memory pids cpu io if _, err := os.Stat(sslCertFile); err == nil { certFiles = getCerts(sslCertFile, false) files = append(files, certFiles...) + } else { + logrus.Warnf("Invalid path in SSL_CERT_FILE: %q", err) + } + } - if len(certFiles) > 0 { - setSSLCertFile := fmt.Sprintf("export %s=%s", "SSL_CERT_FILE", filepath.Join("/etc/containers/certs.d", filepath.Base(sslCertFile))) - files = append(files, File{ - Node: Node{ - Group: getNodeGrp("root"), - Path: "/etc/profile.d/ssl_cert_file.sh", - User: getNodeUsr("root"), - }, - FileEmbedded1: FileEmbedded1{ - Append: nil, - Contents: Resource{ - Source: encodeDataURLPtr(setSSLCertFile), - }, - Mode: intToPtr(0644), - }, - }) - } + if sslCertDir, ok := os.LookupEnv("SSL_CERT_DIR"); ok { + if _, err := os.Stat(sslCertDir); err == nil { + certFiles = getCerts(sslCertDir, true) + files = append(files, certFiles...) + } else { + logrus.Warnf("Invalid path in SSL_CERT_DIR: %q", err) } } @@ -564,7 +561,7 @@ func prepareCertFile(path string, name string) (File, error) { return File{}, err } - targetPath := filepath.Join("/etc/containers/certs.d", name) + targetPath := filepath.Join(UserCertsTargetPath, name) logrus.Debugf("Copying cert file from '%s' to '%s'.", path, targetPath) diff --git a/pkg/machine/qemu/machine.go b/pkg/machine/qemu/machine.go index 8fc2ad0e0f..4b7522b318 100644 --- a/pkg/machine/qemu/machine.go +++ b/pkg/machine/qemu/machine.go @@ -560,18 +560,7 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error { attr.Files = files cmdLine := v.CmdLine - // It is here for providing the ability to propagate - // proxy settings (e.g. HTTP_PROXY and others) on a start - // and avoid a need of re-creating/re-initiating a VM - if proxyOpts := machine.GetProxyVariables(); len(proxyOpts) > 0 { - proxyStr := "name=opt/com.coreos/environment,string=" - var proxies string - for k, v := range proxyOpts { - proxies = fmt.Sprintf("%s%s=\"%s\"|", proxies, k, v) - } - proxyStr = fmt.Sprintf("%s%s", proxyStr, base64.StdEncoding.EncodeToString([]byte(proxies))) - cmdLine = append(cmdLine, "-fw_cfg", proxyStr) - } + cmdLine = propagateHostEnv(cmdLine) // Disable graphic window when not in debug mode // Done in start, so we're not suck with the debug level we used on init @@ -696,6 +685,35 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error { return nil } +// 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 []string) []string { + varsToPropagate := make([]string, 0) + + for k, v := range machine.GetProxyVariables() { + varsToPropagate = append(varsToPropagate, fmt.Sprintf("%s=%q", k, v)) + } + + if sslCertFile, ok := os.LookupEnv("SSL_CERT_FILE"); ok { + pathInVM := filepath.Join(machine.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", machine.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 +} + func (v *MachineVM) checkStatus(monitor *qmp.SocketMonitor) (machine.Status, error) { // this is the format returned from the monitor // {"return": {"status": "running", "singlestep": false, "running": true}} diff --git a/pkg/machine/qemu/machine_test.go b/pkg/machine/qemu/machine_test.go index 4c393d0f42..e188fe98a2 100644 --- a/pkg/machine/qemu/machine_test.go +++ b/pkg/machine/qemu/machine_test.go @@ -4,8 +4,13 @@ package qemu import ( + "encoding/base64" + "fmt" + "strings" "testing" + "github.com/containers/podman/v4/pkg/machine" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -18,3 +23,18 @@ func TestEditCmd(t *testing.T) { require.Equal(t, vm.CmdLine, []string{"command", "-flag", "newvalue", "-anotherflag", "anothervalue"}) } + +func TestPropagateHostEnv(t *testing.T) { + t.Setenv("SSL_CERT_FILE", "/some/foo.cert") + t.Setenv("SSL_CERT_DIR", "/some/my/certs") + t.Setenv("HTTP_PROXY", "proxy") + + 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) + assert.Equal(t, fmt.Sprintf("HTTP_PROXY=\"proxy\"|SSL_CERT_FILE=\"%s/foo.cert\"|SSL_CERT_DIR=%q", machine.UserCertsTargetPath, machine.UserCertsTargetPath), string(decodeString)) +}