120 Commits

Author SHA1 Message Date
Dorian
b8a09b448b fix: AIUI /aiui/ base path, nginx alias cycle, VPN auth, container boot
- AIUI: rebuild with /aiui/ base path (router, chunk loader, SW scope)
- nginx: remove alias from /aiui/ location (caused try_files redirect cycle)
- VPN: WireGuard standalone setup, auth improvements
- ISO: build script hardening, service file updates
- first-boot-containers: networking stack fixes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 20:42:09 +02:00
Dorian
a8c6a36cd1 fix: netavark GLIBC mismatch in ISO, container adopt, app updates
ISO build no longer copies netavark from build host (Debian 13/GLIBC 2.41)
which broke container networking on Debian 12 targets. Rootfs already
installs netavark from Debian 12 repos — just configure the backend.

Install RPC now adopts existing containers (from first-boot) instead of
erroring on duplicates. Container scanner extracts real versions from
image tags and detects available updates against pinned versions.

Frontend shows update button with version info when updates are available.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 11:47:35 +02:00
Dorian
b30f41f3d7 feat: standalone WireGuard from first install, fix networking stack
Standalone WireGuard (wg0:51820):
- New archipelago-wg.service creates wg0 independent of NostrVPN
- Keypair generated on first-boot, persisted on LUKS partition
- vpn.create-peer uses wg genkey/pubkey (no nvpn dependency)
- wg-address service depends on archipelago-wg, not nostr-vpn

Networking fixes:
- Remove nos.lol from default relays (requires PoW, events rejected)
- Add Tor hidden service for private relay (port 7777) — NAT'd peers
  can reach relay over Tor for NostrVPN signaling
- Fix Tor hostname sync race: wait loop before copying hostname files
- Add tor-hostnames + wireguard dirs to LUKS partition setup
- Include relay in hostname sync loops (setup-tor.sh + first-boot)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 20:27:38 +02:00
Dorian
ef69434364 fix: reboot/shutdown commands work without sudo prefix
polkit denies reboot/shutdown for non-root users without a local seat
(e.g. SSH sessions). Since archipelago has NOPASSWD sudo, add shell
aliases so reboot/shutdown/halt/poweroff transparently use sudo.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 17:51:21 +02:00
Dorian
3ee5dd6715 fix: nostr-vpn crash-loop on fresh install, relay config lost on LUKS
Two issues on fresh ISO install:
1. nostr-vpn.service was enabled in rootfs but env file doesn't exist
   until first-boot generates Nostr identity — crash-loop on boot.
   Now only enabled by first-boot-containers.sh after identity exists.
2. LUKS encrypted partition mounts over /var/lib/archipelago/, hiding
   the relay config.toml the Dockerfile put there. Now copies relay
   config and creates nostr-relay/nostr-vpn dirs on the LUKS partition.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 17:48:38 +02:00
Dorian
d7286d5f63 fix: expand brace globs in Dockerfile RUN — dash has no brace expansion
Dockerfile RUN steps execute under /bin/sh (dash on Debian), which
doesn't support brace expansion {a,b,c}. The nostr-relay directory
was never created, causing the config copy to fail (build #444).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 15:43:22 +02:00
Dorian
5f40cd2af4 fix: restore musl static build, brand GRUB as Archipelago
Runner is Debian 13 (glibc 2.41), ISO rootfs is Debian 12/bookworm
(glibc 2.36). Dynamic binary crashes with GLIBC_2.41 not found.
Musl static build eliminates the dependency entirely.

Also set GRUB_DISTRIBUTOR="Archipelago" so installed system boot
menu says "Archipelago" not "Debian GNU/Linux".

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 15:19:14 +02:00
Dorian
42c29b99e2 feat: ISO networking stack — relay + nvpn v0.3.7 + WireGuard
Add nostr-rs-relay as native system service (port 7777) for VPN
signaling. Every node runs its own private relay from first boot.
Update nvpn binary from v0.3.4 to v0.3.7 (fixes mesh event
processing). Add WireGuard helper and address service for peer VPN.
First-boot script configures relay, nvpn identity, relay URLs
(direct + Tor onion), and syncs daemon config.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 15:06:27 +02:00
Dorian
b0907c48b2 feat: NostrVPN mesh + VPN card UI + nvpn v0.3.7
- VPN card: relay URLs, device management, invite QR, add participant
- Backend: vpn.invite, vpn.add-participant, vpn.peer-config RPCs
- nvpn v0.3.7 system service (fixes event processing bug in v0.3.4)
- First-boot: auto-configure nvpn with node identity and endpoint
- Service: AF_NETLINK for WireGuard, NoNewPrivileges=no for sudo wg
- TASK-50: networking stack reliability from first install

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 15:00:00 +02:00
Dorian
6c1f316956 fix: revert musl build, add ACPI power-off support
- Revert CI to normal cargo build --release (musl was false positive)
- Add acpid + acpi-support-base to rootfs packages
- Add acpi=force to GRUB and ISOLINUX boot params (installer + installed)
- Fixes "Maybe missing ACPI. Shutdown not powering off" on some hardware

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 13:15:09 +02:00
Dorian
54cb23f07b feat: NostrVPN as native system service, Claude API key input, fix duplicate password
- Add NostrVPN as a native systemd service (extracted from container)
- Add VPN status detection for nostr-vpn in backend vpn.rs
- ISO build extracts nvpn binary from container image
- First-boot auto-configures NostrVPN with node's Nostr identity
- Change Claude Auth from login iframe to API key input field
- Remove duplicate ChangePasswordSection from Settings.vue
- FIPS and Routstr remain as installable container apps

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 14:40:33 +01:00
Dorian
b27b426728 fix: BUILD_VERSION from Cargo.toml, kiosk scaling, new apps, Rust warnings
Critical:
- BUILD_VERSION was hardcoded as "1.3.0-alpha" — now reads from Cargo.toml
  This caused ALL ISOs to show v1.3.0 regardless of actual binary version

Kiosk:
- Remove --disable-gpu flags (broke display scaling on some monitors)
- Add --start-fullscreen --window-size for reliable fullscreen

New apps:
- Nostr VPN, FIPS, Routstr, noStrudel, BotFights, NWNN, 484 Kitchen,
  Call the Operator, Arch Presentation, Syntropy Institute, T-0

Rust: suppress dead_code and unused_assignments warnings

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 00:35:52 +01:00
Dorian
9953a99010 fix: v1.3.3 — firmware, fedimint perms, GRUB fallback, data dirs, Rust warnings
- Add firmware-linux-nonfree to ISO (fixes missing Realtek NIC firmware)
- Pre-create nbxplorer/Main and btcpay/Main data directories
- Fix fedimint data dir permissions (chmod 775 for non-root container)
- GRUB GFX fallback: gfxpayload=keep + console fallback for incompatible hardware
- Kill stale Chromium before kiosk restart (prevents duplicate processes)
- Suppress Rust warnings: #[allow(dead_code)] on run_boot_reconciliation,
  #[allow(unused_assignments)] on history_dirty
- Version bump to 1.3.3

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 20:28:53 +01:00
Dorian
f84194d9c6 fix: AIUI proxy graceful error without API key, deploy proxy parity
Claude proxy no longer crashes when ANTHROPIC_API_KEY is not set.
Instead serves a 401 with a helpful message telling users to configure
their API key in Settings. Fixes blank AIUI on fresh installs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 18:30:34 +01:00
Dorian
843037af47 fix: onboarding persistence, clipboard, install UI, OnlyOffice removal, UI containers
Onboarding:
- Persist current step in localStorage — page refresh resumes where user was
- Router afterEach saves step; guard redirects to saved step, not always intro
- Show npub alongside DID on restore success screen

UI fixes:
- Clipboard polyfill for HTTP contexts (fixes Copy DID crash on non-HTTPS)
- AppCard installing overlay shows for pkg.state=installing (survives refresh)
- Hide uninstall button during installation
- Frontend version bumped to 1.3.2

App store:
- OnlyOffice fully removed from marketplace, curated apps, app config
- Replaced with CryptPad references throughout
- Remove OnlyOffice from ISO capture patterns

Container stability:
- UI containers (bitcoin-ui, lnd-ui, electrs-ui) pull from registry first
- Added --cap-add FOWNER for rootless Podman compatibility
- electrs-ui now included in first-boot loop alongside bitcoin-ui and lnd-ui

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 18:20:52 +01:00
Dorian
b3a6d2103a fix: container stability, OnlyOffice removal, node bootstrapping, UI fixes
Container orchestration:
- Add --network-alias to all archy-net containers (fixes Podman DNS)
- Fix bitcoin-knots health check: expand $BITCOIN_RPC_PASS at creation
- Increase bitcoin-knots memory limit to 4g, reduce dbcache to 2048
- Enable podman-restart.service in ISO for auto-start on boot
- Fix UI container Dockerfiles: ENTRYPOINT [], user root for rootless

App changes:
- Remove OnlyOffice (incompatible with rootless Podman)
- Replace with CryptPad reference (single-process, e2e encrypted)
- Fix NPM port mapping: 8181 → 81
- Fix OnlyOffice port mapping: 8044 → 9980 (now CryptPad: 3003)

AIUI & proxy:
- Add MODEL_MAP to claude-api-proxy (ISO + deploy)
- Map legacy model IDs (claude-haiku-4.5 → claude-haiku-4-5-20251001)

Kiosk:
- Move chromium-kiosk data dir to /var/lib/archipelago (data partition)
- Remove --metrics-recording-only (contradicted --disable-metrics)

Node bootstrapping:
- Add bootstrap-switchover.sh for live node updates
- ElectrumX UI improvements and nginx proxy fixes
- LND UI nginx config updates

Backend:
- Bitcoin health check uses .cookie auth (no plaintext creds)
- ElectrumX status endpoint improvements
- Network alias flag in install.rs for DNS reliability

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 16:15:04 +01:00
Dorian
5c003daafa fix: stale rootfs container cleanup, OnlyOffice/NPM port corrections
ISO build:
- Remove stale archipelago-rootfs-tmp container before creating new one
  (previous failed builds leave it behind, blocking subsequent builds)

Container ports:
- OnlyOffice: fix LAN address from 8044 to 9980 (actual mapped port)
- Nginx Proxy Manager: fix from 8181 to 81 (correct admin port)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 15:16:24 +01:00
Dorian
5456c63a08 fix: AIUI copy uses rsync to handle same-file in CI workspace
The CI build server's /opt/archipelago/web-ui/aiui resolves to the
same path as the build workspace. cp -r fails with "same file" error
which aborts the build under set -e. Use rsync instead (handles
same-src/dest gracefully), with cp fallback + || true.

This was the root cause of CI build #373 failure.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 13:04:10 +01:00
Dorian
4295476291 feat: frontend remote relay, kiosk hardening, CSS compositor fix
Frontend:
- Add remote-relay.ts: receives companion input via /ws/remote-relay,
  dispatches keyboard/mouse/scroll events into browser DOM
- Add CompanionIndicator.vue: NES gamepad icon when companion connected
- Wire relay start/stop to auth state in App.vue

Kiosk:
- Move Chromium data dir to /var/lib/archipelago/chromium-kiosk (encrypted)
- Disable MetricsReporting, AutofillServerCommunication, PasswordManager
- Remove --metrics-recording-only (contradicts disable-metrics)

CSS:
- Fix Chromium ghost rectangles: only apply preserve-3d + backface-visibility
  during transitions, not always-on (causes Chromium to skip painting
  off-viewport cards)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 11:10:08 +01:00
Dorian
c6b9097f3d fix: add Claude model ID normalization to AIUI proxy in ISO build
Sync MODEL_MAP from deploy script to ISO build's inline claude-api-proxy.
Maps short model names (claude-sonnet-4) to full API IDs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 11:01:58 +01:00
Dorian
07808a95c4 fix: first-boot container creation, remote input relay, ISO packages
Critical first-boot fixes (root cause: ALL 25 containers failed on install):
- Fix image-versions.sh sourcing: multi-path fallback for /opt/archipelago/scripts/
- Fix --add-host host-gateway: resolve actual gateway IP (podman 4.3 compat)
- Fix disk size detection: check /var/lib/archipelago not / (was forcing prune on 428GB disk)
- Fix Bitcoin health check: expand $RPC vars at creation, not inside container
- Add --network-alias to all containers (aardvark-dns reliability)
- Add --network-alias to backend RPC install handler

ISO build:
- Add apache2-utils for htpasswd (Fedimint gateway password hashing)

Remote input:
- Add broadcast relay channel for companion app → browser input forwarding
- Add /ws/remote-relay WebSocket endpoint
- Android: NES controller improvements, server connect flow updates

Container images:
- Fix lnd-ui Dockerfile: listen on 8080, run as root user (rootless compat)
- Fix bitcoin-ui, electrs-ui Dockerfiles: root user for rootless podman

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 10:34:58 +01:00
Dorian
051d3b1375 fix: version 1.3.0-alpha (alpha until beta testing complete)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 08:54:39 +01:00
Dorian
c62d7f77b5 fix: container orchestration stability, AIUI inclusion, lnd-ui port, version 1.3.0
Container stability:
- Merge scan results instead of full replacement (prevents UI flapping)
- Absence threshold: 3 consecutive missed scans before removing from state
- container-list RPC uses cached scanner state for consistency
- Increased Podman API timeout 30s → 60s (scanner + health monitor)
- Keep crashed containers visible as "exited" instead of podman rm -f
- Resolve host-gateway IP via ip route (podman 4.3.x compatibility)

ISO build fixes:
- AIUI web app inclusion: searches 5 paths + CI step to copy from build server
- Claude API proxy: systemctl enable with symlink fallback
- AIUI nginx: try_files =404 (was /aiui/index.html redirect loop)
- Build version set to 1.3.0

Container fixes:
- lnd-ui: nginx listens on 8080 (was 80, Permission denied in rootless)
- first-boot: image-versions.sh sourced from correct path with validation
- first-boot: host-gateway resolved to actual gateway IP

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 01:28:11 +01:00
Dorian
4b82b2a87e fix: unbundled ISO uses full first-boot script with all container fixes
The unbundled build was generating a 73-line inline script that only
created FileBrowser. This meant no lnd.conf, no UI sidecars, no
--add-host DNS fix for any app. Now uses the full first-boot-containers.sh
which handles both bundled (load tarballs) and unbundled (pull from
registry) modes, and includes all fixes for LND config, nginx sidecars,
and DNS resolution.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 22:31:45 +01:00
Dorian
19587687b4 fix: copy scripts/lib/ for unbundled ISO builds (TUI lib was missing)
The UNBUNDLED build path didn't copy scripts/lib/ to the ISO,
so install-tui.sh was never available on unbundled installs.
The installer sourced it but the file wasn't there — no animations.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 10:38:41 +01:00
Dorian
4e0fc38612 feat: sequential build versioning, LND NET_RAW, status labels
Build versioning:
- Sequential build counter (/opt/archipelago/build-counter)
- Version format: 0.1.0-beta.N (written to build-info.txt)
- Backend reads version from build-info.txt at startup, falls
  back to Cargo.toml version — no recompile needed
- UI sidebar + settings show the build version automatically

LND fix (belt + suspenders):
- Added NET_RAW capability (config.rs, first-boot, container-specs)
- Combined with tlsextraip=0.0.0.0 from previous commit

Status labels:
- Both "exited" AND "stopped" states with non-zero exit codes
  now show "crashed" in the UI

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 23:43:32 +01:00
Dorian
7070410b49 feat: integrate demo TUI animations into real installer
Add install-tui.sh library with boot scan, logo decrypt reveal,
bouncing Bitcoin symbol progress bar, and celebration strobe.
The installer sources it if available, falls back to plain text
if missing (easy revert: just remove the source line).

Animations: CRT power-on scan, BIOS memory check simulation,
3D ASCII logo with character-by-character decrypt reveal,
progress bar with ₿ bouncing DVD-screensaver style during
long operations, logo color party on completion, flashing
"REMOVE THE USB DRIVE NOW" warning.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 21:23:29 +01:00
Dorian
08f7f58a9d fix: bulletproof first-boot container creation and install reliability
Remove the Bitcoin RPC 60-second gate that blocked 13+ dependent containers
(mempool, electrumx, btcpay, lnd, fedimint) from being created on first boot.
Containers now always get created and auto-restart via health monitor once
Bitcoin becomes responsive — the designed recovery path.

Additional hardening:
- Validate archy-net creation with retry (silent failure broke DNS)
- Verify critical images are loaded, re-load from tarballs if missing
- Create SearXNG settings.yml before container start (was missing)
- Run reconciler automatically after first-boot failures
- Add load-images as explicit systemd dependency with 900s timeout
- Propagate config write errors in install.rs (bitcoin.conf, lnd.conf)
- FileBrowser password change: retry loop (6 attempts) + 0o600 perms
- Post-start verification: detect containers that exit immediately
- Add 2s dependency waits between container starts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 18:31:00 +01:00
Dorian
a896ecd431 fix: container security hardening, onboarding viewport scaling, boot screen cleanup
Container security:
- Add --cap-drop ALL + --security-opt no-new-privileges:true to 12 containers
  missing hardening in first-boot-containers.sh (mempool-db, electrumx,
  mempool-api, mempool-web, electrs-ui, btcpay-db, nbxplorer, nostr-rs-relay,
  strfry, tailscale, bitcoin-ui, lnd-ui)
- Mirror same hardening in deploy-to-target.sh for consistency
- Add --read-only + tmpfs to nostr-rs-relay
- Fix filebrowser deploy to include security flags
- Remove duplicate UI image definitions in image-versions.sh
- Separate Jellyfin capabilities (needs FOWNER, exec tmpfs for CoreCLR JIT)
- Harden archy-net creation with existence check and error handling

UI fixes:
- Fix onboarding viewport scaling: all 7 screens now use h-full + max-h-full
  pattern so containers never overflow viewport regardless of padding
- Remove path-option-card wrappers from seed verify inputs, left-justify labels
- Remove batteries/barbarian icons from boot screen (keep bitcoin, cloud, github, save)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 17:35:34 +01:00
Dorian
1e283daf13 fix: overhaul container lifecycle — recovery, health, uninstall, UI state
Container recovery:
- Health monitor: MAX_RESTART_ATTEMPTS 3→10, interval 60s→120s
- Dependency-aware restarts: won't restart services before their deps
- Reset dependent counters when a dependency recovers
- Handle "created" state containers (were invisible to health monitor)
- Added IndeedHub, mempool-api, mysql to tier system
- Crash recovery: podman start timeout 30s→120s with retry
- Podman client: socket timeout 5s→30s, added restart policy

UI state representation:
- Exit code 0 shows "stopped" (gray), not "crashed" (red)
- Exit code 137 shows "killed (OOM)"
- Non-zero exit shows "crashed" (red)
- Added exit_code field to PackageDataEntry

Install/uninstall fixes:
- Install returns error when container doesn't start (was silent success)
- Post-install hooks awaited instead of fire-and-forget tokio::spawn
- Uninstall: graceful rm before force, volume prune, network cleanup
- Uninstall returns error on partial failure (was 200 OK)

Config consistency:
- DB passwords read from /var/lib/archipelago/secrets/ (was hardcoded)
- Bitcoin: added ZMQ ports 28332/28333 for LND block notifications
- IndeedHub port 7777→8190 (was conflicting with strfry)
- Marketplace versions: LND 0.17.4→0.18.4, Mempool 2.5.0→3.0.0

Performance:
- Metrics collector interval 60s→300s (was duplicating health monitor)
- Podman client: proper error propagation instead of unwrap_or_default

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 07:03:57 +01:00
Dorian
f6c41f9052 fix: add python3 to ISO packages, set Claude API key in proxy service
AIUI proxy requires python3 which was missing from rootfs packages.
Also sets the beta API key in the claude-api-proxy systemd service
so AIUI works out of the box on fresh installs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 05:01:13 +01:00
Dorian
72d8101045 fix: add python3 to ISO packages for Claude API proxy
The claude-api-proxy.py requires python3 which was missing from the
rootfs package list, breaking AIUI on fresh installs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 04:52:30 +01:00
Dorian
adeb57edbf fix: force UTF-8 console with Terminus font for ASCII logo
The Archipelago ASCII logo uses Unicode block characters (▄▀█) which
render as garbled symbols when the console font doesn't support them.
Force Uni2 codeset + Terminus font in both the live ISO and installed
system's console-setup config.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 23:47:15 +01:00
Dorian
afda9897f1 fix: embed netavark/aardvark-dns in ISO at build time
Previous fix tried to copy from the live system at install time, but
the live ISO doesn't have netavark. Now: binaries are embedded in the
ISO during build (from the build host's /usr/lib/podman/), then copied
to the target at install time from the ISO filesystem.

This fixes container DNS on fresh installs — LND can now resolve
bitcoin-knots, mempool-api can resolve electrumx, etc.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 20:52:01 +01:00
Dorian
b515d3883f fix: install netavark + aardvark-dns for container DNS resolution
Fresh ISO installs use podman with CNI backend which lacks DNS.
Containers on archy-net can't resolve each other by name, causing:
- LND: "lookup bitcoin-knots: no such host"
- Any inter-container communication to fail

Fix: copy netavark + aardvark-dns from build host into ISO rootfs
and configure podman to use netavark backend. This enables automatic
DNS resolution on custom bridge networks (archy-net).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 18:57:17 +01:00
Dorian
44bffee473 fix: container installs, Tor, kiosk, GRUB, LUKS display, error messages
Critical:
- fix: container installs fail with "statfs: no such file or directory"
  Root cause: NoNewPrivileges=yes in systemd blocks sudo inside backend.
  Fix: use std::fs::create_dir_all + podman unshare chown (no sudo needed)
- fix: Tor services.json never written — \$ARCHY_TOR_DIR escaping bug
- fix: kiosk white screen — increase health wait to 60s, add --disable-gpu

Improvements:
- feat: LUKS encryption badge in Server disk stats (backend detects dm-crypt)
- fix: GRUB theme text scaling on 4:3 monitors — explicit fonts, wider menu
- fix: suppress default Debian MOTD (custom profile.d welcome is enough)
- fix: install error messages now show "Failed to pull/start" instead of
  generic "Operation failed" (middleware.rs allowlist expanded)
- fix: container-tests CI — source cargo env before running tests
- docs: interactive container architecture diagram (HTML)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 16:35:06 +01:00
Dorian
fdd69ce1b5 fix: auth, container resilience, ISO build, gamepad polish
- fix: login disconnect — verify session before WebSocket connect
- fix: 403 on app install — distinguish CSRF vs RBAC errors, only retry CSRF
- fix: health monitor now watches ALL containers (removed skip list for
  backend services like nbxplorer, databases, UI containers)
- fix: server.get-state added to CSRF-exempt list (read-only)
- fix: ISO build includes container-specs.sh and lib/common.sh in rootfs
  so reconcile actually works on fresh installs
- fix: gamepad nav — improved Server tab zone nav, focus styles, autofocus
- chore: move L484 web-only apps to Services tab
- chore: install store for cross-view install tracking

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 13:35:02 +01:00
Dorian
0f646a99d3 fix: CSRF 403 blocking all operations + reboot after install
CSRF fix (THE BLOCKER):
- After remember-me session restore, the browser has a stale CSRF
  cookie but a new session token. ALL subsequent RPC calls return 403.
- Fix: exempt read-only polling methods (node-messages-received,
  server.echo, system.stats, tor.status, etc.) from CSRF validation.
  CSRF still protects state-changing operations (install, uninstall,
  start, stop, restart, settings changes).

Reboot fix:
- The separate /tmp/archipelago-reboot.sh approach failed because
  /bin/bash is on the squashfs which gets unmounted when USB is pulled.
- Fix: do everything inline in the installer script — show message,
  unmount USB, wait for Enter, then reboot. Use sysrq-trigger first
  (kernel-level, doesn't need userspace binaries).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 22:42:09 +01:00
Dorian
ca646afd37 fix: version display, FileBrowser auto-login, nostr relay, UID mappings
Version per build:
- Health endpoint returns "1.2.0-alpha-{git_hash}" using GIT_HASH env
- CI passes git hash to cargo build

FileBrowser auto-login:
- filebrowser-client.ts: include CSRF token + credentials:include
- First-boot: generate random password, store at secrets/filebrowser/
- Set FileBrowser admin password to match after container creation

Nostr relay:
- Use docker.io/scsibug/nostr-rs-relay:0.9.0 (not in our registry)

UID mappings:
- Added electrumx (UID 1000), mysql-mempool, archy-btcpay-db, nextcloud-db

522 tests pass, Rust compiles clean.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 21:56:38 +01:00
Dorian
610e51500b fix: container orchestration overhaul — names, errors, Tor, restart
Container name resolution:
- New all_container_names() — single source of truth for every app's
  container name variants (bitcoin-knots/bitcoin/bitcoin-core, etc.)
- Covers all historical naming patterns and multi-container stacks

Start/Stop/Restart:
- No more silent failures (let _ = podman...). Every operation logs
  the command, checks exit status, and returns real errors to the UI.
- Restart uses stop+start fallback when podman restart fails
  (handles rootless podman loopback adapter errors)
- "No containers found" error when app doesn't exist

Tor helper:
- Install archipelago-tor-helper.path + .service in rootfs
- Enable the path unit so backend can manage Tor as non-root
- Copy tor-helper.sh to /opt/archipelago/scripts/

Verified: container with proper caps can stop/start/restart cleanly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 19:26:21 +01:00
Dorian
fbabbd0722 fix: auto-build UI containers for Bitcoin, LND, Electrumx
Critical: headless services (Bitcoin, LND, Electrumx) need companion
UI containers that serve web dashboards. These were only built for
Bitcoin, and only on bundled ISO builds.

Changes:
- install.rs: auto-build UI containers for LND (port 8081) and
  Electrumx (port 50002) in addition to Bitcoin (port 8334)
- build-auto-installer-iso.sh: always bundle docker UI source files
  (was skipping for unbundled builds — they're tiny HTML, not images)
- Dockerfiles: fix nginx base image tag 1.29.6→1.27.4 (matches registry)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 17:48:13 +01:00
Dorian
2049707986 fix: redirect container storage to LUKS encrypted partition
Container image pulls were filling the 29GB root partition (100% full
after 6 images). Now podman graphroot points to /var/lib/archipelago/
containers/storage on the 400GB+ LUKS encrypted data partition.

Added storage.conf with graphroot redirect + symlink for compat.
Also create containers/storage dir on encrypted partition during install.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 15:43:57 +01:00
Dorian
c0347c7592 fix: align image-versions.sh with registry, PATH for reboot
- image-versions.sh: fix 15+ tag mismatches against actual registry
  (bitcoin-knots:28.1→latest, lnd:v0.18.5→v0.18.4, grafana:11.4→10.2,
  vaultwarden:1.32.5→1.30.0-alpine, nextcloud:29→28, etc.)
- .bashrc: add /sbin:/usr/sbin to PATH so reboot/shutdown work
- Tailscale: add Arch Atob node (100.113.33.31)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 14:25:13 +01:00
Dorian
00428071f1 fix: UEFI ESP partition type, WebSocket cookie, password UX
UEFI boot:
- xorriso now uses -append_partition with ESP type GUID
  (C12A7328-F81F-11D2-BA4B-00A0C93EC93B) instead of -isohybrid-gpt-basdat
  which only creates "basic data" partitions. Strict UEFI firmware
  requires the correct ESP type to find BOOTX64.EFI.
- Uses Arch Linux ISO approach: -append_partition + appended_part_as_gpt

WebSocket/login from LAN browser:
- HTTPS nginx /ws block was missing proxy_set_header Cookie $http_cookie
  Session cookie wasn't forwarded → backend returned 401 → WS failed

Password UX:
- Renamed "Change Password" → "Set Password" with description explaining
  default password is password123

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 12:44:13 +01:00
Dorian
f9f54254c1 fix: suppress verbose command output in installer TUI
All mkfs, cryptsetup, grub-install, tar, update-initramfs output now
goes to log file only via run() wrapper. Console shows only clean TUI
status messages (step/ok/warn/fail/spinner).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 12:06:19 +01:00
Dorian
e9903e7b4b fix: UEFI boot fallback — search by file when label fails
The embedded GRUB EFI config only searched by volume label ARCHIPELAGO.
Some UEFI firmware presents USB devices differently, causing the search
to fail and GRUB to stall.

Added fallbacks:
1. search --file /archipelago/auto-install.sh (known ISO file)
2. Fall back to $cmdpath (EFI partition itself)
3. Use configfile before normal for explicit config loading
4. Added search_fs_file module to grub-mkstandalone

Also added same fallback to the main ISO grub.cfg.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 23:58:42 +00:00
Dorian
6e356412b8 fix: batch beta fixes — 13 issues from 2026-03-28 testing
Frontend (neode-ui):
- Login double-enter: change @keyup.enter to @keydown.enter (#10)
- Login loop on LAN: post-login session verify before navigation (#12)
- Splash flash: reorder isReady/showSplash, add black fallback div (#7)
- Skip button text: remove "skip this step" from onboarding (#8)
- Password UI: import existing ChangePasswordSection in Settings (#11)
- Arrow key focus trap: add tab-order fallback when spatial nav fails (#13)

ISO/Boot (image-recipe):
- Step counter: TOTAL_STEPS=7 → 8 to match actual step count
- GRUB theme: add desktop-image-scale-method stretch, widen menu
- Boot noise: add loglevel=0, rd.systemd.show_status=false to kernel
- USB removal: copy reboot script to tmpfs, exec from there
- Tor setup: rewrite python3 JSON generation as bash heredoc
- Doctor/reconcile: copy scripts into rootfs, fix missing file errors
- zstd: add to rootfs packages for initramfs compression

Docs:
- BETA-ISSUES-20260328.md: full issue tracker
- INSTALL-SCREENS-DESIGN.md: editable TUI mockups

522 tests pass, vue-tsc clean.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 23:41:40 +00:00
Dorian
bdd9578bf8 fix: root podman D-Bus cgroup issue in ISO build
When running as sudo, root podman can't reach the systemd D-Bus
session, causing "Transport endpoint is not connected" errors.
Auto-detect and fall back to cgroupfs cgroup manager.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 21:01:10 +00:00
Dorian
717733522b fix: heredoc quoting in installer profile.d (boot media not found)
The profile.d script used <<'PROFILE' (single-quoted heredoc) inside
a bash -c '...' single-quoted block. The inner quotes broke the outer
quoting, causing all $ variables to expand to empty at build time.
The for loop checked if [ -f "/archipelago/auto-install.sh" ] instead
of if [ -f "$dev/archipelago/auto-install.sh" ] — never matching.

Fix: use <<PROFILE with \$ escaping (matching .228's working version).
Also adds fallback device scanning if standard mount points are empty,
and fixes same quoting issue in grub-embed.cfg ($root variable).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 18:44:36 +00:00
Dorian
1b49257d95 fix: heredoc escaping in installer profile.d (build failure)
The z99-archipelago-installer.sh heredoc used $'\033[...]' ANSI-C
quoting inside an unquoted <<PROFILE heredoc. Bash misparses this
during expansion, treating multi-line content as a single ANSI-C
quoted string.

Fix: switch to <<'PROFILE' (quoted, no expansion) and use raw
\033 escape codes in echo -e instead of $'...' variables.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 15:15:42 +00:00