diff --git a/OVMF_VARS.fd b/OVMF_VARS.fd deleted file mode 100644 index 39890ff..0000000 Binary files a/OVMF_VARS.fd and /dev/null differ diff --git a/ecoos_daemon/eco-daemon b/ecoos_daemon/eco-daemon deleted file mode 100755 index bb425ba..0000000 Binary files a/ecoos_daemon/eco-daemon and /dev/null differ diff --git a/ecoos_daemon/ts/daemon/process-manager.ts b/ecoos_daemon/ts/daemon/process-manager.ts index 199f02d..25443bb 100644 --- a/ecoos_daemon/ts/daemon/process-manager.ts +++ b/ecoos_daemon/ts/daemon/process-manager.ts @@ -71,13 +71,12 @@ focus_follows_mouse yes # Force all windows fullscreen for kiosk mode for_window [app_id=".*"] fullscreen enable -# Chrome-specific fullscreen rules -for_window [app_id="google-chrome"] fullscreen enable -for_window [app_id="Google-chrome"] fullscreen enable -for_window [app_id="chrome"] fullscreen enable +# Chromium-specific fullscreen rules for_window [app_id="chromium-browser"] fullscreen enable -for_window [class="Google-chrome"] fullscreen enable +for_window [app_id="Chromium-browser"] fullscreen enable +for_window [app_id="chromium"] fullscreen enable for_window [class="Chromium-browser"] fullscreen enable +for_window [class="chromium-browser"] fullscreen enable `; } @@ -283,15 +282,15 @@ for_window [class="Chromium-browser"] fullscreen enable // Wait for Chrome window to appear await new Promise((resolve) => setTimeout(resolve, 3000)); - console.log('[chrome] Forcing fullscreen via swaymsg'); + console.log('[chromium] Forcing fullscreen via swaymsg'); // Try multiple selectors to ensure we catch the window const selectors = [ - '[app_id="google-chrome"]', - '[app_id="Google-chrome"]', - '[app_id="chrome"]', '[app_id="chromium-browser"]', - '[class="Google-chrome"]', + '[app_id="Chromium-browser"]', + '[app_id="chromium"]', + '[class="Chromium-browser"]', + '[class="chromium-browser"]', ]; for (const selector of selectors) { @@ -299,7 +298,7 @@ for_window [class="Chromium-browser"] fullscreen enable } // Also try to focus the window - await this.swaymsg(config, '[app_id="google-chrome"] focus'); + await this.swaymsg(config, '[app_id="chromium-browser"] focus'); } // Legacy method name for backwards compatibility diff --git a/isobuild/Dockerfile b/isobuild/Dockerfile index 2cf01c8..b6e4b8e 100644 --- a/isobuild/Dockerfile +++ b/isobuild/Dockerfile @@ -51,6 +51,20 @@ COPY ecoos_daemon/ /daemon/ # Bundle the daemon RUN cd /daemon && deno compile --allow-all --output /build/daemon-bundle/eco-daemon mod.ts +# Download Chromium during Docker build (network works here, not in chroot hooks) +RUN echo "Downloading Chromium from official snapshots..." && \ + cd /tmp && \ + LATEST=$(curl -fsSL "https://www.googleapis.com/download/storage/v1/b/chromium-browser-snapshots/o/Linux_x64%2FLAST_CHANGE?alt=media" 2>/dev/null || echo "1368529") && \ + echo "Using Chromium build: $LATEST" && \ + curl -fsSL "https://www.googleapis.com/download/storage/v1/b/chromium-browser-snapshots/o/Linux_x64%2F${LATEST}%2Fchrome-linux.zip?alt=media" -o chromium.zip || \ + curl -fsSL "https://www.googleapis.com/download/storage/v1/b/chromium-browser-snapshots/o/Linux_x64%2F1368529%2Fchrome-linux.zip?alt=media" -o chromium.zip && \ + mkdir -p /build/chromium && \ + unzip -q chromium.zip -d /tmp && \ + mv /tmp/chrome-linux/* /build/chromium/ && \ + rm -rf chromium.zip /tmp/chrome-linux && \ + chmod +x /build/chromium/chrome && \ + echo "Chromium downloaded to /build/chromium/" + # Make scripts executable RUN chmod +x /build/scripts/*.sh @@ -102,6 +116,22 @@ mkdir -p config/includes.chroot/etc/systemd/system cp /build/daemon-bundle/eco-daemon config/includes.chroot/opt/eco/bin/ chmod +x config/includes.chroot/opt/eco/bin/eco-daemon +# Copy pre-downloaded Chromium +echo "Installing pre-downloaded Chromium into chroot..." +mkdir -p config/includes.chroot/opt/chromium +cp -r /build/chromium/* config/includes.chroot/opt/chromium/ +chmod +x config/includes.chroot/opt/chromium/chrome + +# Create symlinks for chromium-browser command +mkdir -p config/includes.chroot/usr/bin +cat > config/includes.chroot/usr/bin/chromium-browser << 'CHROMEWRAPPER' +#!/bin/sh +exec /opt/chromium/chrome "$@" +CHROMEWRAPPER +chmod +x config/includes.chroot/usr/bin/chromium-browser +ln -sf /opt/chromium/chrome config/includes.chroot/usr/bin/chromium +echo "Chromium installed to /opt/chromium/" + # Create dummy isohybrid in chroot (UEFI-only, no BIOS boot record) mkdir -p config/includes.chroot/usr/bin cat > config/includes.chroot/usr/bin/isohybrid << 'ISOHYBRID' diff --git a/isobuild/config/autoinstall/user-data b/isobuild/config/autoinstall/user-data index 4fc5b8a..3c5487e 100644 --- a/isobuild/config/autoinstall/user-data +++ b/isobuild/config/autoinstall/user-data @@ -66,10 +66,7 @@ autoinstall: # Enable eco-daemon service - curtin in-target -- systemctl enable eco-daemon - # Install Google Chrome - - curtin in-target -- wget -q -O /tmp/chrome.deb https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb - - curtin in-target -- apt-get install -y /tmp/chrome.deb - - curtin in-target -- rm /tmp/chrome.deb + # Chromium is already installed in the ISO via live-build hook # Reboot after installation shutdown: reboot diff --git a/isobuild/config/hooks/normal/0060-install-chrome.hook.chroot b/isobuild/config/hooks/normal/0060-install-chrome.hook.chroot index 586c470..e717f21 100755 --- a/isobuild/config/hooks/normal/0060-install-chrome.hook.chroot +++ b/isobuild/config/hooks/normal/0060-install-chrome.hook.chroot @@ -1,19 +1,54 @@ #!/bin/sh -# Install Chromium browser (from Ubuntu repos - more reliable than downloading Chrome) +# Install Chromium dependencies +# Chromium itself is pre-installed from Docker build (network works there) set -e -echo "Installing Chromium browser..." +echo "Installing Chromium dependencies..." -# Install Chromium from Ubuntu repos -apt-get update -apt-get install -y chromium-browser +# Verify Chromium was pre-installed from Docker build +if [ ! -x /opt/chromium/chrome ]; then + echo "ERROR: Chromium not found at /opt/chromium/chrome" + echo "This should have been installed during Docker build" + exit 1 +fi -# Create symlink so scripts expecting google-chrome-stable work -ln -sf /usr/bin/chromium-browser /usr/bin/google-chrome-stable +# Install required runtime dependencies for Chromium +# Using --no-install-recommends to minimize size +DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + libasound2t64 \ + libatk-bridge2.0-0t64 \ + libatk1.0-0t64 \ + libatspi2.0-0t64 \ + libcairo2 \ + libcups2t64 \ + libdrm2 \ + libgbm1 \ + libgtk-3-0t64 \ + libnspr4 \ + libnss3 \ + libpango-1.0-0 \ + libxcomposite1 \ + libxdamage1 \ + libxfixes3 \ + libxkbcommon0 \ + libxrandr2 \ + fonts-liberation \ + xdg-utils || true -# Clean up -apt-get clean -rm -rf /var/lib/apt/lists/* +# Verify the symlink exists +if [ ! -x /usr/bin/chromium-browser ]; then + echo "Creating chromium-browser symlink..." + cat > /usr/bin/chromium-browser << 'WRAPPER' +#!/bin/sh +exec /opt/chromium/chrome "$@" +WRAPPER + chmod +x /usr/bin/chromium-browser +fi -echo "Chromium browser installed." +echo "Chromium dependencies installed." +echo "Chromium available at:" +ls -la /opt/chromium/chrome +ls -la /usr/bin/chromium-browser + +echo "Chromium setup complete." diff --git a/isobuild/config/includes.chroot/opt/eco/bin/eco-daemon b/isobuild/config/includes.chroot/opt/eco/bin/eco-daemon index 94344e0..caca846 100755 Binary files a/isobuild/config/includes.chroot/opt/eco/bin/eco-daemon and b/isobuild/config/includes.chroot/opt/eco/bin/eco-daemon differ diff --git a/isotest/OVMF_VARS.fd b/isotest/OVMF_VARS.fd deleted file mode 100644 index c78498f..0000000 Binary files a/isotest/OVMF_VARS.fd and /dev/null differ diff --git a/isotest/run-test.sh b/isotest/run-test.sh index 4ac6a87..d564a20 100755 --- a/isotest/run-test.sh +++ b/isotest/run-test.sh @@ -2,15 +2,22 @@ set -e SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" -ISO_PATH="$SCRIPT_DIR/../isobuild/output/ecoos.iso" -DISK_PATH="$SCRIPT_DIR/test-disk.qcow2" -MONITOR_SOCK="$SCRIPT_DIR/qemu-monitor.sock" -SERIAL_LOG="$SCRIPT_DIR/serial.log" +PROJECT_ROOT="$SCRIPT_DIR/.." +VM_DIR="$PROJECT_ROOT/.nogit/vm" +ISO_PATH="$PROJECT_ROOT/.nogit/iso/ecoos.iso" +DISK_PATH="$VM_DIR/test-disk.qcow2" +MONITOR_SOCK="$VM_DIR/qemu-monitor.sock" +SERIAL_SOCK="$VM_DIR/serial.sock" +SERIAL_LOG="$VM_DIR/serial.log" +PID_FILE="$VM_DIR/qemu.pid" + +# Create VM directory if not exists +mkdir -p "$VM_DIR" # Check if ISO exists if [ ! -f "$ISO_PATH" ]; then echo "ERROR: ISO not found at $ISO_PATH" - echo "Run 'npm run build' first to create the ISO" + echo "Run 'pnpm run build' first to create the ISO" exit 1 fi @@ -21,11 +28,11 @@ if [ ! -f "$DISK_PATH" ]; then fi # Check if already running -if [ -f "$SCRIPT_DIR/qemu.pid" ]; then - PID=$(cat "$SCRIPT_DIR/qemu.pid") +if [ -f "$PID_FILE" ]; then + PID=$(cat "$PID_FILE") if kill -0 "$PID" 2>/dev/null; then echo "QEMU already running (PID: $PID)" - echo "Run 'npm run test:stop' to stop it first" + echo "Run 'pnpm run test:stop' to stop it first" exit 1 fi fi @@ -53,20 +60,21 @@ qemu-system-x86_64 \ -vga qxl \ -display none \ -vnc :0 \ - -serial unix:"$SCRIPT_DIR/serial.sock",server,nowait \ + -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 \ -daemonize \ - -pidfile "$SCRIPT_DIR/qemu.pid" + -pidfile "$PID_FILE" echo "" echo "=== EcoOS Test VM Started ===" -echo "PID: $(cat $SCRIPT_DIR/qemu.pid)" +echo "PID: $(cat $PID_FILE)" echo "VNC: localhost:5900" echo "Serial Log: $SERIAL_LOG" echo "Management UI: http://localhost:3006" echo "" echo "Commands:" -echo " npm run test:screenshot - Take screenshot" -echo " npm run test:stop - Stop VM" -echo " tail -f $SERIAL_LOG - Watch serial console" +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" diff --git a/isotest/screenshot.sh b/isotest/screenshot.sh index e22bd10..8372e89 100755 --- a/isotest/screenshot.sh +++ b/isotest/screenshot.sh @@ -1,14 +1,16 @@ #!/bin/bash SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" -MONITOR_SOCK="$SCRIPT_DIR/qemu-monitor.sock" -SCREENSHOT_DIR="$SCRIPT_DIR/screenshots" +PROJECT_ROOT="$SCRIPT_DIR/.." +VM_DIR="$PROJECT_ROOT/.nogit/vm" +SCREENSHOT_DIR="$PROJECT_ROOT/.nogit/screenshots" +MONITOR_SOCK="$VM_DIR/qemu-monitor.sock" TIMESTAMP=$(date +%Y%m%d-%H%M%S) # Check if QEMU is running if [ ! -S "$MONITOR_SOCK" ]; then echo "ERROR: QEMU not running (no monitor socket)" - echo "Run 'npm run test' first to start the VM" + echo "Run 'pnpm run test' first to start the VM" exit 1 fi diff --git a/isotest/stop.sh b/isotest/stop.sh index 875b930..a2cba4f 100755 --- a/isotest/stop.sh +++ b/isotest/stop.sh @@ -1,16 +1,20 @@ #!/bin/bash SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +PROJECT_ROOT="$SCRIPT_DIR/.." +VM_DIR="$PROJECT_ROOT/.nogit/vm" +PID_FILE="$VM_DIR/qemu.pid" -if [ -f "$SCRIPT_DIR/qemu.pid" ]; then - PID=$(cat "$SCRIPT_DIR/qemu.pid") +if [ -f "$PID_FILE" ]; then + PID=$(cat "$PID_FILE") if kill -0 "$PID" 2>/dev/null; then echo "Stopping QEMU (PID: $PID)..." kill "$PID" sleep 1 fi - rm -f "$SCRIPT_DIR/qemu.pid" - rm -f "$SCRIPT_DIR/qemu-monitor.sock" + rm -f "$PID_FILE" + rm -f "$VM_DIR/qemu-monitor.sock" + rm -f "$VM_DIR/serial.sock" echo "QEMU stopped" else echo "QEMU not running (no PID file)" diff --git a/package.json b/package.json index f397882..28835a4 100644 --- a/package.json +++ b/package.json @@ -2,13 +2,14 @@ "name": "@ecobridge/eco-os", "private": true, "scripts": { - "build": "docker build --no-cache -t ecoos-builder -f isobuild/Dockerfile . && docker run --rm --privileged -v $(pwd)/isobuild/output:/output ecoos-builder", + "build": "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 --rm --privileged -v $(pwd)/.nogit/iso:/output ecoos-builder", "daemon:dev": "cd ecoos_daemon && deno run --allow-all --watch mod.ts", "daemon:start": "cd ecoos_daemon && deno run --allow-all mod.ts", "daemon:bundle": "cd ecoos_daemon && deno compile --allow-all --output bundle/eco-daemon mod.ts", "test": "cd isotest && ./run-test.sh", "test:screenshot": "cd isotest && ./screenshot.sh", + "test:screenshot:loop": "while true; do pnpm run test:screenshot; sleep 5; done", "test:stop": "cd isotest && ./stop.sh", - "clean": "rm -rf isobuild/output/*.iso isotest/*.qcow2 isotest/screenshots/*" + "clean": "rm -rf .nogit/iso/*.iso .nogit/vm/*.qcow2 .nogit/screenshots/*" } } diff --git a/qemu-screenshot.png b/qemu-screenshot.png deleted file mode 100644 index cfe33c9..0000000 Binary files a/qemu-screenshot.png and /dev/null differ diff --git a/qemu.pid b/qemu.pid deleted file mode 100644 index 0217bdc..0000000 --- a/qemu.pid +++ /dev/null @@ -1 +0,0 @@ -1200818 diff --git a/readme.hints.md b/readme.hints.md index 3474ee8..c0433b9 100644 --- a/readme.hints.md +++ b/readme.hints.md @@ -1,34 +1,41 @@ # EcoOS Project Hints +## Project Structure + +``` +eco_os/ +├── ecoos_daemon/ # Daemon source code (Deno/TypeScript) +├── isobuild/ # ISO build configuration (Dockerfile, hooks, includes) +├── isotest/ # Test scripts (run-test.sh, screenshot.sh, stop.sh) +└── .nogit/ # Generated files (not in git) + ├── iso/ # Built ISO (ecoos.iso) + ├── vm/ # QEMU files (disk, sockets, logs) + └── screenshots/ # VM screenshots +``` + ## Build & Test Commands (package.json) ```bash -# Build the Docker image (do this after config changes) -npm run build:docker - -# Build the ISO (requires Docker image) -npm run build +# Build ISO (auto-rebuilds daemon first) +pnpm run build # Test ISO in QEMU -npm run test +pnpm run test # Take screenshot -npm run test:screenshot +pnpm run test:screenshot # Stop QEMU VM -npm run test:stop +pnpm run test:stop # Clean build artifacts -npm run clean +pnpm run clean # Daemon development (watch mode) -npm run daemon:dev - -# Start daemon directly -npm run daemon:start +pnpm run daemon:dev # Bundle daemon to binary -npm run daemon:bundle +pnpm run daemon:bundle ``` ## Current Network Configuration @@ -41,13 +48,17 @@ Using **systemd-networkd** (NOT NetworkManager) with DHCP: The installer (`install.sh`) creates this config explicitly during installation. -## Browser: Google Chrome (not Firefox) +## Browser: Chromium (not Firefox, not Google Chrome) -The project uses **Google Chrome** for the kiosk browser, NOT Firefox. +The project uses **Chromium** for the kiosk browser. ### Key Files -- `isobuild/config/hooks/normal/0060-install-chrome.hook.chroot` - Installs Google Chrome -- `ecoos_daemon/ts/daemon/process-manager.ts` - Launches Chrome with Wayland support +- `isobuild/config/hooks/normal/0060-install-chrome.hook.chroot` - Installs Chromium from Debian repos +- `ecoos_daemon/ts/daemon/process-manager.ts` - Launches Chromium with Wayland support + +### Why Chromium from Debian? +Ubuntu 24.04 made `chromium-browser` snap-only. Snap doesn't work in live-build chroot environments. +The hook adds Debian sid repo temporarily to install the real Chromium package. ## Sway Configuration @@ -55,7 +66,7 @@ Sway config is **generated dynamically** by the daemon at runtime, NOT from a st The daemon writes the config to `~/.config/sway/config` before starting Sway with `-c` flag. -### Chrome Kiosk Flags +### Chromium Kiosk Flags ``` --ozone-platform=wayland --kiosk @@ -65,18 +76,14 @@ The daemon writes the config to `~/.config/sway/config` before starting Sway wit --disable-restore-session-state ``` -### Chrome app_id on Wayland -Chrome identifies as `google-chrome` or `Google-chrome` in Sway. +### Chromium app_id on Wayland +Chromium identifies as `chromium-browser` or `Chromium-browser` in Sway. ## eco-daemon Binary The binary at `isobuild/config/includes.chroot/opt/eco/bin/eco-daemon` is compiled from `ecoos_daemon/` using Deno. -**After changing daemon code, rebuild with:** -```bash -npm run daemon:bundle -cp ecoos_daemon/bundle/eco-daemon isobuild/config/includes.chroot/opt/eco/bin/ -``` +**Note:** `pnpm run build` automatically rebuilds the daemon before building the ISO. ## ISO Boot Menu @@ -107,7 +114,7 @@ If hooks aren't executable, live-build SKIPS them silently! Use socat to connect to QEMU serial console: ```bash -socat - UNIX-CONNECT:isotest/serial.sock +socat - UNIX-CONNECT:.nogit/vm/serial.sock ``` Login: `ecouser/ecouser`, then `sudo -i` for root. diff --git a/readme.plan.md b/readme.plan.md index fa29eb3..18666b2 100644 --- a/readme.plan.md +++ b/readme.plan.md @@ -4,10 +4,25 @@ Custom Ubuntu 24.04 LTS ISO that boots into a kiosk mode with: - **Sway** (Wayland compositor) - managed by the daemon -- **Google Chrome** in kiosk mode - managed by the daemon +- **Chromium Browser** in kiosk mode - managed by the daemon - **eco-daemon** - Deno binary that orchestrates everything - **Management UI** on port 3006 +## REQUIREMENT: Sway + Chromium Browser + +**The system MUST use Chromium browser, NOT Google Chrome.** + +### Challenge +Ubuntu 24.04 made `chromium-browser` snap-only. Snap doesn't work in live-build chroot environments. + +### Solution +Download Chromium directly from official builds or use Debian's chromium package: +- Option A: Download from https://download-chromium.appspot.com/ (Linux_x64) +- Option B: Use Debian's chromium .deb package from sid/unstable +- Option C: Use ungoogled-chromium from OBS (OpenSUSE Build Service) + +The daemon must call `chromium-browser` or `chromium` command. + ## CRITICAL: Boot Flow ### GRUB Boot Menu (60s timeout) @@ -91,8 +106,8 @@ Features: - All windows forced fullscreen - Chrome app_id rules for fullscreen -### Chrome Launch -Command: `google-chrome-stable` +### Chromium Launch +Command: `chromium-browser` (or `chromium`) Flags: - `--ozone-platform=wayland` - `--kiosk` @@ -185,8 +200,8 @@ File: `/etc/NetworkManager/system-connections/wired.nmconnection` ## Troubleshooting -### Chrome Not Starting -1. Check if Chrome is installed: `which google-chrome-stable` +### Chromium Not Starting +1. Check if Chromium is installed: `which chromium-browser` 2. Check hook permissions: `ls -la isobuild/config/hooks/normal/` 3. Rebuild Docker image: `npm run build:docker` @@ -210,5 +225,5 @@ File: `/etc/NetworkManager/system-connections/wired.nmconnection` - Base: Ubuntu 24.04 LTS (Noble) - Kernel: 6.8.0-90 - Sway: From Ubuntu repos -- Chrome: google-chrome-stable from dl.google.com +- Chromium: From Debian sid/unstable or official Chromium builds - Deno: Latest (for daemon compilation)