feat: on-demand RDP - connect xfreerdp only when session opens
Replaces always-on xfreerdp with on-demand model (load 12 to under 1 at idle). - rdp-proxy/manager.py: HTTP server port 7001 managing xfreerdp lifecycle - rdp-proxy/entrypoint.sh: starts Xvfb+x11vnc+websockify+manager, no auto-connect - rdp-proxy/Dockerfile: adds python3, copies manager.py, exposes 7001 - runtime.py: connect_rdp_slot and disconnect_rdp_slot via manager HTTP API - terminate_session_record: disconnect instead of container restart - main.py: calls connect_rdp_slot in background thread on session create - maintenance.py: cleanup_loop disconnects on expire, run_maintenance_service includes RDP slot init, maintenance_runner fixed to import maintenance
This commit is contained in:
+14
-53
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
RDP_HOST="${RDP_HOST:?RDP_HOST is required}"
|
||||
RDP_HOST="${RDP_HOST:-}"
|
||||
RDP_PORT="${RDP_PORT:-3389}"
|
||||
RDP_USER="${RDP_USER:-}"
|
||||
RDP_PASSWORD="${RDP_PASSWORD:-}"
|
||||
@@ -186,69 +186,30 @@ export DISPLAY="$DISPLAY_NUM"
|
||||
DISPLAY_N="${DISPLAY_NUM#:}"
|
||||
rm -f "/tmp/.X${DISPLAY_N}-lock" "/tmp/.X11-unix/X${DISPLAY_N}" 2>/dev/null || true
|
||||
Xvfb "$DISPLAY_NUM" -screen 0 "$SCREEN_GEOMETRY" >/tmp/xvfb.log 2>&1 &
|
||||
XVFB_PID=$!
|
||||
sleep 1
|
||||
|
||||
RDP_ARGS=(
|
||||
"/v:${RDP_HOST}:${RDP_PORT}"
|
||||
"/cert:ignore"
|
||||
"/f"
|
||||
"/dynamic-resolution"
|
||||
"/gfx-h264:avc444"
|
||||
"/network:auto"
|
||||
"+clipboard"
|
||||
)
|
||||
|
||||
if [ -n "$RDP_SECURITY" ]; then
|
||||
RDP_ARGS+=("/sec:${RDP_SECURITY}")
|
||||
fi
|
||||
|
||||
if [ -n "$RDP_USER" ]; then
|
||||
RDP_ARGS+=("/u:${RDP_USER}")
|
||||
fi
|
||||
if [ -n "$RDP_PASSWORD" ]; then
|
||||
RDP_ARGS+=("/p:${RDP_PASSWORD}")
|
||||
fi
|
||||
if [ -n "$RDP_DOMAIN" ]; then
|
||||
RDP_ARGS+=("/d:${RDP_DOMAIN}")
|
||||
fi
|
||||
|
||||
xfreerdp "${RDP_ARGS[@]}" >/tmp/xfreerdp.log 2>&1 &
|
||||
XFREERDP_PID=$!
|
||||
|
||||
x11vnc -display "$DISPLAY_NUM" -rfbport 5900 -forever -shared -nopw -noxdamage >/tmp/x11vnc.log 2>&1 &
|
||||
X11VNC_PID=$!
|
||||
|
||||
websockify --verbose --idle-timeout="$IDLE_TIMEOUT" --web=/opt/portal 6080 localhost:5900 >/tmp/websockify.log 2>&1 &
|
||||
WEBSOCKIFY_PID=$!
|
||||
|
||||
python3 /manager.py >/tmp/manager.log 2>&1 &
|
||||
MANAGER_PID=$!
|
||||
|
||||
# Anti-idle: send Shift key to xfreerdp window every 30s to prevent remote lock screen
|
||||
anti_idle_loop() {
|
||||
sleep 5
|
||||
while true; do
|
||||
WID=$(DISPLAY="$DISPLAY_NUM" xdotool search --pid "$XFREERDP_PID" 2>/dev/null | head -1)
|
||||
if [ -n "$WID" ]; then
|
||||
DISPLAY="$DISPLAY_NUM" xdotool key --window "$WID" shift 2>/dev/null || true
|
||||
else
|
||||
DISPLAY="$DISPLAY_NUM" xdotool mousemove --sync 500 300 2>/dev/null || true
|
||||
sleep 1
|
||||
DISPLAY="$DISPLAY_NUM" xdotool mousemove --sync 600 400 2>/dev/null || true
|
||||
fi
|
||||
sleep 30
|
||||
done
|
||||
}
|
||||
anti_idle_loop &
|
||||
ANTI_IDLE_PID=$!
|
||||
|
||||
# Graceful shutdown on docker stop (SIGTERM) — exit 0 so Docker does NOT auto-restart
|
||||
cleanup() {
|
||||
kill "$XFREERDP_PID" "$X11VNC_PID" "$WEBSOCKIFY_PID" "$ANTI_IDLE_PID" 2>/dev/null
|
||||
python3 -c "
|
||||
import urllib.request, sys
|
||||
try:
|
||||
urllib.request.urlopen('http://localhost:7001/disconnect', b'', timeout=3)
|
||||
except Exception as e:
|
||||
sys.stderr.write(str(e) + '\n')
|
||||
" 2>/dev/null || true
|
||||
kill "$X11VNC_PID" "$WEBSOCKIFY_PID" "$MANAGER_PID" "$XVFB_PID" 2>/dev/null || true
|
||||
exit 0
|
||||
}
|
||||
trap cleanup TERM INT
|
||||
|
||||
# Monitor xfreerdp — when it exits (disconnect/logoff) restart the container
|
||||
wait "$XFREERDP_PID"
|
||||
echo "xfreerdp exited (code $?), triggering container restart" >> /tmp/xfreerdp.log
|
||||
kill "$X11VNC_PID" "$WEBSOCKIFY_PID" 2>/dev/null
|
||||
exit 1
|
||||
wait "$WEBSOCKIFY_PID" || true
|
||||
cleanup
|
||||
|
||||
Reference in New Issue
Block a user