#!/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:` 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 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 )" [ "$DESKTOP_USER" = "root" ] && die "desktop user resolved to root; pass --desktop-user " 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 </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"