#!/bin/bash #ensure we always start a "log" with the PID of this script echo $$ set -euo pipefail # Config USER_ID=$(id -u) SCRIPT_PID=$$ TIMESTAMP=$(date +"%Y%m%dT%H%M") TEMPBASE="/tmp/xproxy-${USER_ID}-${SCRIPT_PID}" SOCKET_DIR="${TEMPBASE}/xclock-demo" SOCKET_PATH="${SOCKET_DIR}/X5" CONTAINER_NAME="xclock-demo-${SCRIPT_PID}" DISPLAY_NUM="5" CONTAINER_SCRIPT="${TEMPBASE}/run.sh" # Centralized log directory LOGBASE="/tmp/x11proxy-logs-${USER_ID}" mkdir -p "$LOGBASE" LOGFILE="${LOGBASE}/xproxy-${SCRIPT_PID}-${TIMESTAMP}.log" # Cleanup stale logs cleanup_stale_logs() { echo "Scanning for stale xclock logs..." find "$LOGBASE" -type f -name "xproxy-*.log" | while read -r log; do pid=$(head -n 1 "$log") if ! kill -0 "$pid" 2>/dev/null; then echo "Removing stale log: $log" rm -f "$log" fi done } # Entry point: daemonize if not already if [ "${1:-}" != "--daemon" ]; then cleanup_stale_logs echo "Launching X11 proxy and container in background..." # Launch self in background and prepend PID to log nohup "$0" --daemon 2>&1 > "$LOGFILE" & sleep 1 #let the pocess start (and echo any nohup warnings) echo "Started background process. Logs: $LOGFILE" exit 0 fi trap cleanup EXIT mkdir -p "$SOCKET_DIR" # Function: start proxy start_proxy() { mkdir -p "${SOCKET_DIR}" chmod 0700 "${SOCKET_DIR}" echo "Created socket directory: ${SOCKET_DIR}" ./x11proxy -proxy-socket "${SOCKET_PATH}" & PROXY_PID=$! echo "Started x11proxy (PID $PROXY_PID)" sleep 1 } # Function: write container script write_container_script() { cat > "$CONTAINER_SCRIPT" <<'EOF' #!/bin/sh set -e apk update apk add xclock font-misc-misc ttf-dejavu SOCKET="/tmp/.X11-unix/X5" SOCKET_UID=$(stat -c '%u' "$SOCKET") echo "Socket owned by UID: $SOCKET_UID" adduser -u "$SOCKET_UID" -D x11user su x11user -c "whoami && xclock" EOF chmod +x "$CONTAINER_SCRIPT" echo "Wrote container script: $CONTAINER_SCRIPT" } # Function: run container run_container() { echo "Launching Alpine container with xclock..." docker run --rm -i \ --name "${CONTAINER_NAME}" \ -e DISPLAY=":${DISPLAY_NUM}" \ -v "${SOCKET_DIR}:/tmp/.X11-unix" \ -v "${CONTAINER_SCRIPT}:/run.sh" \ alpine sh /run.sh } # Function: cleanup cleanup() { echo "Cleaning up..." kill $PROXY_PID || true rm -rf "${TEMPBASE}" echo "Done." } # Run sequence start_proxy write_container_script run_container cleanup