Skip to content

Commit 1729fb4

Browse files
authored
Merge pull request lima-vm#362 from rancher-sandbox/etc-environment
Write /etc/environment before the lingering session is started
2 parents 2a61833 + ab9ff6c commit 1729fb4

File tree

7 files changed

+101
-14
lines changed

7 files changed

+101
-14
lines changed

hack/test-example.sh

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ function diagnose() {
9292
set +x -e
9393
}
9494

95+
export ftp_proxy=http://localhost:2121
96+
9597
INFO "Starting \"$NAME\" from \"$FILE\""
9698
defer "limactl delete -f \"$NAME\""
9799
set -x
@@ -106,6 +108,17 @@ limactl shell "$NAME" uname -a
106108
limactl shell "$NAME" cat /etc/os-release
107109
set +x
108110

111+
INFO "Testing proxy settings are imported"
112+
got=$(limactl shell "$NAME" env | grep FTP_PROXY)
113+
# Expected: FTP_PROXY is set in addition to ftp_proxy, localhost is replaced
114+
# by the gateway address, and the value is set immediately without a restart
115+
expected="FTP_PROXY=http://192.168.5.2:2121"
116+
INFO "FTP_PROXY: expected=${expected} got=${got}"
117+
if [ "$got" != "$expected" ]; then
118+
ERROR "proxy environment variable not set to correct value"
119+
exit 1
120+
fi
121+
109122
INFO "Testing limactl copy command"
110123
tmpfile="$HOME/lima-hostname"
111124
rm -f "$tmpfile"
@@ -212,9 +225,19 @@ if [[ -n ${CHECKS["restart"]} ]]; then
212225
limactl stop "$NAME"
213226
sleep 3
214227

228+
export ftp_proxy=my.proxy:8021
215229
INFO "Restarting \"$NAME\""
216230
limactl start "$NAME"
217231

232+
INFO "Make sure proxy setting is updated"
233+
got=$(limactl shell "$NAME" env | grep FTP_PROXY)
234+
expected="FTP_PROXY=my.proxy:8021"
235+
INFO "FTP_PROXY: expected=${expected} got=${got}"
236+
if [ "$got" != "$expected" ]; then
237+
ERROR "proxy environment variable not set to correct value"
238+
exit 1
239+
fi
240+
218241
# shellcheck disable=SC2016
219242
if ! limactl shell "$NAME" sh -c 'test -f $HOME/sweet-home'; then
220243
ERROR "Guest home directory does not persist across restarts"

pkg/cidata/cidata.TEMPLATE.d/boot.sh

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ done <"${LIMA_CIDATA_MNT}"/etc_environment
1919

2020
CODE=0
2121

22-
# Don't make any changes to /etc or /var/lib until the boot/* scripts have run
23-
# because they might move the directories to /mnt/data on first boot, so changes
24-
# made on restart would be lost.
22+
# Don't make any changes to /etc or /var/lib until boot/05-persistent-data-volume.sh
23+
# has run because it might move the directories to /mnt/data on first boot. In that
24+
# case changes made on restart would be lost.
2525

2626
for f in "${LIMA_CIDATA_MNT}"/boot/*; do
2727
INFO "Executing $f"
@@ -31,11 +31,6 @@ for f in "${LIMA_CIDATA_MNT}"/boot/*; do
3131
fi
3232
done
3333

34-
if [ -e /etc/environment ]; then
35-
sed -i '/#LIMA-START/,/#LIMA-END/d' /etc/environment
36-
fi
37-
cat "${LIMA_CIDATA_MNT}/etc_environment" >>/etc/environment
38-
3934
if [ -d "${LIMA_CIDATA_MNT}"/provision.system ]; then
4035
for f in "${LIMA_CIDATA_MNT}"/provision.system/*; do
4136
INFO "Executing $f"
@@ -64,5 +59,9 @@ if [ -d "${LIMA_CIDATA_MNT}"/provision.user ]; then
6459
done
6560
fi
6661

62+
# Signal that provisioning is done. The instance-id in the meta-data file changes on every boot,
63+
# so any copy from a previous boot cycle will have different content.
64+
cp "${LIMA_CIDATA_MNT}"/meta-data /run/lima-boot-done
65+
6766
INFO "Exiting with code $CODE"
6867
exit "$CODE"
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/bin/sh
2+
set -eux
3+
4+
# /etc/environment must be written after 05-persistent-data-volume.sh has run to
5+
# make sure the changes on a restart are applied to the persisted version.
6+
7+
if [ -e /etc/environment ]; then
8+
sed -i '/#LIMA-START/,/#LIMA-END/d' /etc/environment
9+
fi
10+
cat "${LIMA_CIDATA_MNT}/etc_environment" >>/etc/environment
11+
12+
# It is possible that a requirements script has started an ssh session before
13+
# /etc/environment was updated, so we need to kill it to make sure it will
14+
# restart with the updated environment before "linger" is being enabled.
15+
16+
if command -v loginctl >/dev/null 2>&1; then
17+
loginctl terminate-user "${LIMA_CIDATA_USER}" || true
18+
fi
19+
20+
# Make sure the guestagent socket from a previous boot is removed before we open the "lima-ssh-ready" gate.
21+
rm -f /run/lima-guest-agent.sock
22+
23+
# Signal that provisioning is done. The instance-id in the meta-data file changes on every boot,
24+
# so any copy from a previous boot cycle will have different content.
25+
cp "${LIMA_CIDATA_MNT}"/meta-data /run/lima-ssh-ready

pkg/cidata/cidata.TEMPLATE.d/boot/30-install-packages.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ if [ -n "${LIMA_CIDATA_TCP_DNS_LOCAL_PORT}" ] && [ "${LIMA_CIDATA_TCP_DNS_LOCAL_
112112
fi
113113
if [ "${SETUP_DNS}" = 1 ]; then
114114
# Try to setup iptables rule again, in case we just installed iptables
115-
"${LIMA_CIDATA_MNT}/boot/07-host-dns-setup.sh"
115+
"${LIMA_CIDATA_MNT}/boot/09-host-dns-setup.sh"
116116
fi
117117

118118
# update_fuse_conf has to be called after installing all the packages,

pkg/hostagent/hostagent.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,9 @@ func (a *HostAgent) startHostAgentRoutines(ctx context.Context) error {
388388
if err := a.waitForRequirements(ctx, "optional", a.optionalRequirements()); err != nil {
389389
mErr = multierror.Append(mErr, err)
390390
}
391+
if err := a.waitForRequirements(ctx, "final", a.finalRequirements()); err != nil {
392+
mErr = multierror.Append(mErr, err)
393+
}
391394
return mErr
392395
}
393396

pkg/hostagent/requirements.go

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,16 +60,33 @@ type requirement struct {
6060

6161
func (a *HostAgent) essentialRequirements() []requirement {
6262
req := make([]requirement, 0)
63-
req = append(req, requirement{
64-
description: "ssh",
65-
script: `#!/bin/bash
63+
req = append(req,
64+
requirement{
65+
description: "ssh",
66+
script: `#!/bin/bash
6667
true
6768
`,
68-
debugHint: `Failed to SSH into the guest.
69+
debugHint: `Failed to SSH into the guest.
6970
Make sure that the YAML field "ssh.localPort" is not used by other processes on the host.
7071
If any private key under ~/.ssh is protected with a passphrase, you need to have ssh-agent to be running.
7172
`,
72-
})
73+
},
74+
requirement{
75+
description: "user session is ready for ssh",
76+
script: `#!/bin/bash
77+
set -eux -o pipefail
78+
if ! timeout 30s bash -c "until sudo diff -q /run/lima-ssh-ready /mnt/lima-cidata/meta-data 2>/dev/null; do sleep 3; done"; then
79+
echo >&2 "not ready to start persistent ssh session"
80+
exit 1
81+
fi
82+
`,
83+
debugHint: `The boot sequence will terminate any existing user session after updating
84+
/etc/environment to make sure the session includes the new values.
85+
Terminating the session will break the persistent SSH tunnel, so
86+
it must not be created until the session reset is done.
87+
`,
88+
})
89+
7390
if len(a.y.Mounts) > 0 {
7491
req = append(req, requirement{
7592
description: "sshfs binary to be installed",
@@ -164,3 +181,23 @@ Also see "/var/log/cloud-init-output.log" in the guest.
164181
}
165182
return req
166183
}
184+
185+
func (a *HostAgent) finalRequirements() []requirement {
186+
req := make([]requirement, 0)
187+
req = append(req,
188+
requirement{
189+
description: "boot scripts must have finished",
190+
script: `#!/bin/bash
191+
set -eux -o pipefail
192+
if ! timeout 30s bash -c "until sudo diff -q /run/lima-boot-done /mnt/lima-cidata/meta-data 2>/dev/null; do sleep 3; done"; then
193+
echo >&2 "boot scripts have not finished"
194+
exit 1
195+
fi
196+
`,
197+
debugHint: `All boot scripts, provisioning scripts, and readiness probes must
198+
finish before the instance is considered "ready".
199+
Check "/var/log/cloud-init-output.log" in the guest to see where the process is blocked!
200+
`,
201+
})
202+
return req
203+
}

0 commit comments

Comments
 (0)