mirror of
https://github.com/kuhyx/utils.git
synced 2026-11-10 20:07:18 +01:00
vmbox: give guest commands the sandbox's own X session
The image ships Xorg + i3 on tty1 precisely so locker and i3 tests can run,
but `vm run` executes through `sh -c`, which reads no profile. Every X tool
therefore landed with no DISPLAY and no XAUTHORITY and failed with
"Could not determine i3 socket path" -- indistinguishable from "this sandbox
has no X server". testsAndMisc's i3-configuration installer failed that way;
with the environment resolved it exits 0 and i3-msg reports {"success":true}.
XAUTHORITY is the awkward half: startx generates /tmp/serverauth.XXXXXXXX
with a fresh random suffix every boot, so it cannot be hardcoded. Resolve it
from the running Xorg's own -auth argument, falling back to a newest-first
glob.
The `[ -f ]` guard on the source line is load-bearing, not defensive
dressing. In POSIX sh, `.` on a missing file is a SPECIAL BUILTIN error that
exits the shell outright, and `|| true` does NOT rescue it -- written that
way, every `vm run` against a base image predating this snippet silently
produced no output at all. Found by doing exactly that.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdyMBGCrGVGDWtJ9xe48f3
This commit is contained in:
parent
25ba142f94
commit
cf5982c9fa
@ -138,6 +138,48 @@ exec --no-startup-id xterm -T vmbox-ready -e 'echo VMBOX READY; exec bash'
|
||||
I3
|
||||
chown -R "$GUEST_USER:$GUEST_USER" "/home/$GUEST_USER/.config"
|
||||
|
||||
# --- X session discovery for non-login commands ---------------------------
|
||||
# The image ships a real X/i3 session on tty1 so locker and i3 tests can run.
|
||||
# But `vm run` executes through `sh -c`, which reads no profile, so those
|
||||
# commands land with no DISPLAY and no XAUTHORITY -- and every X tool then
|
||||
# fails with "Could not determine i3 socket path" / "cannot open display".
|
||||
# That looks exactly like "the sandbox has no X", which is wrong and cost a
|
||||
# real installer run to diagnose.
|
||||
#
|
||||
# XAUTHORITY is the awkward half: startx generates /tmp/serverauth.XXXXXXXX
|
||||
# with a random suffix on every boot, so it cannot be hardcoded. Resolve it
|
||||
# from the running Xorg process instead, falling back to a glob.
|
||||
cat > /etc/profile.d/vmbox-x11.sh <<'XENV'
|
||||
# Point non-login shells at the guest's X session, if one is running.
|
||||
# Sourced by vmbox's `vm run`; harmless when no X session exists.
|
||||
if [ -z "${DISPLAY:-}" ]; then
|
||||
if pgrep -x Xorg >/dev/null 2>&1; then
|
||||
DISPLAY=":0"
|
||||
export DISPLAY
|
||||
fi
|
||||
fi
|
||||
if [ -n "${DISPLAY:-}" ] && [ -z "${XAUTHORITY:-}" ]; then
|
||||
# Prefer the auth file the running Xorg was actually started with.
|
||||
_vmbox_xauth="$(tr '\0' '\n' < /proc/"$(pgrep -x Xorg | head -1)"/cmdline 2>/dev/null \
|
||||
| grep -A1 -x -- -auth | tail -1)"
|
||||
if [ ! -f "${_vmbox_xauth:-}" ]; then
|
||||
_vmbox_xauth="$(ls -1t /tmp/serverauth.* 2>/dev/null | head -1)"
|
||||
fi
|
||||
if [ -f "${_vmbox_xauth:-}" ]; then
|
||||
XAUTHORITY="$_vmbox_xauth"
|
||||
export XAUTHORITY
|
||||
fi
|
||||
unset _vmbox_xauth
|
||||
fi
|
||||
# i3 tools look here when I3SOCK is unset; setting it explicitly avoids a
|
||||
# second round of X round-trips in tests that shell out repeatedly.
|
||||
if [ -n "${DISPLAY:-}" ] && [ -z "${I3SOCK:-}" ] && command -v i3 >/dev/null 2>&1; then
|
||||
I3SOCK="$(i3 --get-socketpath 2>/dev/null || true)"
|
||||
[ -n "$I3SOCK" ] && export I3SOCK || unset I3SOCK
|
||||
fi
|
||||
XENV
|
||||
chmod 644 /etc/profile.d/vmbox-x11.sh
|
||||
|
||||
# --- static IP on the VM-to-VM segment ------------------------------------
|
||||
# The multicast segment has no DHCP (the user-mode NIC serves the other
|
||||
# interface), so without a static address sandboxes cannot reach each other.
|
||||
|
||||
@ -17,6 +17,14 @@ source "$(dirname "${BASH_SOURCE[0]}")/ssh.sh"
|
||||
source "$(dirname "${BASH_SOURCE[0]}")/verdict.sh"
|
||||
|
||||
readonly RC_PATH="/var/tmp/vmbox.rc"
|
||||
# Sourced before every guest command so X11 tests can reach the guest's own
|
||||
# i3 session. `sh -c` reads no profile, so without this DISPLAY/XAUTHORITY are
|
||||
# unset and every X tool fails as if the sandbox had no X server at all.
|
||||
# The `[ -f ]` guard is load-bearing, not defensive dressing: in POSIX sh, `.`
|
||||
# on a missing file is a SPECIAL BUILTIN error that exits the shell outright,
|
||||
# and `|| true` does NOT rescue it. Written that way, every `vm run` against a
|
||||
# base image predating this snippet silently produced no output at all.
|
||||
readonly GUEST_ENV_SETUP='[ -f /etc/profile.d/vmbox-x11.sh ] && . /etc/profile.d/vmbox-x11.sh;'
|
||||
# Transport for guest commands. Serial is the default for shutdown work: it
|
||||
# keeps printing through the poweroff that kills ssh, and it still works when
|
||||
# sshd does not. ssh stays available as the faster path for bulk work.
|
||||
@ -67,7 +75,7 @@ _run_exec() {
|
||||
case "$(_run_transport "$name")" in
|
||||
serial) _run_exec_serial "$name" "$cmd" ;;
|
||||
*) vm_ssh_exec "$name" \
|
||||
"sh -c '{ $cmd; } ; echo \$? | sudo tee $RC_PATH >/dev/null' </dev/null" \
|
||||
"sh -c '$GUEST_ENV_SETUP { $cmd; } ; echo \$? | sudo tee $RC_PATH >/dev/null' </dev/null" \
|
||||
</dev/null ;;
|
||||
esac
|
||||
}
|
||||
@ -90,7 +98,7 @@ _run_exec_serial() {
|
||||
console="$(vm_console "$name")"
|
||||
[[ -S "$console" ]] || die "no serial console socket for '$name'"
|
||||
python3 "$VMBOX_LIB_DIR/serial_exec.py" "$console" \
|
||||
"{ $cmd ; } ; echo \$? > $RC_PATH"
|
||||
"$GUEST_ENV_SETUP { $cmd ; } ; echo \$? > $RC_PATH"
|
||||
}
|
||||
|
||||
# Give a guest that is shutting down time to finish writing its serial log.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user