Skip to content

Commit

Permalink
Merge pull request #362 from rancher-sandbox/etc-environment
Browse files Browse the repository at this point in the history
Write /etc/environment before the lingering session is started
  • Loading branch information
AkihiroSuda authored Nov 4, 2021
2 parents 2a61833 + ab9ff6c commit 1729fb4
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 14 deletions.
23 changes: 23 additions & 0 deletions hack/test-example.sh
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ function diagnose() {
set +x -e
}

export ftp_proxy=http://localhost:2121

INFO "Starting \"$NAME\" from \"$FILE\""
defer "limactl delete -f \"$NAME\""
set -x
Expand All @@ -106,6 +108,17 @@ limactl shell "$NAME" uname -a
limactl shell "$NAME" cat /etc/os-release
set +x

INFO "Testing proxy settings are imported"
got=$(limactl shell "$NAME" env | grep FTP_PROXY)
# Expected: FTP_PROXY is set in addition to ftp_proxy, localhost is replaced
# by the gateway address, and the value is set immediately without a restart
expected="FTP_PROXY=http://192.168.5.2:2121"
INFO "FTP_PROXY: expected=${expected} got=${got}"
if [ "$got" != "$expected" ]; then
ERROR "proxy environment variable not set to correct value"
exit 1
fi

INFO "Testing limactl copy command"
tmpfile="$HOME/lima-hostname"
rm -f "$tmpfile"
Expand Down Expand Up @@ -212,9 +225,19 @@ if [[ -n ${CHECKS["restart"]} ]]; then
limactl stop "$NAME"
sleep 3

export ftp_proxy=my.proxy:8021
INFO "Restarting \"$NAME\""
limactl start "$NAME"

INFO "Make sure proxy setting is updated"
got=$(limactl shell "$NAME" env | grep FTP_PROXY)
expected="FTP_PROXY=my.proxy:8021"
INFO "FTP_PROXY: expected=${expected} got=${got}"
if [ "$got" != "$expected" ]; then
ERROR "proxy environment variable not set to correct value"
exit 1
fi

# shellcheck disable=SC2016
if ! limactl shell "$NAME" sh -c 'test -f $HOME/sweet-home'; then
ERROR "Guest home directory does not persist across restarts"
Expand Down
15 changes: 7 additions & 8 deletions pkg/cidata/cidata.TEMPLATE.d/boot.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ done <"${LIMA_CIDATA_MNT}"/etc_environment

CODE=0

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

for f in "${LIMA_CIDATA_MNT}"/boot/*; do
INFO "Executing $f"
Expand All @@ -31,11 +31,6 @@ for f in "${LIMA_CIDATA_MNT}"/boot/*; do
fi
done

if [ -e /etc/environment ]; then
sed -i '/#LIMA-START/,/#LIMA-END/d' /etc/environment
fi
cat "${LIMA_CIDATA_MNT}/etc_environment" >>/etc/environment

if [ -d "${LIMA_CIDATA_MNT}"/provision.system ]; then
for f in "${LIMA_CIDATA_MNT}"/provision.system/*; do
INFO "Executing $f"
Expand Down Expand Up @@ -64,5 +59,9 @@ if [ -d "${LIMA_CIDATA_MNT}"/provision.user ]; then
done
fi

# Signal that provisioning is done. The instance-id in the meta-data file changes on every boot,
# so any copy from a previous boot cycle will have different content.
cp "${LIMA_CIDATA_MNT}"/meta-data /run/lima-boot-done

INFO "Exiting with code $CODE"
exit "$CODE"
25 changes: 25 additions & 0 deletions pkg/cidata/cidata.TEMPLATE.d/boot/07-etc-environment.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/bin/sh
set -eux

# /etc/environment must be written after 05-persistent-data-volume.sh has run to
# make sure the changes on a restart are applied to the persisted version.

if [ -e /etc/environment ]; then
sed -i '/#LIMA-START/,/#LIMA-END/d' /etc/environment
fi
cat "${LIMA_CIDATA_MNT}/etc_environment" >>/etc/environment

# It is possible that a requirements script has started an ssh session before
# /etc/environment was updated, so we need to kill it to make sure it will
# restart with the updated environment before "linger" is being enabled.

if command -v loginctl >/dev/null 2>&1; then
loginctl terminate-user "${LIMA_CIDATA_USER}" || true
fi

# Make sure the guestagent socket from a previous boot is removed before we open the "lima-ssh-ready" gate.
rm -f /run/lima-guest-agent.sock

# Signal that provisioning is done. The instance-id in the meta-data file changes on every boot,
# so any copy from a previous boot cycle will have different content.
cp "${LIMA_CIDATA_MNT}"/meta-data /run/lima-ssh-ready
2 changes: 1 addition & 1 deletion pkg/cidata/cidata.TEMPLATE.d/boot/30-install-packages.sh
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ if [ -n "${LIMA_CIDATA_TCP_DNS_LOCAL_PORT}" ] && [ "${LIMA_CIDATA_TCP_DNS_LOCAL_
fi
if [ "${SETUP_DNS}" = 1 ]; then
# Try to setup iptables rule again, in case we just installed iptables
"${LIMA_CIDATA_MNT}/boot/07-host-dns-setup.sh"
"${LIMA_CIDATA_MNT}/boot/09-host-dns-setup.sh"
fi

# update_fuse_conf has to be called after installing all the packages,
Expand Down
3 changes: 3 additions & 0 deletions pkg/hostagent/hostagent.go
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,9 @@ func (a *HostAgent) startHostAgentRoutines(ctx context.Context) error {
if err := a.waitForRequirements(ctx, "optional", a.optionalRequirements()); err != nil {
mErr = multierror.Append(mErr, err)
}
if err := a.waitForRequirements(ctx, "final", a.finalRequirements()); err != nil {
mErr = multierror.Append(mErr, err)
}
return mErr
}

Expand Down
47 changes: 42 additions & 5 deletions pkg/hostagent/requirements.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,33 @@ type requirement struct {

func (a *HostAgent) essentialRequirements() []requirement {
req := make([]requirement, 0)
req = append(req, requirement{
description: "ssh",
script: `#!/bin/bash
req = append(req,
requirement{
description: "ssh",
script: `#!/bin/bash
true
`,
debugHint: `Failed to SSH into the guest.
debugHint: `Failed to SSH into the guest.
Make sure that the YAML field "ssh.localPort" is not used by other processes on the host.
If any private key under ~/.ssh is protected with a passphrase, you need to have ssh-agent to be running.
`,
})
},
requirement{
description: "user session is ready for ssh",
script: `#!/bin/bash
set -eux -o pipefail
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
echo >&2 "not ready to start persistent ssh session"
exit 1
fi
`,
debugHint: `The boot sequence will terminate any existing user session after updating
/etc/environment to make sure the session includes the new values.
Terminating the session will break the persistent SSH tunnel, so
it must not be created until the session reset is done.
`,
})

if len(a.y.Mounts) > 0 {
req = append(req, requirement{
description: "sshfs binary to be installed",
Expand Down Expand Up @@ -164,3 +181,23 @@ Also see "/var/log/cloud-init-output.log" in the guest.
}
return req
}

func (a *HostAgent) finalRequirements() []requirement {
req := make([]requirement, 0)
req = append(req,
requirement{
description: "boot scripts must have finished",
script: `#!/bin/bash
set -eux -o pipefail
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
echo >&2 "boot scripts have not finished"
exit 1
fi
`,
debugHint: `All boot scripts, provisioning scripts, and readiness probes must
finish before the instance is considered "ready".
Check "/var/log/cloud-init-output.log" in the guest to see where the process is blocked!
`,
})
return req
}

0 comments on commit 1729fb4

Please sign in to comment.