From 55164c566575e054a994ff986583065afcc3367d Mon Sep 17 00:00:00 2001 From: Max Date: Thu, 5 Feb 2026 18:23:15 +0800 Subject: [PATCH] Enhance VNC sandbox images with Yao branding and sudo support - Add passwordless sudo for sandbox user in playwright and desktop images - Configure Yao branding for Fluxbox (CUI dark theme, centered logo) - Configure Yao branding for XFCE (panel icons, wallpaper, workspace shortcut) - Add D-Bus support for XFCE desktop environment - Add dynamic wallpaper generation with configurable resolution and logo size - Hide Fluxbox toolbar for cleaner Playwright automation view - Create chromium wrapper script using Playwright's bundled browser - Add feh and imagemagick for wallpaper management in Fluxbox - Update .gitignore for config scripts and TODO file Co-authored-by: Cursor --- .gitignore | 2 + sandbox/docker/desktop/Dockerfile | 24 +++ .../config/panel-launcher-chromium.desktop | 12 ++ sandbox/docker/desktop/config/setup-xfce.sh | 160 ++++++++++++++++++ .../docker/desktop/config/workspace.desktop | 9 + .../docker/desktop/config/yao-logo-128.png | Bin 0 -> 7001 bytes .../docker/desktop/config/yao-logo-256.png | Bin 0 -> 14416 bytes sandbox/docker/desktop/config/yao-logo-48.png | Bin 0 -> 2897 bytes sandbox/docker/desktop/config/yao-logo.svg | 16 ++ sandbox/docker/playwright/Dockerfile | 18 +- sandbox/docker/playwright/config/yao-logo.png | Bin 0 -> 24810 bytes sandbox/docker/vnc/start-vnc.sh | 38 +++++ 12 files changed, 277 insertions(+), 2 deletions(-) create mode 100644 sandbox/docker/desktop/config/panel-launcher-chromium.desktop create mode 100644 sandbox/docker/desktop/config/setup-xfce.sh create mode 100644 sandbox/docker/desktop/config/workspace.desktop create mode 100644 sandbox/docker/desktop/config/yao-logo-128.png create mode 100644 sandbox/docker/desktop/config/yao-logo-256.png create mode 100644 sandbox/docker/desktop/config/yao-logo-48.png create mode 100644 sandbox/docker/desktop/config/yao-logo.svg create mode 100644 sandbox/docker/playwright/config/yao-logo.png diff --git a/.gitignore b/.gitignore index eaab7002..fcd6eada 100644 --- a/.gitignore +++ b/.gitignore @@ -57,8 +57,10 @@ agent/test/UPGRADE_PLAN.md introduction/* !sandbox/docker/build.sh !sandbox/docker/vnc/*.sh +!sandbox/docker/desktop/config/*.sh sandbox/docker/yao-bridge-* sandbox/docker/claude-proxy-* sandbox/docker/claude/claude-proxy-* sandbox/proxy/claude-proxy-linux-* release/* +sandbox/TODO-VNC.md diff --git a/sandbox/docker/desktop/Dockerfile b/sandbox/docker/desktop/Dockerfile index 6fcd389c..aaa26c87 100644 --- a/sandbox/docker/desktop/Dockerfile +++ b/sandbox/docker/desktop/Dockerfile @@ -16,6 +16,8 @@ RUN sed -i 's|http://ports.ubuntu.com/ubuntu-ports|http://mirrors.mit.edu/ubuntu # Install X11, VNC, and XFCE desktop environment RUN apt-get update && apt-get install -y --no-install-recommends \ + # Sudo for sandbox user + sudo \ # Virtual display xvfb \ # VNC server @@ -23,6 +25,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ # noVNC (HTML5 VNC client) and websockify novnc \ python3-websockify \ + # D-Bus (required for XFCE) + dbus-x11 \ # XFCE Desktop (full-featured but lightweight) xfce4 \ xfce4-terminal \ @@ -40,6 +44,14 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ && apt-get remove -y xfce4-screensaver xscreensaver || true \ && rm -rf /var/lib/apt/lists/* +# Configure passwordless sudo for sandbox user +RUN echo "sandbox ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/sandbox && \ + chmod 0440 /etc/sudoers.d/sandbox + +# Create chromium wrapper script (uses Playwright's Chromium, starts maximized) +RUN echo '#!/bin/bash\nexec /home/sandbox/.cache/ms-playwright/chromium-1208/chrome-linux/chrome --no-sandbox --start-maximized "$@"' > /usr/local/bin/chromium && \ + chmod +x /usr/local/bin/chromium + # Optional: Install Playwright system dependencies (requires root) # Users can run browser automation in desktop mode too RUN npx playwright install-deps chromium || true @@ -58,6 +70,16 @@ COPY vnc/start-vnc.sh /usr/local/bin/start-vnc.sh COPY vnc/entrypoint-vnc.sh /usr/local/bin/entrypoint.sh RUN chmod +x /usr/local/bin/start-vnc.sh /usr/local/bin/entrypoint.sh +# Copy Yao branding assets +RUN mkdir -p /usr/share/yao +COPY desktop/config/yao-logo-48.png /usr/share/yao/yao-logo-48.png +COPY desktop/config/yao-logo-128.png /usr/share/yao/yao-logo-128.png +COPY desktop/config/yao-logo-256.png /usr/share/yao/yao-logo-256.png +COPY desktop/config/panel-launcher-chromium.desktop /usr/share/yao/panel-launcher-chromium.desktop +COPY desktop/config/workspace.desktop /usr/share/yao/workspace.desktop +COPY desktop/config/setup-xfce.sh /usr/local/bin/setup-xfce.sh +RUN chmod +x /usr/local/bin/setup-xfce.sh + # Environment variables for VNC ENV DISPLAY=:99 ENV VNC_PORT=5900 @@ -65,6 +87,8 @@ ENV NOVNC_PORT=6080 ENV RESOLUTION=1920x1080x24 ENV SANDBOX_VNC_ENABLED=true ENV SANDBOX_DESKTOP=xfce +# Set hostname for XFCE panel display +ENV HOSTNAME="Yao Sandbox" # Node.js environment - ensure global modules are accessible ENV NODE_PATH=/home/sandbox/.npm-global/lib/node_modules diff --git a/sandbox/docker/desktop/config/panel-launcher-chromium.desktop b/sandbox/docker/desktop/config/panel-launcher-chromium.desktop new file mode 100644 index 00000000..f392c51e --- /dev/null +++ b/sandbox/docker/desktop/config/panel-launcher-chromium.desktop @@ -0,0 +1,12 @@ +[Desktop Entry] +Version=1.0 +Type=Application +Name=Chromium +Comment=Access the Internet +GenericName=Web Browser +Exec=/usr/local/bin/chromium %U +Icon=org.xfce.webbrowser +Terminal=false +Categories=Network;WebBrowser; +MimeType=text/html;text/xml;application/xhtml+xml;application/xml;application/vnd.mozilla.xul+xml;application/rss+xml;application/rdf+xml;x-scheme-handler/http;x-scheme-handler/https; +StartupNotify=true diff --git a/sandbox/docker/desktop/config/setup-xfce.sh b/sandbox/docker/desktop/config/setup-xfce.sh new file mode 100644 index 00000000..75015a5a --- /dev/null +++ b/sandbox/docker/desktop/config/setup-xfce.sh @@ -0,0 +1,160 @@ +#!/bin/bash +# XFCE desktop configuration script +# Runs on container startup to set up Yao branding and default applications + +set -e + +XFCE_CONFIG_DIR="$HOME/.config/xfce4" +XFDESKTOP_DIR="$HOME/.config/xfce4/xfconf/xfce-perchannel-xml" +ICONS_DIR="$HOME/.local/share/icons/hicolor" +APPS_DIR="$HOME/.local/share/applications" +DESKTOP_DIR="$HOME/Desktop" + +# Create necessary directories +mkdir -p "$XFCE_CONFIG_DIR/panel" +mkdir -p "$XFDESKTOP_DIR" +mkdir -p "$ICONS_DIR/48x48/apps" +mkdir -p "$ICONS_DIR/128x128/apps" +mkdir -p "$ICONS_DIR/256x256/apps" +mkdir -p "$APPS_DIR" +mkdir -p "$DESKTOP_DIR" + +# Copy Yao logo to user icons directory +if [ -f /usr/share/yao/yao-logo-48.png ]; then + cp /usr/share/yao/yao-logo-48.png "$ICONS_DIR/48x48/apps/yao.png" + cp /usr/share/yao/yao-logo-128.png "$ICONS_DIR/128x128/apps/yao.png" + cp /usr/share/yao/yao-logo-256.png "$ICONS_DIR/256x256/apps/yao.png" + # Also copy to system location for panel icon + sudo cp /usr/share/yao/yao-logo-48.png /usr/share/pixmaps/yao.png 2>/dev/null || true + gtk-update-icon-cache "$ICONS_DIR" 2>/dev/null || true +fi + +# Copy Chromium launcher to applications +if [ -f /usr/share/yao/panel-launcher-chromium.desktop ]; then + cp /usr/share/yao/panel-launcher-chromium.desktop "$APPS_DIR/chromium-browser.desktop" +fi + +# Configure xfdesktop - hide default icons (File System, Home, Trash), keep only custom shortcuts +cat > "$XFDESKTOP_DIR/xfce4-desktop.xml" << 'XMLEOF' + + + + + + + + + + + + +XMLEOF + +# Copy workspace shortcut to desktop (named "Workspace" with folder icon) +if [ -f /usr/share/yao/workspace.desktop ]; then + cp /usr/share/yao/workspace.desktop "$DESKTOP_DIR/workspace.desktop" + chmod +x "$DESKTOP_DIR/workspace.desktop" +fi + +# Set Chromium as default browser +xdg-settings set default-web-browser chromium-browser.desktop 2>/dev/null || true + +# Configure XFCE panel - set Applications menu icon to Yao logo +# This will be applied when xfce4-panel starts +cat > "$XFDESKTOP_DIR/xfce4-panel.xml" << 'XMLEOF' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +XMLEOF + +echo "[XFCE Setup] Configuration complete" diff --git a/sandbox/docker/desktop/config/workspace.desktop b/sandbox/docker/desktop/config/workspace.desktop new file mode 100644 index 00000000..dbb5ebdb --- /dev/null +++ b/sandbox/docker/desktop/config/workspace.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Version=1.0 +Type=Application +Name=Workspace +Comment=Open Workspace folder +Icon=folder +Exec=thunar /workspace +Terminal=false +Categories=System;FileManager; diff --git a/sandbox/docker/desktop/config/yao-logo-128.png b/sandbox/docker/desktop/config/yao-logo-128.png new file mode 100644 index 0000000000000000000000000000000000000000..d86a79ac11818c1c276eb3bd62f1851731fef8c7 GIT binary patch literal 7001 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 CPUR*5 literal 0 HcmV?d00001 diff --git a/sandbox/docker/desktop/config/yao-logo-48.png b/sandbox/docker/desktop/config/yao-logo-48.png new file mode 100644 index 0000000000000000000000000000000000000000..52c779700b119aed32af89a43e04578d90141c00 GIT binary patch literal 2897 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 + + Yaobots + + + + + + + + + + + + + \ No newline at end of file diff --git a/sandbox/docker/playwright/Dockerfile b/sandbox/docker/playwright/Dockerfile index be6faa46..e131744f 100644 --- a/sandbox/docker/playwright/Dockerfile +++ b/sandbox/docker/playwright/Dockerfile @@ -16,6 +16,8 @@ RUN sed -i 's|http://ports.ubuntu.com/ubuntu-ports|http://mirrors.mit.edu/ubuntu # Install X11, VNC, and minimal window manager RUN apt-get update && apt-get install -y --no-install-recommends \ + # Sudo for sandbox user + sudo \ # Virtual display xvfb \ # VNC server @@ -25,6 +27,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ python3-websockify \ # Minimal window manager (lightweight, perfect for Playwright) fluxbox \ + # Background/wallpaper utilities + feh \ + imagemagick \ # Fonts (required for proper browser rendering) fonts-liberation \ fonts-noto-cjk \ @@ -36,6 +41,10 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ pulseaudio \ && rm -rf /var/lib/apt/lists/* +# Configure passwordless sudo for sandbox user +RUN echo "sandbox ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/sandbox && \ + chmod 0440 /etc/sudoers.d/sandbox + # Install Playwright system dependencies (requires root) # This installs system libraries needed by Chromium/Firefox RUN npx playwright install-deps chromium firefox || true @@ -50,11 +59,16 @@ RUN npm install -g playwright && \ USER root -# Copy VNC startup scripts +# Create directories for branding assets +RUN mkdir -p /usr/local/share/yao + +# Copy VNC startup scripts and branding assets # Note: Build context should be sandbox/docker/, so paths are relative to that COPY vnc/start-vnc.sh /usr/local/bin/start-vnc.sh COPY vnc/entrypoint-vnc.sh /usr/local/bin/entrypoint.sh -RUN chmod +x /usr/local/bin/start-vnc.sh /usr/local/bin/entrypoint.sh +COPY playwright/config/setup-fluxbox.sh /usr/local/bin/setup-fluxbox.sh +COPY playwright/config/yao-logo.png /usr/local/share/yao/yao-logo.png +RUN chmod +x /usr/local/bin/start-vnc.sh /usr/local/bin/entrypoint.sh /usr/local/bin/setup-fluxbox.sh # Environment variables for VNC ENV DISPLAY=:99 diff --git a/sandbox/docker/playwright/config/yao-logo.png b/sandbox/docker/playwright/config/yao-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..de7e59fb2b8374048cf82680484c3d28ec23fded GIT binary patch literal 24810 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 YVc|z6QtRCJZ^tRgsmYeUd>i=x07`^SIRF3v literal 0 HcmV?d00001 diff --git a/sandbox/docker/vnc/start-vnc.sh b/sandbox/docker/vnc/start-vnc.sh index d7d0677b..57f0a03c 100644 --- a/sandbox/docker/vnc/start-vnc.sh +++ b/sandbox/docker/vnc/start-vnc.sh @@ -31,20 +31,58 @@ if ! kill -0 $XVFB_PID 2>/dev/null; then fi echo "[VNC] Xvfb started (PID: $XVFB_PID)" +# Start D-Bus session bus (required for XFCE) +if [ "$DESKTOP" = "xfce" ] || [ "$DESKTOP" = "xfce4" ]; then + echo "[VNC] Starting D-Bus session bus..." + if command -v dbus-launch &> /dev/null; then + eval $(dbus-launch --sh-syntax) + export DBUS_SESSION_BUS_ADDRESS + echo "[VNC] D-Bus started: $DBUS_SESSION_BUS_ADDRESS" + else + echo "[VNC] WARNING: dbus-launch not found, XFCE may have limited functionality" + fi +fi + # Start window manager / desktop environment echo "[VNC] Starting ${DESKTOP}..." case "$DESKTOP" in xfce|xfce4) + # Run XFCE setup script if exists (for Yao branding) + if [ -x /usr/local/bin/setup-xfce.sh ]; then + echo "[VNC] Running XFCE setup..." + /usr/local/bin/setup-xfce.sh || true + fi # XFCE desktop environment startxfce4 & ;; fluxbox) + # Run Fluxbox setup script if exists (Yao branding, disable toolbar) + if [ -x /usr/local/bin/setup-fluxbox.sh ]; then + echo "[VNC] Running Fluxbox setup..." + /usr/local/bin/setup-fluxbox.sh || true + fi # Minimal window manager for Playwright fluxbox & + sleep 1 + # Set wallpaper with feh if available (for Yao branding) + WALLPAPER="$HOME/.local/share/wallpapers/yao-wallpaper.png" + if [ -f "$WALLPAPER" ] && command -v feh &> /dev/null; then + echo "[VNC] Setting wallpaper..." + feh --bg-center "$WALLPAPER" || true + fi ;; *) # Default to fluxbox + if [ -x /usr/local/bin/setup-fluxbox.sh ]; then + /usr/local/bin/setup-fluxbox.sh || true + fi fluxbox & + sleep 1 + # Set wallpaper with feh if available + WALLPAPER="$HOME/.local/share/wallpapers/yao-wallpaper.png" + if [ -f "$WALLPAPER" ] && command -v feh &> /dev/null; then + feh --bg-center "$WALLPAPER" || true + fi ;; esac sleep 2