Skip to content

Commit 2128236

Browse files
esendjermheon
authored andcommitted
ignition: propagate proxy settings from a host into a vm
Set proxy settings (such as `HTTP_PROXY`, and others) for the whole guest OS with setting up `DefaultEnvironment` with a `systemd` configuration file `default-env.conf`, a `profile.d` scenario file - `default-env.sh` and a `environment.d` configuration file `default-env.conf` The **actual** environment variables are read by podman at a start, then they are encrypted with base64 into a single string and after are provided into a VM through QEMU Firmware Configuration (fw_cfg) Device Inside a VM a systemd service `envset-fwcfg.service` reads the providead encrypted string from fw_cfg, decrypts and then adds to the files - `/etc/systemd/system.conf.d/default-env.conf` - `/etc/profile.d/default-env.sh` - `/etc/environment.d/default-env.conf` At the end this service execute `systemctl daemon-reload` to propagate new variables for systemd manager [NO NEW TESTS NEEDED] Closes #13168 Signed-off-by: esendjer <[email protected]>
1 parent 809da6b commit 2128236

File tree

2 files changed

+79
-22
lines changed

2 files changed

+79
-22
lines changed

pkg/machine/ignition.go

+63-22
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,42 @@ ExecStartPost=/bin/touch /var/lib/%N.stamp
145145
146146
[Install]
147147
WantedBy=default.target
148-
`
148+
`
149+
// This service gets environment variables that are provided
150+
// through qemu fw_cfg and then sets them into systemd/system.conf.d,
151+
// profile.d and environment.d files
152+
//
153+
// Currently, it is used for propagating
154+
// proxy settings e.g. HTTP_PROXY and others, on a start avoiding
155+
// a need of re-creating/re-initiating a VM
156+
envset := `[Unit]
157+
Description=Environment setter from QEMU FW_CFG
158+
[Service]
159+
Type=oneshot
160+
RemainAfterExit=yes
161+
Environment=FWCFGRAW=/sys/firmware/qemu_fw_cfg/by_name/opt/com.coreos/environment/raw
162+
Environment=SYSTEMD_CONF=/etc/systemd/system.conf.d/default-env.conf
163+
Environment=ENVD_CONF=/etc/environment.d/default-env.conf
164+
Environment=PROFILE_CONF=/etc/profile.d/default-env.sh
165+
ExecStart=/usr/bin/bash -c '/usr/bin/test -f ${FWCFGRAW} &&\
166+
echo "[Manager]\n#Got from QEMU FW_CFG\nDefaultEnvironment=$(/usr/bin/base64 -d ${FWCFGRAW} | sed -e "s+|+ +g")\n" > ${SYSTEMD_CONF} ||\
167+
echo "[Manager]\n#Got nothing from QEMU FW_CFG\n#DefaultEnvironment=\n" > ${SYSTEMD_CONF}'
168+
ExecStart=/usr/bin/bash -c '/usr/bin/test -f ${FWCFGRAW} && (\
169+
echo "#Got from QEMU FW_CFG"> ${ENVD_CONF};\
170+
IFS="|";\
171+
for iprxy in $(/usr/bin/base64 -d ${FWCFGRAW}); do\
172+
echo "$iprxy" >> ${ENVD_CONF}; done ) || \
173+
echo "#Got nothing from QEMU FW_CFG"> ${ENVD_CONF}'
174+
ExecStart=/usr/bin/bash -c '/usr/bin/test -f ${FWCFGRAW} && (\
175+
echo "#Got from QEMU FW_CFG"> ${PROFILE_CONF};\
176+
IFS="|";\
177+
for iprxy in $(/usr/bin/base64 -d ${FWCFGRAW}); do\
178+
echo "export $iprxy" >> ${PROFILE_CONF}; done ) || \
179+
echo "#Got nothing from QEMU FW_CFG"> ${PROFILE_CONF}'
180+
ExecStartPost=/usr/bin/systemctl daemon-reload
181+
[Install]
182+
WantedBy=sysinit.target
183+
`
149184
_ = ready
150185
ignSystemd := Systemd{
151186
Units: []Unit{
@@ -173,6 +208,11 @@ WantedBy=default.target
173208
Name: "remove-moby.service",
174209
Contents: &deMoby,
175210
},
211+
{
212+
Enabled: boolToPtr(true),
213+
Name: "envset-fwcfg.service",
214+
Contents: &envset,
215+
},
176216
}}
177217
ignConfig := Config{
178218
Ignition: ignVersion,
@@ -226,6 +266,25 @@ func getDirs(usrName string) []Directory {
226266
DirectoryEmbedded1: DirectoryEmbedded1{Mode: intToPtr(0755)},
227267
})
228268

269+
// The directory is used by envset-fwcfg.service
270+
// for propagating environment variables that got
271+
// from a host
272+
dirs = append(dirs, Directory{
273+
Node: Node{
274+
Group: getNodeGrp("root"),
275+
Path: "/etc/systemd/system.conf.d",
276+
User: getNodeUsr("root"),
277+
},
278+
DirectoryEmbedded1: DirectoryEmbedded1{Mode: intToPtr(0755)},
279+
}, Directory{
280+
Node: Node{
281+
Group: getNodeGrp("root"),
282+
Path: "/etc/environment.d",
283+
User: getNodeUsr("root"),
284+
},
285+
DirectoryEmbedded1: DirectoryEmbedded1{Mode: intToPtr(0755)},
286+
})
287+
229288
return dirs
230289
}
231290

@@ -363,24 +422,6 @@ Delegate=memory pids cpu io
363422
},
364423
})
365424

366-
setProxyOpts := getProxyVariables()
367-
if setProxyOpts != "" {
368-
files = append(files, File{
369-
Node: Node{
370-
Group: getNodeGrp("root"),
371-
Path: "/etc/profile.d/proxy-opts.sh",
372-
User: getNodeUsr("root"),
373-
},
374-
FileEmbedded1: FileEmbedded1{
375-
Append: nil,
376-
Contents: Resource{
377-
Source: encodeDataURLPtr(setProxyOpts),
378-
},
379-
Mode: intToPtr(0644),
380-
},
381-
})
382-
}
383-
384425
setDockerHost := `export DOCKER_HOST="unix://$(podman info -f "{{.Host.RemoteSocket.Path}}")"
385426
`
386427

@@ -506,11 +547,11 @@ func prepareCertFile(path string, name string) (File, error) {
506547
return file, nil
507548
}
508549

509-
func getProxyVariables() string {
510-
proxyOpts := ""
550+
func GetProxyVariables() map[string]string {
551+
proxyOpts := make(map[string]string)
511552
for _, variable := range config.ProxyEnv {
512553
if value, ok := os.LookupEnv(variable); ok {
513-
proxyOpts += fmt.Sprintf("\n export %s=%s", variable, value)
554+
proxyOpts[variable] = value
514555
}
515556
}
516557
return proxyOpts

pkg/machine/qemu/machine.go

+16
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
//go:build (amd64 && !windows) || (arm64 && !windows)
12
// +build amd64,!windows arm64,!windows
23

34
package qemu
45

56
import (
67
"bufio"
8+
"encoding/base64"
79
"encoding/json"
810
"fmt"
911
"io/ioutil"
@@ -123,6 +125,20 @@ func (p *Provider) LoadVMByName(name string) (machine.VM, error) {
123125
return nil, err
124126
}
125127
err = json.Unmarshal(b, vm)
128+
129+
// It is here for providing the ability to propagate
130+
// proxy settings (e.g. HTTP_PROXY and others) on a start
131+
// and avoid a need of re-creating/re-initiating a VM
132+
if proxyOpts := machine.GetProxyVariables(); len(proxyOpts) > 0 {
133+
proxyStr := "name=opt/com.coreos/environment,string="
134+
var proxies string
135+
for k, v := range proxyOpts {
136+
proxies = fmt.Sprintf("%s%s=\"%s\"|", proxies, k, v)
137+
}
138+
proxyStr = fmt.Sprintf("%s%s", proxyStr, base64.StdEncoding.EncodeToString([]byte(proxies)))
139+
vm.CmdLine = append(vm.CmdLine, "-fw_cfg", proxyStr)
140+
}
141+
126142
logrus.Debug(vm.CmdLine)
127143
return vm, err
128144
}

0 commit comments

Comments
 (0)