feat: custom boot branding, MBR fix, Plymouth theme, CI smoke tests
Boot fix: - Ship proven Debian Live MBR (4552) as branding/isohdpfx.bin — the ISOLINUX package MBR (33ed) doesn't boot on all hardware. This was the root cause of "machine doesn't pick up the USB". Branding: - Custom GRUB background: pixel-art floating island (1024x574) - Archipelago pixel-art logo for Plymouth boot splash - GRUB theme: dark background, orange selected item, no broken font refs - Plymouth theme: script-based with progress bar, LUKS prompt support - Plymouth + splash added to target rootfs packages - GRUB theme installed on both installer ISO and target system - Serial console (ttyS0) added to kernel params for QEMU debugging CI improvements: - Smoke test step: mounts ISO, verifies all critical files, checks initrd has live-boot, confirms boot=live in grub.cfg. Fails build before copying to Builds if any check fails. Dev workflow: - dev-branding.sh: extract ISO, swap branding, repackage, boot in QEMU (~10 seconds vs 20 min full rebuild) - generate-grub-background.py: procedural cyberpunk background generator - generate-plymouth-logo.py: procedural logo generator - Improved test-iso-qemu.sh: --bios/--nographic flags, serial logging Build: - Simplified live-boot install (clean chroot, no complex fallbacks) - Static branding images preferred, generators as fallback Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -265,6 +265,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
unclutter \
|
||||
fonts-liberation \
|
||||
xfonts-base \
|
||||
plymouth \
|
||||
plymouth-themes \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
@@ -464,51 +466,27 @@ linux-image-${DEB_ARCH},grub-efi-${DEB_ARCH},grub-pc-bin,\
|
||||
pciutils,usbutils,less,nano \
|
||||
bookworm /installer http://deb.debian.org/debian
|
||||
|
||||
# Install live-boot separately — debootstrap minbase resolver cannot handle it.
|
||||
# Use apt-get with explicit root dir instead of chroot (avoids /proc issues in containers).
|
||||
# Install live-boot via chroot — debootstrap minbase resolver cannot handle it.
|
||||
# The chroot approach works (confirmed in CI run 90) — just needs proc/sys/dev mounts.
|
||||
echo " [container] Installing live-boot for squashfs root support..."
|
||||
cp /etc/resolv.conf /installer/etc/resolv.conf 2>/dev/null || true
|
||||
apt-get -o Dir=/installer -o Dir::State::status=/installer/var/lib/dpkg/status \
|
||||
-o Dir::Etc::SourceList=/installer/etc/apt/sources.list \
|
||||
-o Dir::Cache=/installer/var/cache/apt \
|
||||
update -qq 2>/dev/null || {
|
||||
# Fallback: copy host apt lists and install directly
|
||||
echo " [container] apt-get Dir method failed, using dpkg extraction..."
|
||||
apt-get update -qq
|
||||
apt-get download live-boot live-boot-initramfs-tools 2>/dev/null
|
||||
for deb in live-boot*.deb; do
|
||||
dpkg-deb -x "$deb" /installer/ 2>/dev/null || true
|
||||
done
|
||||
rm -f live-boot*.deb
|
||||
}
|
||||
# Try chroot install if apt-get Dir method populated the lists
|
||||
if [ -f /installer/var/lib/apt/lists/*_Packages 2>/dev/null ]; then
|
||||
mount --bind /proc /installer/proc 2>/dev/null || true
|
||||
mount --bind /sys /installer/sys 2>/dev/null || true
|
||||
mount --bind /dev /installer/dev 2>/dev/null || true
|
||||
chroot /installer apt-get install -y --no-install-recommends live-boot live-boot-initramfs-tools 2>/dev/null || true
|
||||
chroot /installer apt-get clean 2>/dev/null || true
|
||||
umount /installer/dev 2>/dev/null || true
|
||||
umount /installer/sys 2>/dev/null || true
|
||||
umount /installer/proc 2>/dev/null || true
|
||||
fi
|
||||
mount --bind /proc /installer/proc
|
||||
mount --bind /sys /installer/sys
|
||||
mount --bind /dev /installer/dev
|
||||
chroot /installer apt-get update -qq
|
||||
chroot /installer apt-get install -y --no-install-recommends live-boot live-boot-initramfs-tools
|
||||
chroot /installer apt-get clean
|
||||
umount /installer/dev 2>/dev/null || true
|
||||
umount /installer/sys 2>/dev/null || true
|
||||
umount /installer/proc 2>/dev/null || true
|
||||
|
||||
# Verify live-boot hooks are in place
|
||||
# Verify live-boot hooks are in place (scripts/live is a FILE not a directory)
|
||||
if [ -e /installer/usr/share/initramfs-tools/scripts/live ]; then
|
||||
echo " [container] live-boot initramfs hooks: OK"
|
||||
else
|
||||
echo " [container] WARNING: live-boot hooks missing, trying dpkg extraction..."
|
||||
apt-get download live-boot live-boot-initramfs-tools 2>/dev/null || true
|
||||
for deb in live-boot*.deb; do
|
||||
dpkg-deb -x "$deb" /installer/ 2>/dev/null || true
|
||||
done
|
||||
rm -f live-boot*.deb 2>/dev/null || true
|
||||
if [ -e /installer/usr/share/initramfs-tools/scripts/live ]; then
|
||||
echo " [container] live-boot hooks installed via dpkg extraction: OK"
|
||||
else
|
||||
echo " [container] FATAL: Could not install live-boot hooks!"
|
||||
exit 1
|
||||
fi
|
||||
echo " [container] FATAL: live-boot hooks not found after install!"
|
||||
ls -la /installer/usr/share/initramfs-tools/scripts/ 2>/dev/null
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo " [container] Configuring installer environment..."
|
||||
@@ -725,6 +703,16 @@ if [ -d "$WORK_DIR/grub-fonts" ]; then
|
||||
# Also copy unicode font for GRUB to load
|
||||
cp "$WORK_DIR/grub-fonts/dejavu_16.pf2" "$INSTALLER_ISO/boot/grub/font.pf2"
|
||||
fi
|
||||
# Copy GRUB background image (static asset or generate if missing)
|
||||
GRUB_BG="$SCRIPT_DIR/branding/grub-theme/background.png"
|
||||
if [ -f "$GRUB_BG" ]; then
|
||||
cp "$GRUB_BG" "$THEME_DST/background.png"
|
||||
echo " Installed GRUB background"
|
||||
elif [ -f "$SCRIPT_DIR/branding/generate-grub-background.py" ]; then
|
||||
echo " Generating GRUB background..."
|
||||
python3 "$SCRIPT_DIR/branding/generate-grub-background.py" "$THEME_DST/background.png" 2>/dev/null || \
|
||||
echo " WARNING: Could not generate GRUB background"
|
||||
fi
|
||||
|
||||
echo " Installer squashfs: $(du -h "$INSTALLER_ISO/live/filesystem.squashfs" | cut -f1)"
|
||||
echo " Kernel: $(du -h "$INSTALLER_ISO/live/vmlinuz" | cut -f1)"
|
||||
@@ -858,6 +846,14 @@ if [ -d "$SCRIPT_DIR/../apps" ]; then
|
||||
cp -r "$SCRIPT_DIR/../apps" "$ARCH_DIR/"
|
||||
fi
|
||||
|
||||
# Copy Plymouth theme files for installation on target
|
||||
PLYMOUTH_SRC="$SCRIPT_DIR/branding/plymouth-theme"
|
||||
if [ -d "$PLYMOUTH_SRC" ]; then
|
||||
mkdir -p "$ARCH_DIR/plymouth-theme"
|
||||
cp "$PLYMOUTH_SRC/"* "$ARCH_DIR/plymouth-theme/"
|
||||
echo " Included Plymouth theme"
|
||||
fi
|
||||
|
||||
# =============================================================================
|
||||
# STEP 3b: Bundle container images for offline installation
|
||||
# =============================================================================
|
||||
@@ -2117,6 +2113,23 @@ if [ -d "$BOOT_MEDIA/boot/grub/themes/archipelago" ]; then
|
||||
echo " Installed Archipelago GRUB theme on target"
|
||||
fi
|
||||
|
||||
# Install Archipelago Plymouth theme on target system
|
||||
if [ -d "$BOOT_MEDIA/archipelago/plymouth-theme" ]; then
|
||||
PLYMOUTH_DIR="/mnt/target/usr/share/plymouth/themes/archipelago"
|
||||
mkdir -p "$PLYMOUTH_DIR"
|
||||
cp "$BOOT_MEDIA/archipelago/plymouth-theme/"* "$PLYMOUTH_DIR/"
|
||||
# Set as default Plymouth theme
|
||||
chroot /mnt/target plymouth-set-default-theme archipelago 2>/dev/null || \
|
||||
ln -sf /usr/share/plymouth/themes/archipelago/archipelago.plymouth \
|
||||
/mnt/target/etc/alternatives/default.plymouth 2>/dev/null || true
|
||||
# Enable splash in GRUB
|
||||
if ! grep -q "splash" /mnt/target/etc/default/grub; then
|
||||
sed -i 's/GRUB_CMDLINE_LINUX_DEFAULT="\(.*\)"/GRUB_CMDLINE_LINUX_DEFAULT="\1 splash"/' \
|
||||
/mnt/target/etc/default/grub 2>/dev/null || true
|
||||
fi
|
||||
echo " Installed Archipelago Plymouth theme on target"
|
||||
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..."
|
||||
@@ -2513,7 +2526,7 @@ else
|
||||
fi
|
||||
|
||||
menuentry "Install Archipelago" --hotkey=i {
|
||||
linux /live/vmlinuz boot=live components quiet
|
||||
linux /live/vmlinuz boot=live components quiet console=ttyS0,115200 console=tty0
|
||||
initrd /live/initrd.img
|
||||
}
|
||||
|
||||
@@ -2546,7 +2559,7 @@ 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 console=ttyS0,115200 console=tty0
|
||||
MENU DEFAULT
|
||||
|
||||
LABEL install-verbose
|
||||
@@ -2573,8 +2586,13 @@ else
|
||||
OUTPUT_ISO="$OUTPUT_DIR/archipelago-installer-${ARCH}.iso"
|
||||
fi
|
||||
|
||||
# Use ISOLINUX isohdpfx.bin for hybrid USB boot (built in Step 2)
|
||||
ISOHDPFX="$WORK_DIR/isohdpfx.bin"
|
||||
# Use the proven MBR code for hybrid USB boot
|
||||
# The ISOLINUX package's isohdpfx.bin (33 ed) doesn't boot on all hardware.
|
||||
# We ship the Debian Live MBR (45 52) which is known to work with Balena Etcher.
|
||||
ISOHDPFX="$SCRIPT_DIR/branding/isohdpfx.bin"
|
||||
if [ ! -f "$ISOHDPFX" ]; then
|
||||
ISOHDPFX="$WORK_DIR/isohdpfx.bin"
|
||||
fi
|
||||
if [ ! -f "$ISOHDPFX" ]; then
|
||||
# Fallback to system-installed copy
|
||||
for path in \
|
||||
|
||||
Reference in New Issue
Block a user