utils/vmbox/guest/shim.sh
Krzysztof kuhy Rudnicki 00bb6706fd
Some checks are pending
dependency freshness / dependencies on newest stable (push) Waiting to run
file length / file-length (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
palette drift / palette (push) Waiting to run
shared gate tests / gate unit tests (push) Waiting to run
vmbox: vm lightdm and vm shim — the host's login topology and fake hardware
The golden image logs in with agetty+startx and has no RGB controllers,
no NVIDIA card and no sound card, so the night-lockdown scripts — which
mask/stop lightdm.service and getty@.service and shell out to openrgb,
nvidia-smi and amixer — had nothing real to act on in a sandbox and
were being "verified" on the host instead.

- `vm lightdm <name>`: installs lightdm + lightdm-gtk-greeter into the
  live overlay (pacman -Syu, not -S: the overlay's package database is
  the image's and mirrors have rotated those versions out), configures
  autologin -> i3 exactly like the host, turns tty1 back into a plain
  getty, reboots the guest and proves lightdm.service is active with an
  Xorg it owns. Never rebuilds the base: `vm build --force` re-seals a
  new checksum while every existing sandbox still backs onto the old
  file's name, which is silent qcow2 corruption.
- `vm shim <name> <tool> [exit[:N]|hang|sleep:S]`: a fake tool ahead of
  the real one on PATH, every call logged with an epoch to
  /var/log/vmbox-shim/<tool>.log so the host can assert what ran and in
  what order. `hang` is the openrgb 1.0-2 that never returned on
  2026-09-12 and defeated the curfew.
- The DISPLAY/XAUTHORITY resolver `vm run` sources becomes its own file,
  guest/vmbox-x11.sh, installed by the image build and re-installed by
  the lightdm switch; it now tests readability, not existence, and tries
  ~/.Xauthority before the startx serverauth glob, because lightdm's
  Xorg -auth file is root-only.
- README: the worked example uses MIDNIGHT_SHUTDOWN_CONFIRM=y (the
  installer refuses to run unattended now; `echo y |` no longer works),
  and the "i2c RGB stays on the host" line is gone.
- bats: four host-side tests for shim.sh (exit, exit:N, hang, refusals).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015mLnUeoJ3mUwGRTowTUH6d
2026-09-13 10:51:10 +02:00

50 lines
1.9 KiB
Bash

#!/bin/bash
# ============================================================================
# Runs INSIDE a sandbox as root, via `vm shim <name> <tool> [mode]`.
#
# Install a fake <tool> ahead of the real one on PATH (/usr/local/sbin is
# first for root and for systemd services), so scripts that shell out to
# hardware the guest does not have -- openrgb, nvidia-smi, amixer -- can be
# driven through a chosen behaviour instead of "command not found":
#
# exit[:N] return N immediately (default 0)
# hang never return (what openrgb 1.0-2 did on 2026-09-12)
# sleep:S return 0 after S seconds
#
# Every invocation is appended to /var/log/vmbox-shim/<tool>.log as
# "<epoch> <argv>", so the host can assert from the guest what was called,
# with which arguments, and in what order relative to other shims.
# ============================================================================
set -euo pipefail
TOOL="${1:?usage: shim.sh <tool> [exit[:N]|hang|sleep:S]}"
MODE="${2:-exit}"
# Overridable for the host-side bats tests, which must not write to /usr.
readonly SHIM_DIR="${VMBOX_SHIM_DIR:-/usr/local/sbin}"
readonly LOG_DIR="${VMBOX_SHIM_LOG_DIR:-/var/log/vmbox-shim}"
case "$TOOL" in
*/*|'') echo "shim: tool must be a bare command name, got '$TOOL'" >&2; exit 1 ;;
esac
behaviour=""
case "$MODE" in
exit) behaviour='exit 0' ;;
exit:*) behaviour="exit ${MODE#exit:}" ;;
hang) behaviour='exec sleep infinity' ;;
sleep:*) behaviour="sleep ${MODE#sleep:}; exit 0" ;;
*) echo "shim: unknown mode '$MODE' (exit[:N] | hang | sleep:S)" >&2; exit 1 ;;
esac
install -d -m 755 "$LOG_DIR" "$SHIM_DIR"
cat > "$SHIM_DIR/$TOOL" <<SHIM
#!/bin/bash
# vmbox shim for ${TOOL} (mode: ${MODE}) -- installed by \`vm shim\`.
printf '%(%s)T %s\\n' -1 "\$*" >> "${LOG_DIR}/${TOOL}.log"
${behaviour}
SHIM
chmod 755 "$SHIM_DIR/$TOOL"
: > "$LOG_DIR/$TOOL.log"
echo "shim: $SHIM_DIR/$TOOL installed (mode: $MODE), log: $LOG_DIR/$TOOL.log"