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>
This commit is contained in:
Dorian
2026-03-28 23:41:40 +00:00
parent bdd9578bf8
commit 6e356412b8
10 changed files with 330 additions and 57 deletions

View File

@@ -5,17 +5,18 @@
title-text: ""
desktop-color: "#0a0a0a"
desktop-image: "background.png"
desktop-image-scale-method: "stretch"
+ boot_menu {
left = 25%
left = 15%
top = 40%
width = 50%
height = 30%
width = 70%
height = 35%
item_color = "#aaaaaa"
selected_item_color = "#f7931a"
item_height = 36
item_spacing = 8
item_padding = 16
item_height = 40
item_spacing = 10
item_padding = 20
scrollbar = false
}

View File

@@ -280,6 +280,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
xfonts-base \
plymouth \
plymouth-themes \
zstd \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
@@ -339,6 +340,13 @@ COPY archipelago-doctor.timer /etc/systemd/system/archipelago-doctor.timer
COPY archipelago-reconcile.service /etc/systemd/system/archipelago-reconcile.service
COPY archipelago-reconcile.timer /etc/systemd/system/archipelago-reconcile.timer
# Copy container doctor + reconcile scripts (referenced by the services above)
RUN mkdir -p /home/archipelago/archy/scripts
COPY container-doctor.sh /home/archipelago/archy/scripts/container-doctor.sh
COPY reconcile-containers.sh /home/archipelago/archy/scripts/reconcile-containers.sh
RUN chmod +x /home/archipelago/archy/scripts/*.sh && \
chown -R archipelago:archipelago /home/archipelago/archy
# Enable services
RUN systemctl enable NetworkManager || true && \
systemctl enable ssh || true && \
@@ -409,12 +417,18 @@ NGINXCONF
echo " Using archipelago-update.service + timer from configs/"
fi
# Copy container doctor and reconciliation timers
# Copy container doctor and reconciliation timers + scripts
if [ -f "$SCRIPT_DIR/configs/archipelago-doctor.service" ]; then
cp "$SCRIPT_DIR/configs/archipelago-doctor.service" "$WORK_DIR/archipelago-doctor.service"
cp "$SCRIPT_DIR/configs/archipelago-doctor.timer" "$WORK_DIR/archipelago-doctor.timer"
cp "$SCRIPT_DIR/configs/archipelago-reconcile.service" "$WORK_DIR/archipelago-reconcile.service"
cp "$SCRIPT_DIR/configs/archipelago-reconcile.timer" "$WORK_DIR/archipelago-reconcile.timer"
# Copy the actual scripts the services reference
for s in container-doctor.sh reconcile-containers.sh; do
if [ -f "$SCRIPT_DIR/../scripts/$s" ]; then
cp "$SCRIPT_DIR/../scripts/$s" "$WORK_DIR/$s"
fi
done
echo " Using container doctor + reconcile timers from configs/"
fi
@@ -1106,21 +1120,20 @@ LOG="/var/log/archipelago-tor.log"
mkdir -p "$ARCHY_TOR_DIR"
# Write services.json for the backend to read
python3 -c '
import json
services = [
{"name": "archipelago", "local_port": 80, "enabled": True},
{"name": "bitcoin", "local_port": 8333, "enabled": True},
{"name": "electrumx", "local_port": 50001, "enabled": True},
{"name": "lnd", "local_port": 9735, "enabled": True},
{"name": "btcpay", "local_port": 23000, "enabled": True},
{"name": "mempool", "local_port": 4080, "enabled": True},
{"name": "fedimint", "local_port": 8175, "enabled": True}
]
with open("'"$ARCHY_TOR_DIR"'/services.json", "w") as f:
json.dump({"services": services}, f, indent=2)
print("services.json created")
'
cat > "\$ARCHY_TOR_DIR/services.json" <<TORJSON
{
"services": [
{"name": "archipelago", "local_port": 80, "enabled": true},
{"name": "bitcoin", "local_port": 8333, "enabled": true},
{"name": "electrumx", "local_port": 50001, "enabled": true},
{"name": "lnd", "local_port": 9735, "enabled": true},
{"name": "btcpay", "local_port": 23000, "enabled": true},
{"name": "mempool", "local_port": 4080, "enabled": true},
{"name": "fedimint", "local_port": 8175, "enabled": true}
]
}
TORJSON
echo "services.json created"
# Generate torrc — use /var/lib/tor/ for hidden services (AppArmor-safe)
cat > /etc/tor/torrc <<TORRC
@@ -1437,7 +1450,7 @@ boxline() {
# TUI helpers — Claude Code-inspired status display
STEP=0
TOTAL_STEPS=7
TOTAL_STEPS=8
step() {
STEP=$((STEP + 1))
echo ""
@@ -1863,27 +1876,32 @@ if [ -t 0 ] && [ -z "$ARCHIPELAGO_WELCOMED" ]; then
sleep 2
done
O='\033[38;5;208m'
D='\033[38;5;242m'
N='\033[0m'
clear
echo ""
echo " a r c h i p e l a g o"
echo " ━━━━━━━━━━━━━━━━━━━━━"
echo " bitcoin node os"
echo -e " ${O}█▀█ █▀▄ █▀▀ █ █ █ █▀▄▀█ █▀▀ █ █▀█ █▀▀ █▀█${N}"
echo -e " ${O}█▀█ █▀▄ █ █▀█ █ █ ▀ █ ██▀ █ █▀█ █ █ █ █${N}"
echo -e " ${O}▀ ▀ ▀ ▀ ▀▀▀ ▀ ▀ ▀ ▀ ▀ ▀▀▀ ▀▀▀ ▀ ▀ ▀▀▀ ▀▀▀${N}"
echo -e " ${D}bitcoin node os${N}"
echo ""
if [ -n "$IP" ]; then
echo " Web UI: http://$IP"
echo " SSH: ssh archipelago@$IP"
echo " Password: archipelago (SSH) / password123 (Web)"
echo -e " ${D}web ui${N} http://$IP"
echo -e " ${D}ssh${N} archipelago@$IP"
echo -e " ${D}password${N} archipelago (SSH) / password123 (Web)"
else
echo " Waiting for network..."
echo -e " ${D}Waiting for network...${N}"
fi
echo ""
if [ -b /dev/mapper/archipelago-data ]; then
echo " Storage: LUKS2 encrypted"
echo -e " ${D}storage${N} LUKS2 encrypted"
fi
if systemctl is-active archipelago-kiosk.service >/dev/null 2>&1; then
echo " Display: Kiosk active (Ctrl+Alt+F1 for terminal)"
echo -e " ${D}display${N} Kiosk active (Ctrl+Alt+F1 for terminal)"
else
echo " Display: Console (Ctrl+Alt+F7 for kiosk)"
echo -e " ${D}display${N} Console (Ctrl+Alt+F7 for kiosk)"
fi
echo ""
fi
@@ -2540,6 +2558,28 @@ echo ""
# Suppress kernel messages on console (SquashFS errors when USB is pulled)
echo 1 > /proc/sys/kernel/printk 2>/dev/null || true
# Copy reboot script to tmpfs so it survives USB removal
cat > /tmp/archipelago-reboot.sh <<'REBOOTSCRIPT'
#!/bin/bash
# This script runs from tmpfs — safe after USB removal
TW=$(tput cols 2>/dev/null || echo 60)
[ "$TW" -gt 120 ] && TW=120
cc() { local s=$(echo -e "$1" | sed 's/\x1b\[[0-9;]*m//g'); local p=$(( (TW - ${#s}) / 2 )); [ $p -lt 0 ] && p=0; printf "%*s" "$p" ""; echo -e "$1"; }
cc "\033[1;33m>>> REMOVE THE USB DRIVE NOW <<<\033[0m"
echo ""
cc "\033[37mPress Enter to reboot (or wait 30 seconds)\033[0m"
# Wait for Enter or timeout
read -t 30 -s 2>/dev/null || true
echo ""
cc "\033[37mRebooting...\033[0m"
sleep 1
reboot -f
REBOOTSCRIPT
chmod +x /tmp/archipelago-reboot.sh
# Lazy-unmount live filesystem BEFORE telling user to pull USB
exec 2>/dev/null
umount -l /run/live/medium 2>/dev/null || true
@@ -2553,13 +2593,8 @@ if [ -n "$BOOT_DEV" ]; then
fi
exec 2>&1
cc "${YELLOW}>>> REMOVE THE USB DRIVE <<<${NC}"
echo ""
cc "${DIM}Rebooting in 10 seconds...${NC}"
sleep 10
# Force reboot — skips systemd clean shutdown (which fails on missing USB)
reboot -f
# Hand off to tmpfs-based script — survives USB removal
exec /bin/bash /tmp/archipelago-reboot.sh
INSTALLER_SCRIPT
# For unbundled builds, patch the completion message to reflect no pre-loaded apps
@@ -2601,7 +2636,7 @@ set default=0
# Load font for graphical menu
if loadfont ($root)/boot/grub/font.pf2; then
set gfxmode=auto
set gfxmode=1024x768,auto
insmod gfxterm
insmod png
terminal_output gfxterm
@@ -2620,12 +2655,12 @@ else
fi
menuentry "Install Archipelago" --hotkey=i {
linux ($root)/live/vmlinuz boot=live components quiet splash
linux ($root)/live/vmlinuz boot=live components quiet splash loglevel=0 rd.systemd.show_status=false vt.global_cursor_default=0
initrd ($root)/live/initrd.img
}
menuentry "Install Archipelago (verbose)" --hotkey=v {
linux ($root)/live/vmlinuz boot=live components console=ttyS0,115200 console=tty0
linux ($root)/live/vmlinuz boot=live components loglevel=4 console=ttyS0,115200 console=tty0
initrd ($root)/live/initrd.img
}
@@ -2688,13 +2723,13 @@ DEFAULT install
LABEL install
MENU LABEL Install Archipelago
KERNEL /live/vmlinuz
APPEND initrd=/live/initrd.img boot=live components quiet
APPEND initrd=/live/initrd.img boot=live components quiet loglevel=0 rd.systemd.show_status=false vt.global_cursor_default=0
MENU DEFAULT
LABEL install-verbose
MENU LABEL Install (verbose output)
KERNEL /live/vmlinuz
APPEND initrd=/live/initrd.img boot=live components
APPEND initrd=/live/initrd.img boot=live components loglevel=4
LABEL local
MENU LABEL Boot from local disk