feat: add build report and first-boot diagnostics
Some checks failed
Build Archipelago ISO / build-iso (push) Has been cancelled

CI build report: checks rootfs contents (nginx, SSL, keyboard, kiosk,
lid config, backend, frontend) and ISO contents after build. Reports
in the Actions log so build issues are immediately visible.

First-boot diagnostics: one-shot systemd service runs 30s after first
boot, logs service status, nginx test, SSL certs, LUKS, podman,
kiosk, console-setup, disk, network, and journal errors to
/var/log/archipelago-first-boot-diag.log. Only runs once (ConditionPathExists).

SSH in and cat the log to debug any fresh install issues.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-26 20:54:32 +00:00
parent 5b60d13693
commit 3db9ff9216
2 changed files with 149 additions and 2 deletions

View File

@@ -47,11 +47,65 @@ jobs:
ISO=$(ls image-recipe/results/archipelago-installer-unbundled-*.iso 2>/dev/null | head -1)
if [ -n "$ISO" ]; then
DATE=$(date +%Y%m%d-%H%M)
sudo cp "$ISO" "/var/lib/archipelago/filebrowser/Builds/archipelago-unbundled-${DATE}.iso"
sudo chown 1000:1000 "/var/lib/archipelago/filebrowser/Builds/archipelago-unbundled-${DATE}.iso"
DEST="/var/lib/archipelago/filebrowser/Builds/archipelago-unbundled-${DATE}.iso"
sudo cp "$ISO" "$DEST"
sudo chown 1000:1000 "$DEST"
echo "ISO: archipelago-unbundled-${DATE}.iso"
echo "Size: $(du -h "$DEST" | cut -f1)"
echo "SHA256: $(sha256sum "$DEST" | cut -d' ' -f1)"
fi
- name: Build report
if: always()
run: |
echo "══════════════════════════════════════════"
echo "BUILD REPORT"
echo "══════════════════════════════════════════"
echo "Commit: $(git rev-parse --short HEAD) ($(git log -1 --format=%s))"
echo "Branch: ${GITHUB_REF_NAME:-unknown}"
echo "Date: $(date -u '+%Y-%m-%d %H:%M:%S UTC')"
echo "Runner: $(hostname)"
echo ""
echo "── Artifacts ──"
ls -lh image-recipe/results/*.iso 2>/dev/null || echo " No ISO produced"
ls -lh /var/lib/archipelago/filebrowser/Builds/archipelago-unbundled-*.iso 2>/dev/null | tail -3
echo ""
echo "── Rootfs contents check ──"
ROOTFS=$(ls image-recipe/build/auto-installer/rootfs.tar 2>/dev/null)
if [ -n "$ROOTFS" ]; then
echo " rootfs.tar: $(du -h "$ROOTFS" | cut -f1)"
echo " nginx config: $(tar tf "$ROOTFS" ./etc/nginx/sites-available/archipelago 2>/dev/null && echo 'PRESENT' || echo 'MISSING')"
echo " SSL cert: $(tar tf "$ROOTFS" ./etc/archipelago/ssl/archipelago.crt 2>/dev/null && echo 'PRESENT' || echo 'MISSING')"
echo " keyboard config: $(tar tf "$ROOTFS" ./etc/default/keyboard 2>/dev/null && echo 'PRESENT' || echo 'MISSING')"
echo " console-setup: $(tar tf "$ROOTFS" ./etc/default/console-setup 2>/dev/null && echo 'PRESENT' || echo 'MISSING')"
echo " kiosk launcher: $(tar tf "$ROOTFS" ./usr/local/bin/archipelago-kiosk-launcher 2>/dev/null && echo 'PRESENT' || echo 'MISSING')"
echo " logind lid: $(tar tf "$ROOTFS" ./etc/systemd/logind.conf.d/lid-ignore.conf 2>/dev/null && echo 'PRESENT' || echo 'MISSING')"
echo " backend binary: $(tar tf "$ROOTFS" ./usr/local/bin/archipelago 2>/dev/null && echo 'PRESENT' || echo 'MISSING')"
echo " web-ui index: $(tar tf "$ROOTFS" ./opt/archipelago/web-ui/index.html 2>/dev/null && echo 'PRESENT' || echo 'MISSING')"
else
echo " rootfs.tar not found in workspace"
fi
echo ""
echo "── ISO contents check ──"
ISO=$(ls image-recipe/results/archipelago-installer-unbundled-*.iso 2>/dev/null | head -1)
if [ -n "$ISO" ]; then
echo " ISO size: $(du -h "$ISO" | cut -f1)"
# Check installer script is present
ISO_MOUNT=$(mktemp -d)
if sudo mount -o loop,ro "$ISO" "$ISO_MOUNT" 2>/dev/null; then
echo " auto-install.sh: $([ -f "$ISO_MOUNT/archipelago/auto-install.sh" ] && echo 'PRESENT' || echo 'MISSING')"
echo " rootfs.tar: $([ -f "$ISO_MOUNT/archipelago/rootfs.tar" ] && echo "PRESENT ($(du -h "$ISO_MOUNT/archipelago/rootfs.tar" | cut -f1))" || echo 'MISSING')"
echo " backend bin: $([ -f "$ISO_MOUNT/archipelago/bin/archipelago" ] && echo "PRESENT ($(du -h "$ISO_MOUNT/archipelago/bin/archipelago" | cut -f1))" || echo 'MISSING')"
echo " frontend: $([ -f "$ISO_MOUNT/archipelago/web-ui/index.html" ] && echo 'PRESENT' || echo 'MISSING')"
echo " image-versions: $([ -f "$ISO_MOUNT/archipelago/scripts/image-versions.sh" ] && echo 'PRESENT' || echo 'MISSING')"
sudo umount "$ISO_MOUNT" 2>/dev/null
else
echo " Could not mount ISO for inspection"
fi
rmdir "$ISO_MOUNT" 2>/dev/null
fi
echo "══════════════════════════════════════════"
- name: Fix workspace permissions
if: always()
run: sudo chown -R $(id -u):$(id -g) . 2>/dev/null || true

View File

@@ -1040,6 +1040,10 @@ cat > "$ARCH_DIR/auto-install.sh" <<'INSTALLER_SCRIPT'
set -e
# Log everything to a file on the target disk (after mount) and to console
INSTALL_LOG="/tmp/archipelago-install.log"
exec > >(tee -a "$INSTALL_LOG") 2>&1
# Detect architecture at install time
case "$(uname -m)" in
x86_64|amd64)
@@ -1853,6 +1857,92 @@ chroot /mnt/target systemctl enable archipelago-setup-tor.service 2>/dev/null ||
chroot /mnt/target systemctl enable archipelago-first-boot-containers.service 2>/dev/null || true
chroot /mnt/target systemctl enable archipelago-kiosk.service 2>/dev/null || true
# Install first-boot diagnostic script — runs once after first boot and logs system state
cat > /mnt/target/opt/archipelago/scripts/first-boot-diag.sh <<'DIAGSCRIPT'
#!/bin/bash
LOG="/var/log/archipelago-first-boot-diag.log"
exec > "$LOG" 2>&1
echo "=== Archipelago First Boot Diagnostics ==="
echo "Date: $(date -u)"
echo "Hostname: $(hostname)"
echo "Kernel: $(uname -r)"
echo "IP: $(hostname -I 2>/dev/null | awk '{print $1}')"
echo ""
echo "=== Build Info ==="
cat /opt/archipelago/build-info.txt 2>/dev/null || echo "No build-info.txt"
echo ""
echo "=== Services ==="
for svc in nginx archipelago archipelago-kiosk archipelago-load-images archipelago-first-boot-containers; do
STATUS=$(systemctl is-active "$svc" 2>/dev/null || echo "missing")
ENABLED=$(systemctl is-enabled "$svc" 2>/dev/null || echo "missing")
printf " %-45s active=%-10s enabled=%s\n" "$svc" "$STATUS" "$ENABLED"
done
echo ""
echo "=== Nginx Test ==="
nginx -t 2>&1
echo ""
echo "=== SSL Cert ==="
ls -la /etc/archipelago/ssl/ 2>/dev/null || echo " No SSL directory"
echo ""
echo "=== EFI Boot ==="
ls -la /boot/efi/EFI/BOOT/ 2>/dev/null || echo " No EFI/BOOT directory"
echo ""
echo "=== LUKS ==="
ls -la /dev/mapper/archipelago-data 2>/dev/null && echo " LUKS volume open" || echo " No LUKS volume"
cat /etc/crypttab 2>/dev/null
echo ""
echo "=== Podman ==="
podman --version 2>/dev/null || echo " podman not found"
podman ps -a --format "{{.Names}} {{.Status}}" 2>/dev/null | head -20
echo ""
echo "=== Kiosk ==="
systemctl status archipelago-kiosk --no-pager 2>&1 | head -10
echo ""
echo "=== Console Setup ==="
systemctl status console-setup --no-pager 2>&1 | head -5
cat /etc/default/keyboard 2>/dev/null || echo " No keyboard config"
echo ""
echo "=== Logind (Lid) ==="
cat /etc/systemd/logind.conf.d/lid-ignore.conf 2>/dev/null || echo " No lid config"
echo ""
echo "=== Disk ==="
df -h / /boot/efi /var/lib/archipelago 2>/dev/null
echo ""
echo "=== Network ==="
ip addr show | grep -E "inet |link/" | head -10
echo ""
echo "=== Journal Errors (last boot) ==="
journalctl -b -p err --no-pager 2>/dev/null | tail -30
echo ""
echo "=== Done ==="
DIAGSCRIPT
chmod +x /mnt/target/opt/archipelago/scripts/first-boot-diag.sh
# Systemd oneshot service for first-boot diagnostics
cat > /mnt/target/etc/systemd/system/archipelago-diag.service <<'DIAGSVC'
[Unit]
Description=Archipelago First Boot Diagnostics
After=multi-user.target archipelago.service nginx.service
ConditionPathExists=!/var/log/archipelago-first-boot-diag.log
[Service]
Type=oneshot
ExecStartPre=/bin/sleep 30
ExecStart=/opt/archipelago/scripts/first-boot-diag.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
DIAGSVC
chroot /mnt/target systemctl enable archipelago-diag.service 2>/dev/null || true
# Write build info into the installed system
cat > /mnt/target/opt/archipelago/build-info.txt <<BUILDINFO
commit=$(cd /tmp 2>/dev/null && git -C "$BOOT_MEDIA/../" rev-parse --short HEAD 2>/dev/null || echo "unknown")
date=$(date -u '+%Y-%m-%d %H:%M:%S UTC')
type=unbundled
BUILDINFO
# Cleanup
sync
umount /mnt/target/run 2>/dev/null || true
@@ -1919,6 +2009,9 @@ echo ""
echo ""
echo -e "${YELLOW} >>> REMOVE THE USB DRIVE NOW <<<${NC}"
echo ""
# Save install log to target disk for post-install debugging
cp "$INSTALL_LOG" /mnt/target/var/log/archipelago-install.log 2>/dev/null || true
read -p "Press Enter to reboot (make sure USB is removed)..."
# Suppress all error output during cleanup and reboot