Skip to content

Commit

Permalink
podman machine: Propagate SSL_CERT_FILE and SSL_CERT_DIR to systemd e…
Browse files Browse the repository at this point in the history
…nvironment.

Fixes containers#16041.
Maybe fixes containers#16413.

Signed-off-by: Björn Mosler <dev@bjoern.mosler.ch>
  • Loading branch information
Björn Mosler committed Nov 9, 2022
1 parent d720440 commit 34a98fd
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 35 deletions.
41 changes: 19 additions & 22 deletions pkg/machine/ignition.go
Expand Up @@ -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
Expand Down Expand Up @@ -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...)
}
}

Expand Down Expand Up @@ -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)

Expand All @@ -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 {
Expand Down
47 changes: 34 additions & 13 deletions pkg/machine/qemu/machine.go
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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}}
Expand Down
20 changes: 20 additions & 0 deletions pkg/machine/qemu/machine_test.go
Expand Up @@ -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"
)

Expand All @@ -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))
}

0 comments on commit 34a98fd

Please sign in to comment.