Files
local-ci-cd-system/scripts/install-vmware-gui-access.sh
T
Simone 3f43b1ca12 feat(setup): persist ci-runner X grant for ci vmware GUI
`ci vmware` runs as ci-runner and relies on host-based X auth (xhost),
but the grant is per-session and wiped on logout / X restart, so the GUI
launch fails with "cannot open X display" after every desktop relogin.

Add scripts/install-vmware-gui-access.sh: installs an XDG autostart entry
in the desktop user's home that re-applies `xhost +SI:localuser:ci-runner`
at each graphical login, and applies it immediately when a display is
reachable. Desktop user resolves from --desktop-user / $CI_DESKTOP_USER /
$SUDO_USER (never root); service user from $CI_RUN_USER. --uninstall
removes the autostart entry and revokes the live grant.

Wire it into setup-host-linux.sh as Step 8, with --desktop-user (default
$SUDO_USER) and --skip-gui-access for headless hosts.
2026-06-08 21:11:07 +02:00

99 lines
4.2 KiB
Bash
Executable File

#!/usr/bin/env bash
# install-vmware-gui-access.sh — authorise the ci-runner service user on the
# desktop operator's X session so `ci vmware` can open the VMware Workstation
# GUI (the VM files are owned by ci-runner, mode 750, so the GUI must run as
# that user — see commands/vm.py:vmware).
#
# `ci vmware` runs as ci-runner and relies on host-based X auth (xhost). An
# xhost grant is runtime + per-session: it is wiped on logout / X restart. This
# script makes it persistent by installing a per-user XDG autostart entry in
# the *desktop* user's home that re-runs the grant at every graphical login. It
# also applies the grant immediately when a display is reachable, so no logout
# is needed the first time.
#
# Usage:
# ./scripts/install-vmware-gui-access.sh # desktop user = $SUDO_USER or $USER
# ./scripts/install-vmware-gui-access.sh --desktop-user simone
# ./scripts/install-vmware-gui-access.sh --uninstall
#
# Env:
# CI_RUN_USER service user to authorise (default: ci-runner)
# CI_DESKTOP_USER desktop user whose X session is granted (overridden by --desktop-user)
#
# Idempotent: re-running overwrites the autostart entry in place.
#
# Security note: `xhost +SI:localuser:<user>` grants that local user full
# access to the desktop X session (input injection, screen capture). Acceptable
# on a single-operator CI workstation. `SI:localuser:` is same-machine only,
# never network. Remove with --uninstall when no longer needed.
set -euo pipefail
RUN_USER="${CI_RUN_USER:-ci-runner}"
DESKTOP_USER="${CI_DESKTOP_USER:-}"
ACTION="install"
log() { printf '[install-vmware-gui-access] %s\n' "$*"; }
die() { printf '[install-vmware-gui-access] ERROR: %s\n' "$*" >&2; exit 1; }
while [ $# -gt 0 ]; do
case "$1" in
--desktop-user) DESKTOP_USER="${2:-}"; shift 2 ;;
--uninstall) ACTION="uninstall"; shift ;;
-h|--help) sed -n '2,30p' "$0"; exit 0 ;;
*) die "unknown argument: $1 (use --desktop-user <name> or --uninstall)" ;;
esac
done
# Resolve the desktop user: explicit flag/env, else the user behind sudo, else
# the current user. Never default to root — root has no graphical session.
if [ -z "$DESKTOP_USER" ]; then
DESKTOP_USER="${SUDO_USER:-$USER}"
fi
[ -z "$DESKTOP_USER" ] && die "could not determine desktop user (pass --desktop-user <name>)"
[ "$DESKTOP_USER" = "root" ] && die "desktop user resolved to root; pass --desktop-user <name>"
id "$DESKTOP_USER" &>/dev/null || die "desktop user '$DESKTOP_USER' does not exist"
id "$RUN_USER" &>/dev/null || log "WARNING: service user '$RUN_USER' does not exist yet — grant installed anyway."
HOME_DIR="$(getent passwd "$DESKTOP_USER" | cut -d: -f6)"
[ -n "$HOME_DIR" ] && [ -d "$HOME_DIR" ] || die "home directory for '$DESKTOP_USER' not found"
AUTOSTART_DIR="$HOME_DIR/.config/autostart"
DESKTOP_FILE="$AUTOSTART_DIR/ci-runner-xhost.desktop"
GRANT="SI:localuser:$RUN_USER"
# Run a command as the desktop user, preserving ownership of created files.
as_desktop() { sudo -u "$DESKTOP_USER" "$@"; }
if [ "$ACTION" = "uninstall" ]; then
as_desktop rm -f "$DESKTOP_FILE" && log "removed $DESKTOP_FILE"
# Best-effort: revoke the live grant too (ignore failure when no display).
as_desktop xhost "-$GRANT" >/dev/null 2>&1 && log "revoked live grant ($GRANT)" || true
log "done."
exit 0
fi
# Install the autostart entry, owned by the desktop user.
as_desktop mkdir -p "$AUTOSTART_DIR"
as_desktop tee "$DESKTOP_FILE" >/dev/null <<EOF
[Desktop Entry]
Type=Application
Name=Authorise $RUN_USER on X (CI vmware GUI)
Comment=Grant the $RUN_USER service user access to this X session so 'ci vmware' can open the VMware Workstation GUI
Exec=xhost +$GRANT
X-GNOME-Autostart-enabled=true
NoDisplay=true
EOF
as_desktop chmod 0644 "$DESKTOP_FILE"
log "installed $DESKTOP_FILE (re-applies at each graphical login)"
# Apply immediately if a display is reachable now, so no logout is needed.
DESKTOP_DISPLAY="${DISPLAY:-:0}"
if as_desktop env DISPLAY="$DESKTOP_DISPLAY" xhost "+$GRANT" >/dev/null 2>&1; then
log "applied now on display $DESKTOP_DISPLAY ($GRANT)"
else
log "could not apply now (no reachable display) — takes effect at next login of '$DESKTOP_USER'"
fi
log "done. Test with: ci vmware"