PSA/tools/ai-automation/vnc-startup-improved.sh
Hermes 284313f908
Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Initial import of AlgaPSA codebase from PSA server
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz

Source: /opt/alga-psa on psa.joliet.tech
2026-06-22 16:12:17 -05:00

314 lines
9.0 KiB
Bash
Executable File

#!/bin/bash
# Improved VNC startup script for Kubernetes environments
# This version includes better error handling and fallback options
echo "=== Improved VNC Startup Script for Kubernetes ==="
echo "Starting at: $(date)"
echo "Running as: $(id)"
# Configuration
DISPLAY_NUM=99
export DISPLAY=:${DISPLAY_NUM}
VNC_PORT=5901
WEBSOCKET_PORT=5900
MAX_RETRIES=3
RETRY_DELAY=5
# Color codes for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Helper functions
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
check_process() {
local process_name=$1
if pgrep -f "$process_name" > /dev/null; then
local pid=$(pgrep -f "$process_name" | head -1)
log_info "$process_name is running (PID: $pid)"
return 0
else
log_error "$process_name is NOT running"
return 1
fi
}
setup_directories() {
log_info "Setting up directories..."
# Create necessary directories
mkdir -p /tmp/.X11-unix /tmp/.ICE-unix /tmp/xvfb
chmod 1777 /tmp/.X11-unix /tmp/.ICE-unix
chmod 777 /tmp/xvfb
# Set up user-specific directories if running as non-root
if [ "$UID" != "0" ]; then
export XDG_RUNTIME_DIR=${XDG_RUNTIME_DIR:-/tmp/xvfb/runtime-$UID}
export XAUTHORITY=${XAUTHORITY:-/tmp/xvfb/.Xauthority-$UID}
mkdir -p "$XDG_RUNTIME_DIR"
chmod 700 "$XDG_RUNTIME_DIR"
fi
}
check_system_resources() {
log_info "Checking system resources..."
# Memory check
local mem_available=$(awk '/MemAvailable/ {print int($2/1024)}' /proc/meminfo)
log_info "Available memory: ${mem_available}MB"
if [ "$mem_available" -lt 256 ]; then
log_warn "Low memory detected. Using minimal configuration."
echo "minimal"
elif [ "$mem_available" -lt 512 ]; then
log_warn "Limited memory. Using reduced configuration."
echo "reduced"
else
echo "standard"
fi
}
start_xvfb() {
local config_level=$(check_system_resources)
local xvfb_started=false
# Force software rendering to avoid DRI driver crashes in Kubernetes
export LIBGL_ALWAYS_SOFTWARE=1
export GALLIUM_DRIVER=llvmpipe
export LP_NO_RAST=false
export LIBGL_DRI3_DISABLE=1
export LIBGL_ALWAYS_INDIRECT=1
log_info "Forced software rendering mode for compatibility"
# Kill any existing Xvfb processes
pkill -f "Xvfb :${DISPLAY_NUM}" 2>/dev/null || true
sleep 2
# Define configurations based on resource availability
case "$config_level" in
"minimal")
local configs=(
"-screen 0 640x480x8 -ac -extension GLX"
"-screen 0 640x480x8 -ac"
"-screen 0 320x240x8 -ac"
)
;;
"reduced")
local configs=(
"-screen 0 1920x1024x16 -ac -nolisten tcp -extension GLX"
"-screen 0 1280x1024x16 -ac -extension GLX"
"-screen 0 1024x768x16 -ac -extension GLX"
"-screen 0 800x600x8 -ac"
)
;;
*)
local configs=(
"-screen 0 1920x1024x16 -ac -nolisten tcp -extension GLX +extension RANDR"
"-screen 0 1280x1024x16 -ac -extension GLX"
"-screen 0 1024x768x16 -ac -extension GLX"
"-screen 0 800x600x16 -ac"
"-screen 0 640x480x8 -ac"
)
;;
esac
# Try each configuration
for config in "${configs[@]}"; do
log_info "Trying Xvfb configuration: $config"
Xvfb :${DISPLAY_NUM} $config > /tmp/xvfb/xvfb.log 2>&1 &
local xvfb_pid=$!
sleep 3
if kill -0 $xvfb_pid 2>/dev/null; then
# Test if display is working
if DISPLAY=:${DISPLAY_NUM} xdpyinfo > /tmp/xvfb/xdpyinfo.log 2>&1; then
log_info "Xvfb started successfully with configuration: $config"
xvfb_started=true
break
else
log_warn "Display test failed, trying next configuration..."
kill $xvfb_pid 2>/dev/null || true
fi
else
log_warn "Xvfb failed to start with this configuration"
fi
done
if [ "$xvfb_started" = "false" ]; then
log_error "Failed to start Xvfb with any configuration"
log_error "Last error log:"
tail -20 /tmp/xvfb/xvfb.log
return 1
fi
return 0
}
start_window_manager() {
log_info "Starting window manager..."
# Try fluxbox first, then fallback to simpler options
if command -v fluxbox >/dev/null 2>&1; then
# Create a simple fluxbox menu if it doesn't exist
mkdir -p ~/.fluxbox
if [ ! -f ~/.fluxbox/menu ]; then
cat > ~/.fluxbox/menu << 'EOF'
[begin] (Fluxbox)
[exec] (Terminal) {x-terminal-emulator}
[exec] (File Manager) {thunar}
[submenu] (Applications)
[exec] (Web Browser) {chromium}
[exec] (Text Editor) {nano}
[end]
[submenu] (System)
[exec] (Reload Config) {fluxbox-remote reload}
[restart] (Restart)
[exit] (Exit)
[end]
[end]
EOF
fi
fluxbox > /tmp/xvfb/fluxbox.log 2>&1 &
sleep 2
check_process "fluxbox" || log_warn "Fluxbox not running, but continuing..."
else
log_warn "Fluxbox not found, skipping window manager"
fi
}
start_vnc_server() {
if ! command -v x11vnc >/dev/null 2>&1; then
log_warn "x11vnc not installed, VNC will not be available"
return 1
fi
local vnc_started=false
for attempt in $(seq 1 $MAX_RETRIES); do
log_info "Starting x11vnc (attempt $attempt/$MAX_RETRIES)..."
x11vnc -display :${DISPLAY_NUM} \
-nopw \
-listen localhost \
-xkb \
-forever \
-shared \
-many \
-rfbport ${VNC_PORT} \
-timeout 0 \
-ping 30 \
-defer 1 \
-o /tmp/xvfb/x11vnc.log \
> /tmp/xvfb/x11vnc_stdout.log 2>&1 &
sleep 3
if check_process "x11vnc"; then
vnc_started=true
break
else
log_warn "x11vnc failed to start, attempt $attempt"
[ -f /tmp/xvfb/x11vnc.log ] && tail -10 /tmp/xvfb/x11vnc.log
sleep $RETRY_DELAY
fi
done
[ "$vnc_started" = "true" ] && return 0 || return 1
}
start_websocket_proxy() {
if ! command -v websockify >/dev/null 2>&1; then
log_warn "websockify not installed, WebSocket proxy will not be available"
return 1
fi
log_info "Starting WebSocket proxy..."
# Check for NoVNC
local novnc_path=""
for path in /usr/share/novnc /usr/share/webapps/novnc /opt/novnc; do
if [ -d "$path" ]; then
novnc_path="$path"
break
fi
done
if [ -n "$novnc_path" ]; then
log_info "Using NoVNC from: $novnc_path"
# Copy custom index if exists (skip if no write permission)
if [ -f "/usr/src/app/novnc-index.html" ] && [ -w "$novnc_path" ]; then
cp /usr/src/app/novnc-index.html "$novnc_path/index.html"
fi
# Start websockify with NoVNC web files
cd "$novnc_path"
# Add verbose logging and timeout settings to prevent disconnections
python3 -m websockify -v --web . --heartbeat=30 0.0.0.0:${WEBSOCKET_PORT} localhost:${VNC_PORT} > /tmp/xvfb/websockify.log 2>&1 &
cd - > /dev/null
else
log_warn "NoVNC not found, starting websockify without web interface"
python3 -m websockify -v --heartbeat=30 0.0.0.0:${WEBSOCKET_PORT} localhost:${VNC_PORT} > /tmp/xvfb/websockify.log 2>&1 &
fi
sleep 3
check_process "websockify"
}
# Main execution
main() {
log_info "Starting VNC setup..."
# Setup
setup_directories
# Start Xvfb
if ! start_xvfb; then
log_error "Failed to start Xvfb, falling back to xvfb-run"
exec xvfb-run -a -s "-screen 0 1024x768x16" "$@"
fi
# Start window manager (optional)
start_window_manager
# Start VNC server
if start_vnc_server; then
# Start WebSocket proxy only if VNC is running
start_websocket_proxy
log_info "VNC setup complete!"
log_info "VNC is available on port ${VNC_PORT}"
[ -n "$novnc_path" ] && log_info "NoVNC web interface: http://localhost:${WEBSOCKET_PORT}/vnc.html"
else
log_warn "VNC server not available, but X display is working"
fi
# Summary
echo ""
log_info "=== Service Status Summary ==="
check_process "Xvfb :${DISPLAY_NUM}"
check_process "fluxbox" || true
check_process "x11vnc" || true
check_process "websockify" || true
echo ""
# Execute the main application
log_info "Starting main application..."
exec "$@"
}
# Run main function with all arguments
main "$@"