diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..78f9461 --- /dev/null +++ b/go.mod @@ -0,0 +1,4 @@ +module x11proxy + +go 1.24.5 + diff --git a/hello_xclock.sh b/hello_xclock.sh new file mode 100755 index 0000000..665fcda --- /dev/null +++ b/hello_xclock.sh @@ -0,0 +1,109 @@ +#!/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..." + mkdir -p "${TEMPBASE}" + + # Launch self in background and prepend PID to log + nohup "$0" --daemon 2>&1 > "$LOGFILE" & + + 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