fix: WebSocket race conditions, Vue error handler, remove sudo podman, add container health checks

- F1: Guard connectWebSocket against concurrent calls with isWsConnecting flag
- F2: Serialize mesh send operations with sendQueue to prevent fetchMessages races
- F3: Add global Vue error handler with toast notification
- S1: Replace sudo podman with podman across all scripts (rootless Podman)
- S2: Add health-cmd to all 40 container run commands in first-boot-containers.sh

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-21 01:11:05 +00:00
parent b57ca4f171
commit 1d98de24d0
10 changed files with 301 additions and 110 deletions

View File

@@ -38,7 +38,9 @@ case "$ARCH" in
LINUX_IMAGE_PKG="linux-image-amd64"
GRUB_EFI_PKG="grub-efi-amd64"
GRUB_EFI_SIGNED_PKG="grub-efi-amd64-signed"
GRUB_PC_PKG="grub-pc-bin"
GRUB_TARGET="x86_64-efi"
GRUB_BIOS_TARGET="i386-pc"
CONTAINER_PLATFORM="linux/amd64"
LIB_DIR="${LIB_DIR}"
;;
@@ -48,7 +50,9 @@ case "$ARCH" in
LINUX_IMAGE_PKG="linux-image-arm64"
GRUB_EFI_PKG="grub-efi-arm64"
GRUB_EFI_SIGNED_PKG="grub-efi-arm64-signed"
GRUB_PC_PKG=""
GRUB_TARGET="arm64-efi"
GRUB_BIOS_TARGET=""
CONTAINER_PLATFORM="linux/arm64"
LIB_DIR="aarch64-linux-gnu"
;;
@@ -179,7 +183,7 @@ RUN apt-get update && apt-get install -y \
${LINUX_IMAGE_PKG} \
${GRUB_EFI_PKG} \
${GRUB_EFI_SIGNED_PKG} \
shim-signed \
${GRUB_PC_PKG} shim-signed \
systemd \
systemd-sysv \
dbus \
@@ -576,7 +580,7 @@ if [ -n "$DEV_SERVER" ] && [ "$DEV_SERVER" != "localhost" ] && [ "$DEV_SERVER" !
# Patterns match against `podman images` repository names (not container names)
CAPTURE_PATTERNS="bitcoin-ui bitcoinknots lnd lnd-ui electrs-ui filebrowser mempool backend frontend electrs tailscale homeassistant home-assistant btcpayserver nbxplorer postgres alpine-tor nostr-rs-relay strfry fedimintd gatewayd dwn-server grafana uptime-kuma jellyfin vaultwarden searxng mariadb valkey nginx-alpine portainer photoprism nextcloud nginx-proxy-manager immich onlyoffice adguard penpot"
REMOTE_TMP="/tmp/archipelago-image-capture-$$"
SAVED_LIST=$(ssh "$DEV_SERVER" "mkdir -p $REMOTE_TMP && for p in $CAPTURE_PATTERNS; do img=\$(sudo podman images --format '{{.Repository}}:{{.Tag}}' 2>/dev/null | grep -i \"\$p\" | head -1); [ -n \"\$img\" ] && sudo podman save -o \"$REMOTE_TMP/\$p.tar\" \"\$img\" 2>/dev/null && echo \"\$p\"; done" 2>/dev/null) || true
SAVED_LIST=$(ssh "$DEV_SERVER" "mkdir -p $REMOTE_TMP && for p in $CAPTURE_PATTERNS; do img=\$(podman images --format '{{.Repository}}:{{.Tag}}' 2>/dev/null | grep -i \"\$p\" | head -1); [ -n \"\$img\" ] && podman save -o \"$REMOTE_TMP/\$p.tar\" \"\$img\" 2>/dev/null && echo \"\$p\"; done" 2>/dev/null) || true
for p in $SAVED_LIST; do
if [ -n "$p" ] && scp "$DEV_SERVER:$REMOTE_TMP/$p.tar" "$IMAGES_DIR/$p.tar" 2>/dev/null; then
echo " ✅ Captured from server: $p.tar"
@@ -899,6 +903,20 @@ cat > "$ARCH_DIR/auto-install.sh" <<'INSTALLER_SCRIPT'
set -e
# Detect architecture at install time
case "$(uname -m)" in
x86_64|amd64)
ARCH="x86_64"
GRUB_TARGET="x86_64-efi"
GRUB_BIOS_TARGET="i386-pc"
;;
aarch64|arm64)
ARCH="arm64"
GRUB_TARGET="arm64-efi"
GRUB_BIOS_TARGET=""
;;
esac
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
@@ -1032,22 +1050,29 @@ echo ""
umount ${TARGET_DISK}* 2>/dev/null || true
umount ${TARGET_DISK}p* 2>/dev/null || true
# Create partition table
# Create partition table — dual BIOS+UEFI boot support
echo " [1/6] Creating partitions..."
parted -s "$TARGET_DISK" mklabel gpt
parted -s "$TARGET_DISK" mkpart primary fat32 1MiB 513MiB
parted -s "$TARGET_DISK" set 1 esp on
parted -s "$TARGET_DISK" mkpart primary ext4 513MiB 100%
# Partition 1: 1MB BIOS boot partition (for legacy BIOS GRUB on GPT disks)
parted -s "$TARGET_DISK" mkpart bios_boot 1MiB 2MiB
parted -s "$TARGET_DISK" set 1 bios_grub on
# Partition 2: 512MB EFI System Partition (for UEFI boot)
parted -s "$TARGET_DISK" mkpart efi fat32 2MiB 514MiB
parted -s "$TARGET_DISK" set 2 esp on
# Partition 3: Root filesystem (remaining space)
parted -s "$TARGET_DISK" mkpart root ext4 514MiB 100%
sleep 2
# Determine partition names
if [[ "$TARGET_DISK" == *nvme* ]]; then
EFI_PART="${TARGET_DISK}p1"
ROOT_PART="${TARGET_DISK}p2"
BIOS_PART="${TARGET_DISK}p1"
EFI_PART="${TARGET_DISK}p2"
ROOT_PART="${TARGET_DISK}p3"
else
EFI_PART="${TARGET_DISK}1"
ROOT_PART="${TARGET_DISK}2"
BIOS_PART="${TARGET_DISK}1"
EFI_PART="${TARGET_DISK}2"
ROOT_PART="${TARGET_DISK}3"
fi
# Format partitions
@@ -1157,6 +1182,10 @@ chown -R 1000:1000 /mnt/target/var/lib/archipelago 2>/dev/null || true
# Create welcome profile (nginx serves on port 80)
cat > /mnt/target/etc/profile.d/archipelago.sh <<'PROFILE'
#!/bin/bash
# Ensure /sbin and /usr/sbin are in PATH (needed for reboot, shutdown, etc.)
case ":$PATH:" in
*:/sbin:*) ;; *) export PATH="$PATH:/sbin:/usr/sbin" ;;
esac
if [ -t 0 ] && [ -z "$ARCHIPELAGO_WELCOMED" ]; then
export ARCHIPELAGO_WELCOMED=1
IP=$(hostname -I 2>/dev/null | awk '{print $1}')
@@ -1322,9 +1351,71 @@ if grep -q "^archipelago:[!*]" /mnt/target/etc/shadow 2>/dev/null; then
fi
echo " Passwords set for archipelago and root users"
chroot /mnt/target grub-install --target=${GRUB_TARGET} --efi-directory=/boot/efi --bootloader-id=archipelago --removable 2>/dev/null || \
chroot /mnt/target grub-install --target=${GRUB_TARGET} --efi-directory=/boot/efi --bootloader-id=archipelago 2>/dev/null || \
echo " Warning: GRUB install had issues, trying alternative..."
# UEFI boot: install to fallback path (/EFI/BOOT/BOOTX64.EFI) for maximum compatibility
echo " Installing UEFI bootloader..."
if chroot /mnt/target grub-install --target=${GRUB_TARGET} --efi-directory=/boot/efi --bootloader-id=archipelago --removable; then
echo " ✅ UEFI bootloader installed (removable/fallback path)"
else
echo " ⚠️ UEFI removable install failed, trying standard..."
if chroot /mnt/target grub-install --target=${GRUB_TARGET} --efi-directory=/boot/efi --bootloader-id=archipelago; then
echo " ✅ UEFI bootloader installed (standard)"
else
echo " ❌ UEFI bootloader installation failed"
fi
fi
# Secure Boot chain: replace unsigned GRUB with signed shim+grub for Secure Boot compatibility
# Framework laptops and other Secure Boot-enabled machines need this chain:
# BOOTX64.EFI (shimx64, Microsoft-signed) → grubx64.efi (Debian-signed) → kernel
echo " Setting up Secure Boot chain..."
if [ "$ARCH" = "x86_64" ]; then
SHIM_SRC="/mnt/target/usr/lib/shim/shimx64.efi.signed"
GRUB_SIGNED_SRC="/mnt/target/usr/lib/grub/x86_64-efi-signed/grubx64.efi.signed"
EFI_BOOT_BINARY="BOOTX64.EFI"
GRUB_EFI_BINARY="grubx64.efi"
SHIM_EFI_BINARY="shimx64.efi"
else
SHIM_SRC="/mnt/target/usr/lib/shim/shimaa64.efi.signed"
GRUB_SIGNED_SRC="/mnt/target/usr/lib/grub/arm64-efi-signed/grubaa64.efi.signed"
EFI_BOOT_BINARY="BOOTAA64.EFI"
GRUB_EFI_BINARY="grubaa64.efi"
SHIM_EFI_BINARY="shimaa64.efi"
fi
EFI_BOOT_DIR="/mnt/target/boot/efi/EFI/BOOT"
EFI_ARCHY_DIR="/mnt/target/boot/efi/EFI/archipelago"
if [ -f "$SHIM_SRC" ] && [ -f "$GRUB_SIGNED_SRC" ]; then
# Fallback path — what UEFI firmware checks when no boot entry exists
mkdir -p "$EFI_BOOT_DIR"
cp "$SHIM_SRC" "$EFI_BOOT_DIR/$EFI_BOOT_BINARY"
cp "$GRUB_SIGNED_SRC" "$EFI_BOOT_DIR/$GRUB_EFI_BINARY"
# Named entry path — for efibootmgr-registered entries
mkdir -p "$EFI_ARCHY_DIR"
cp "$SHIM_SRC" "$EFI_ARCHY_DIR/$SHIM_EFI_BINARY"
cp "$GRUB_SIGNED_SRC" "$EFI_ARCHY_DIR/$GRUB_EFI_BINARY"
echo " ✅ Secure Boot chain installed (shim + signed GRUB)"
else
echo " ⚠️ Signed shim/GRUB not found — Secure Boot machines must disable Secure Boot"
[ ! -f "$SHIM_SRC" ] && echo " Missing: $(basename $SHIM_SRC)"
[ ! -f "$GRUB_SIGNED_SRC" ] && echo " Missing: $(basename $GRUB_SIGNED_SRC)"
fi
# Legacy BIOS boot: only install if the installer booted in Legacy BIOS mode
# (if /sys/firmware/efi exists, the machine supports UEFI — no need for BIOS fallback)
if [ -n "${GRUB_BIOS_TARGET}" ] && [ ! -d /sys/firmware/efi ]; then
echo " Installing Legacy BIOS bootloader (machine booted in BIOS mode)..."
if chroot /mnt/target grub-install --target=${GRUB_BIOS_TARGET} "${TARGET_DISK}"; then
echo " ✅ Legacy BIOS bootloader installed"
else
echo " ⚠️ Legacy BIOS bootloader failed (UEFI-only boot)"
fi
elif [ -n "${GRUB_BIOS_TARGET}" ]; then
echo " Skipping Legacy BIOS bootloader (machine supports UEFI)"
fi
# Regenerate initramfs — the one from Docker export is corrupt/incomplete
# (Docker builds have limited /proc, /sys, /dev so initramfs generation fails silently)
echo " Regenerating initramfs..."
chroot /mnt/target update-initramfs -u -k all
chroot /mnt/target update-grub