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
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz Source: /opt/alga-psa on psa.joliet.tech
314 lines
9.0 KiB
Bash
Executable File
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 "$@" |