From c8ab9afbc6396b4c670b9cfdd3e9c1544a30f6d1 Mon Sep 17 00:00:00 2001 From: Juergen Kunz Date: Fri, 9 Jan 2026 19:39:14 +0000 Subject: [PATCH] update --- ecoos_daemon/ts/daemon/process-manager.ts | 12 ++- ecoos_daemon/ts/version.ts | 2 +- .../includes.chroot/opt/eco/bin/eco-daemon | Bin 87002180 -> 87003557 bytes isotest/run-test.sh | 99 +++++++++++++++--- isotest/screenshot.sh | 78 ++++++-------- package.json | 2 +- 6 files changed, 127 insertions(+), 66 deletions(-) diff --git a/ecoos_daemon/ts/daemon/process-manager.ts b/ecoos_daemon/ts/daemon/process-manager.ts index a7d3b1a..2151442 100644 --- a/ecoos_daemon/ts/daemon/process-manager.ts +++ b/ecoos_daemon/ts/daemon/process-manager.ts @@ -417,9 +417,15 @@ for_window [app_id="chromium-browser"] fullscreen enable name: string, enabled: boolean ): Promise { - const command = `output ${name} ${enabled ? 'enable' : 'disable'}`; - console.log(`[displays] ${command}`); - return this.swaymsg(config, command); + if (enabled) { + console.log(`[displays] Enabling ${name}`); + // First try to set resolution, then enable + await this.swaymsg(config, `output ${name} resolution 1920x1080`); + return this.swaymsg(config, `output ${name} enable`); + } else { + console.log(`[displays] Disabling ${name}`); + return this.swaymsg(config, `output ${name} disable`); + } } /** diff --git a/ecoos_daemon/ts/version.ts b/ecoos_daemon/ts/version.ts index 2391cca..86305df 100644 --- a/ecoos_daemon/ts/version.ts +++ b/ecoos_daemon/ts/version.ts @@ -1 +1 @@ -export const VERSION = "0.4.2"; +export const VERSION = "0.4.4"; diff --git a/isobuild/config/includes.chroot/opt/eco/bin/eco-daemon b/isobuild/config/includes.chroot/opt/eco/bin/eco-daemon index dba7ed29b745bd1dcf2c5fd5b59e58d08a5255ec..2bf08b83d84bbf5e4aa12b8307774cfaa6d825bd 100755 GIT binary patch delta 5508 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 N9&yB>t?80}{{c$zCba+n diff --git a/isotest/run-test.sh b/isotest/run-test.sh index 36bc04f..afc2cd2 100755 --- a/isotest/run-test.sh +++ b/isotest/run-test.sh @@ -48,7 +48,25 @@ else echo "KVM not available, using software emulation (slower)" fi -# Start QEMU with multiple displays (3 total) for multi-monitor testing +# Cleanup function +cleanup() { + echo "" + echo "Shutting down..." + if [ -n "$VIEWER_PID" ] && kill -0 "$VIEWER_PID" 2>/dev/null; then + kill "$VIEWER_PID" 2>/dev/null || true + fi + if [ -f "$PID_FILE" ]; then + PID=$(cat "$PID_FILE") + if kill -0 "$PID" 2>/dev/null; then + kill "$PID" 2>/dev/null || true + fi + rm -f "$PID_FILE" + fi + echo "Done" +} +trap cleanup EXIT INT TERM + +# Start QEMU with virtio-gpu multi-head (3 outputs) > "$SERIAL_LOG" # Clear old log qemu-system-x86_64 \ $KVM_OPTS \ @@ -57,26 +75,81 @@ qemu-system-x86_64 \ -bios /usr/share/qemu/OVMF.fd \ -drive file="$ISO_PATH",media=cdrom \ -drive file="$DISK_PATH",format=qcow2,if=virtio \ - -device virtio-gpu-pci,id=video0 \ - -device virtio-gpu-pci,id=video1 \ - -device virtio-gpu-pci,id=video2 \ + -device virtio-vga,max_outputs=3 \ -display none \ -spice port=5930,disable-ticketing=on \ + -device virtio-serial-pci \ + -chardev spicevmc,id=vdagent,name=vdagent \ + -device virtserialport,chardev=vdagent,name=com.redhat.spice.0 \ -serial unix:"$SERIAL_SOCK",server,nowait \ -monitor unix:"$MONITOR_SOCK",server,nowait \ -nic user,model=virtio-net-pci,hostfwd=tcp::3006-:3006,hostfwd=tcp::2222-:22 \ -pidfile "$PID_FILE" & +QEMU_PID=$! + echo "" -sleep 1 echo "=== EcoOS Test VM Started ===" -echo "PID: $(cat $PID_FILE 2>/dev/null || echo 'running')" -echo "SPICE: spicy -h localhost -p 5930" -echo "Serial Log: $SERIAL_LOG" +echo "QEMU PID: $QEMU_PID" echo "Management UI: http://localhost:3006" echo "" -echo "Commands:" -echo " pnpm run test:screenshot - Take screenshot" -echo " pnpm run test:stop - Stop VM" -echo " tail -f $SERIAL_LOG - Watch serial console" -echo " socat - UNIX-CONNECT:$SERIAL_SOCK - Interactive serial" + +# Wait for QEMU to start and SPICE to be ready +echo "Waiting for SPICE server..." +sleep 3 + +# Check if remote-viewer is available +if ! command -v remote-viewer &> /dev/null; then + echo "WARNING: remote-viewer not installed" + echo "Install with: sudo apt install virt-viewer" + echo "" + echo "Running without display viewer. Press Ctrl-C to stop." + wait $QEMU_PID + exit 0 +fi + +# Detect DISPLAY if not set +if [ -z "$DISPLAY" ]; then + # Try to find an active X display + if [ -S /tmp/.X11-unix/X0 ]; then + export DISPLAY=:0 + elif [ -S /tmp/.X11-unix/X1 ]; then + export DISPLAY=:1 + fi +fi + +# Detect WAYLAND_DISPLAY if not set +if [ -z "$WAYLAND_DISPLAY" ] && [ -z "$DISPLAY" ]; then + # Try common Wayland sockets + if [ -S "$XDG_RUNTIME_DIR/wayland-0" ]; then + export WAYLAND_DISPLAY=wayland-0 + elif [ -S "/run/user/$(id -u)/wayland-0" ]; then + export XDG_RUNTIME_DIR="/run/user/$(id -u)" + export WAYLAND_DISPLAY=wayland-0 + fi +fi + +# Launch remote-viewer - use Xvfb if no display available +if [ -z "$DISPLAY" ] && [ -z "$WAYLAND_DISPLAY" ]; then + echo "No display found, using Xvfb for headless SPICE client..." + # Use Xvfb with large virtual screen to support 3 monitors (5760x1080 = 3x1920x1080) + xvfb-run -a -s "-screen 0 5760x1080x24" remote-viewer spice://localhost:5930 & + VIEWER_PID=$! + echo "remote-viewer running headlessly under Xvfb (PID: $VIEWER_PID)" +else + echo "Launching remote-viewer (DISPLAY=$DISPLAY, WAYLAND_DISPLAY=$WAYLAND_DISPLAY)..." + remote-viewer spice://localhost:5930 & + VIEWER_PID=$! +fi +echo "" + +echo "=== Press Ctrl-C to stop ===" +echo "" +echo "Tips:" +echo " - View > Displays > Enable Display 2/3 for multi-monitor" +echo " - pnpm run test:screenshot - Take screenshot" +echo " - http://localhost:3006 - Management UI" +echo "" + +# Wait for either process to exit +wait $QEMU_PID 2>/dev/null || true diff --git a/isotest/screenshot.sh b/isotest/screenshot.sh index 9cdefda..940f365 100755 --- a/isotest/screenshot.sh +++ b/isotest/screenshot.sh @@ -4,6 +4,7 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" PROJECT_ROOT="$SCRIPT_DIR/.." VM_DIR="$PROJECT_ROOT/.nogit/vm" SCREENSHOT_DIR="$PROJECT_ROOT/.nogit/screenshots" +TIMESTAMPED_DIR="$SCREENSHOT_DIR/timestamped" MONITOR_SOCK="$VM_DIR/qemu-monitor.sock" TIMESTAMP=$(date +%Y%m%d-%H%M%S) @@ -15,57 +16,38 @@ if [ ! -S "$MONITOR_SOCK" ]; then fi mkdir -p "$SCREENSHOT_DIR" +mkdir -p "$TIMESTAMPED_DIR" -# Screenshot all displays (video0, video1, video2) -DISPLAYS="video0 video1 video2" -SCREENSHOTS=() +echo "Taking screenshot..." -echo "Taking screenshots of all displays..." +PPM_FILE="$SCREENSHOT_DIR/temp.ppm" +LATEST_FILE="$SCREENSHOT_DIR/latest.png" +TIMESTAMPED_FILE="$TIMESTAMPED_DIR/ecoos-$TIMESTAMP.png" -for DISPLAY in $DISPLAYS; do - PPM_FILE="$SCREENSHOT_DIR/ecoos-$TIMESTAMP-$DISPLAY.ppm" - PNG_FILE="$SCREENSHOT_DIR/ecoos-$TIMESTAMP-$DISPLAY.png" +# Take screenshot (virtio-vga captures all outputs in one framebuffer) +echo "screendump $PPM_FILE" | socat - UNIX-CONNECT:"$MONITOR_SOCK" > /dev/null 2>&1 +sleep 0.5 - # Take screenshot of this display - echo "screendump $PPM_FILE $DISPLAY" | socat - UNIX-CONNECT:"$MONITOR_SOCK" 2>/dev/null - sleep 0.5 - - if [ -f "$PPM_FILE" ]; then - # Convert to PNG if imagemagick is available - if command -v convert &> /dev/null; then - convert "$PPM_FILE" "$PNG_FILE" - rm "$PPM_FILE" - SCREENSHOTS+=("$PNG_FILE") - echo " $DISPLAY: $PNG_FILE" - else - SCREENSHOTS+=("$PPM_FILE") - echo " $DISPLAY: $PPM_FILE" - fi - else - echo " $DISPLAY: (no output or not connected)" - fi -done - -# Create a combined image if we have multiple screenshots and imagemagick -if command -v convert &> /dev/null && [ ${#SCREENSHOTS[@]} -gt 1 ]; then - COMBINED_FILE="$SCREENSHOT_DIR/ecoos-$TIMESTAMP-combined.png" - LATEST_FILE="$SCREENSHOT_DIR/latest.png" - - # Combine images horizontally - convert "${SCREENSHOTS[@]}" +append "$COMBINED_FILE" - cp "$COMBINED_FILE" "$LATEST_FILE" - - echo "" - echo "Combined screenshot: $COMBINED_FILE" - echo "Also saved as: $LATEST_FILE" -elif [ ${#SCREENSHOTS[@]} -eq 1 ]; then - LATEST_FILE="$SCREENSHOT_DIR/latest.png" - cp "${SCREENSHOTS[0]}" "$LATEST_FILE" - echo "" - echo "Also saved as: $LATEST_FILE" +if [ ! -f "$PPM_FILE" ]; then + echo "ERROR: Failed to capture screenshot" + exit 1 fi -# Keep only last 20 screenshot sets (excluding latest.png) -cd "$SCREENSHOT_DIR" -ls -t ecoos-*-combined.png 2>/dev/null | tail -n +21 | xargs -r rm -f -ls -t ecoos-*-video*.png 2>/dev/null | tail -n +61 | xargs -r rm -f +# Convert to PNG +if command -v convert &> /dev/null; then + convert "$PPM_FILE" "$LATEST_FILE" + cp "$LATEST_FILE" "$TIMESTAMPED_FILE" + rm "$PPM_FILE" + echo "Screenshot saved: $LATEST_FILE" + echo "Timestamped copy: $TIMESTAMPED_FILE" +else + mv "$PPM_FILE" "$SCREENSHOT_DIR/latest.ppm" + cp "$SCREENSHOT_DIR/latest.ppm" "$TIMESTAMPED_DIR/ecoos-$TIMESTAMP.ppm" + echo "Screenshot saved: $SCREENSHOT_DIR/latest.ppm" + echo "(Install ImageMagick for PNG conversion)" +fi + +# Keep only last 50 timestamped screenshots +cd "$TIMESTAMPED_DIR" +ls -t ecoos-*.png 2>/dev/null | tail -n +51 | xargs -r rm -f +ls -t ecoos-*.ppm 2>/dev/null | tail -n +51 | xargs -r rm -f diff --git a/package.json b/package.json index 437b45e..e61a8bb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@ecobridge/eco-os", - "version": "0.4.2", + "version": "0.4.4", "private": true, "scripts": { "build": "[ -z \"$CI\" ] && npm version patch --no-git-tag-version || true && node -e \"const v=require('./package.json').version; require('fs').writeFileSync('ecoos_daemon/ts/version.ts', 'export const VERSION = \\\"'+v+'\\\";\\n');\" && pnpm run daemon:bundle && cp ecoos_daemon/bundle/eco-daemon isobuild/config/includes.chroot/opt/eco/bin/ && mkdir -p .nogit/iso && docker build --no-cache -t ecoos-builder -f isobuild/Dockerfile . && docker run --privileged --name ecoos-build ecoos-builder && docker cp ecoos-build:/output/ecoos.iso .nogit/iso/ecoos.iso && docker rm ecoos-build",