From 34a98fd360aebc1fcba2580efc67d5802747c1f5 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. Maybe fixes #16413. Signed-off-by: Björn Mosler --- pkg/machine/ignition.go | 41 +++++++++++++--------------- pkg/machine/qemu/machine.go | 47 +++++++++++++++++++++++--------- pkg/machine/qemu/machine_test.go | 20 ++++++++++++++ 3 files changed, 73 insertions(+), 35 deletions(-) diff --git a/pkg/machine/ignition.go b/pkg/machine/ignition.go index 39ddce14cdad..2f2586c40dcd 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,13 @@ Delegate=memory pids cpu io if _, err := os.Stat(sslCertFile); err == nil { certFiles = getCerts(sslCertFile, false) files = append(files, certFiles...) + } + } - 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...) } } @@ -564,7 +557,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) @@ -586,13 +579,17 @@ func prepareCertFile(path string, name string) (File, error) { } func GetProxyVariables() map[string]string { - proxyOpts := make(map[string]string) - for _, variable := range config.ProxyEnv { + return ReadEnvVars(config.ProxyEnv) +} + +func ReadEnvVars(variableNames []string) map[string]string { + envVars := make(map[string]string) + for _, variable := range variableNames { if value, ok := os.LookupEnv(variable); ok { - proxyOpts[variable] = value + envVars[variable] = value } } - return proxyOpts + return envVars } func getLinks(usrName string) []Link { diff --git a/pkg/machine/qemu/machine.go b/pkg/machine/qemu/machine.go index 8fc2ad0e0f5b..2f706f663de3 100644 --- a/pkg/machine/qemu/machine.go +++ b/pkg/machine/qemu/machine.go @@ -37,7 +37,13 @@ import ( var ( qemuProvider = &Provider{} // vmtype refers to qemu (vs libvirt, krun, etc). - vmtype = "qemu" + vmtype = "qemu" + sslEnvVars = []string{ + // TODO move to github.com/containers/common/pkg/config/config.go like ProxyEnv? + // TODO how about lower case options? + "SSL_CERT_FILE", + "SSL_CERT_DIR", + } ) func GetVirtualizationProvider() machine.Provider { @@ -560,18 +566,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 +691,32 @@ 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)) + } + + for k, v := range machine.ReadEnvVars(sslEnvVars) { + pathInVM := filepath.Join(machine.UserCertsTargetPath, filepath.Base(v)) // take into account where certs are copied during ignition + varsToPropagate = append(varsToPropagate, fmt.Sprintf("%s=%q", k, pathInVM)) + fmt.Println(varsToPropagate) + } + + 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 4c393d0f42db..c2162bef00fa 100644 --- a/pkg/machine/qemu/machine_test.go +++ b/pkg/machine/qemu/machine_test.go @@ -4,8 +4,15 @@ 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 +25,16 @@ 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("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, _ := base64.StdEncoding.DecodeString(tokens[1]) + assert.Equal(t, fmt.Sprintf("HTTP_PROXY=\"proxy\"|SSL_CERT_FILE=\"%s/foo.cert\"", machine.UserCertsTargetPath), string(decodeString)) +}