feat: replace Debian Live with custom debootstrap ISO base + branding
Major ISO build overhaul on dev-iso branch: - Replace ~800MB Debian Live download with debootstrap --variant=minbase (~150MB installer squashfs built from scratch) - Custom initramfs with archipelago-mount hook for boot media detection - Systemd service auto-starts installer (replaces profile.d hack) - GRUB + ISOLINUX configs written from scratch (no Debian Live dependency) - EFI boot image built with grub-mkimage (no more MBR extraction) - Archipelago GRUB theme: dark background, Bitcoin orange accents - Theme installed on both installer ISO and target system - Rootfs optimizations: --no-install-recommends, strip docs/man/locales, remove firmware-misc-nonfree/wget/htop, add explicit font deps - Separate CI workflow (build-iso-dev.yml) for dev-iso branch - Includes pre-existing fixes from main (build-iso.yml, middleware, Login) Target: sub-2GB unbundled ISO (down from 3.9GB) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -31,7 +31,7 @@
|
||||
# build-auto-installer-iso.sh — Main orchestrator (config, CLI args, step sequencing)
|
||||
# lib/
|
||||
# rootfs.sh — Step 1: Build root filesystem via Docker (~185 lines)
|
||||
# installer-env.sh — Step 2: Download/extract Debian Live base ISO (~80 lines)
|
||||
# installer-env.sh — Step 2: Build minimal installer via debootstrap (~80 lines)
|
||||
# components.sh — Step 3: Add Archipelago components (binary, configs, web UI) (~120 lines)
|
||||
# container-images.sh — Step 3b: Bundle container images for offline install (~330 lines)
|
||||
# auto-install-script.sh — Step 4: Generate the embedded auto-install.sh (~615 lines)
|
||||
@@ -133,36 +133,42 @@ check_tools() {
|
||||
missing="$missing docker-or-podman"
|
||||
fi
|
||||
|
||||
if ! command -v xorriso >/dev/null 2>&1; then
|
||||
missing="$missing xorriso"
|
||||
for tool in xorriso mksquashfs; do
|
||||
if ! command -v $tool >/dev/null 2>&1; then
|
||||
missing="$missing $tool"
|
||||
fi
|
||||
done
|
||||
# Check for isolinux MBR (needed for hybrid USB boot)
|
||||
if [ ! -f /usr/lib/ISOLINUX/isohdpfx.bin ] && [ ! -f /usr/share/syslinux/isohdpfx.bin ]; then
|
||||
missing="$missing isolinux"
|
||||
fi
|
||||
if ! command -v 7z >/dev/null 2>&1 && ! command -v 7za >/dev/null 2>&1; then
|
||||
missing="$missing p7zip-full"
|
||||
fi
|
||||
|
||||
|
||||
if [ -n "$missing" ]; then
|
||||
echo "❌ Missing required tools:$missing"
|
||||
|
||||
echo "Missing required tools:$missing"
|
||||
|
||||
if [ "$can_install" = true ]; then
|
||||
echo " 📦 Auto-installing missing dependencies..."
|
||||
echo " Auto-installing missing dependencies..."
|
||||
apt-get update -qq
|
||||
|
||||
|
||||
if [[ "$missing" == *"xorriso"* ]]; then
|
||||
apt-get install -y xorriso
|
||||
fi
|
||||
if [[ "$missing" == *"p7zip-full"* ]]; then
|
||||
apt-get install -y p7zip-full
|
||||
if [[ "$missing" == *"mksquashfs"* ]]; then
|
||||
apt-get install -y squashfs-tools
|
||||
fi
|
||||
|
||||
if [[ "$missing" == *"isolinux"* ]]; then
|
||||
apt-get install -y isolinux syslinux-common
|
||||
fi
|
||||
|
||||
if [[ "$missing" == *"docker-or-podman"* ]]; then
|
||||
echo " Installing podman..."
|
||||
apt-get install -y podman
|
||||
CONTAINER_CMD="podman"
|
||||
fi
|
||||
|
||||
echo " ✅ Dependencies installed successfully!"
|
||||
|
||||
echo " Dependencies installed successfully!"
|
||||
else
|
||||
echo " Install with: sudo apt install xorriso podman"
|
||||
echo " Install with: sudo apt install xorriso squashfs-tools isolinux podman"
|
||||
echo " Or run this script with sudo to auto-install"
|
||||
exit 1
|
||||
fi
|
||||
@@ -226,7 +232,7 @@ RUN echo "deb http://deb.debian.org/debian bookworm main non-free-firmware" > /e
|
||||
rm -f /etc/apt/sources.list.d/debian.sources
|
||||
|
||||
# Install all packages we need including nginx, podman, tor, and openssl (for self-signed certs)
|
||||
RUN apt-get update && apt-get install -y \
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
${LINUX_IMAGE_PKG} \
|
||||
${GRUB_EFI_PKG} \
|
||||
${GRUB_EFI_SIGNED_PKG} \
|
||||
@@ -241,9 +247,7 @@ RUN apt-get update && apt-get install -y \
|
||||
podman \
|
||||
tor \
|
||||
curl \
|
||||
wget \
|
||||
git \
|
||||
htop \
|
||||
vim-tiny \
|
||||
ca-certificates \
|
||||
openssl \
|
||||
@@ -254,19 +258,26 @@ RUN apt-get update && apt-get install -y \
|
||||
cryptsetup \
|
||||
firmware-realtek \
|
||||
firmware-iwlwifi \
|
||||
firmware-misc-nonfree \
|
||||
intel-microcode \
|
||||
amd64-microcode \
|
||||
xorg \
|
||||
chromium \
|
||||
unclutter \
|
||||
fonts-liberation \
|
||||
xfonts-base \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Strip docs, man pages, and unused locales
|
||||
RUN find /usr/share/doc -depth -type f ! -name copyright -delete 2>/dev/null || true && \
|
||||
find /usr/share/doc -empty -delete 2>/dev/null || true && \
|
||||
rm -rf /usr/share/man /usr/share/info /usr/share/lintian /usr/share/linda && \
|
||||
find /usr/share/locale -maxdepth 1 -mindepth 1 ! -name 'en_US' ! -name 'locale.alias' -exec rm -rf {} + 2>/dev/null || true
|
||||
|
||||
# Install Tailscale from official repo
|
||||
RUN curl -fsSL https://pkgs.tailscale.com/stable/debian/bookworm.noarmor.gpg | tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null && \
|
||||
curl -fsSL https://pkgs.tailscale.com/stable/debian/bookworm.tailscale-keyring.list | tee /etc/apt/sources.list.d/tailscale.list && \
|
||||
apt-get update && apt-get install -y tailscale && \
|
||||
apt-get update && apt-get install -y --no-install-recommends tailscale && \
|
||||
apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Configure locale
|
||||
@@ -418,88 +429,249 @@ else
|
||||
fi
|
||||
|
||||
# =============================================================================
|
||||
# STEP 2: Create installer environment
|
||||
# STEP 2: Build minimal installer environment (replaces Debian Live)
|
||||
# =============================================================================
|
||||
echo ""
|
||||
echo "📦 Step 2: Creating installer environment..."
|
||||
echo "Step 2: Building minimal installer environment via debootstrap..."
|
||||
|
||||
# Download Debian Live as our installer base
|
||||
BASE_ISO="$WORK_DIR/debian-live-installer.iso"
|
||||
EXPECTED_SIZE=350000000 # ~350MB min (Debian 12 Live standard ~600MB)
|
||||
INSTALLER_ISO="$WORK_DIR/installer-iso"
|
||||
INSTALLER_SQUASHFS="$WORK_DIR/installer-squashfs"
|
||||
rm -rf "$INSTALLER_ISO" "$INSTALLER_SQUASHFS"
|
||||
mkdir -p "$INSTALLER_ISO/live" "$INSTALLER_ISO/archipelago"
|
||||
mkdir -p "$INSTALLER_ISO/boot/grub" "$INSTALLER_ISO/isolinux"
|
||||
mkdir -p "$INSTALLER_ISO/EFI/BOOT"
|
||||
|
||||
# Check if file exists and is complete
|
||||
if [ -f "$BASE_ISO" ]; then
|
||||
CURRENT_SIZE=$(stat -f%z "$BASE_ISO" 2>/dev/null || stat -c%s "$BASE_ISO" 2>/dev/null || echo 0)
|
||||
if [ "$CURRENT_SIZE" -ge "$EXPECTED_SIZE" ]; then
|
||||
echo " ✅ Debian Live base already downloaded"
|
||||
else
|
||||
echo " Found incomplete download ($(($CURRENT_SIZE / 1024 / 1024))MB), removing..."
|
||||
rm -f "$BASE_ISO"
|
||||
# Build the installer filesystem inside a container
|
||||
# This creates: vmlinuz, initrd.img, filesystem.squashfs
|
||||
echo " Building installer rootfs with debootstrap (this takes a few minutes)..."
|
||||
$CONTAINER_CMD run --rm --privileged --platform $CONTAINER_PLATFORM \
|
||||
-v "$WORK_DIR:/output" \
|
||||
-e DEB_ARCH="$DEB_ARCH" \
|
||||
-e LIB_DIR="$LIB_DIR" \
|
||||
debian:bookworm bash -c '
|
||||
set -e
|
||||
|
||||
apt-get update -qq
|
||||
apt-get install -y -qq debootstrap squashfs-tools initramfs-tools dosfstools mtools \
|
||||
grub-efi-amd64-bin grub-pc-bin grub-common isolinux syslinux-common
|
||||
|
||||
echo " [container] Running debootstrap --variant=minbase..."
|
||||
debootstrap --variant=minbase --arch=${DEB_ARCH} \
|
||||
--include=systemd,systemd-sysv,udev,dbus,bash,coreutils,mount,util-linux,\
|
||||
kmod,procps,iproute2,ca-certificates,gdisk,\
|
||||
cryptsetup,cryptsetup-initramfs,parted,dosfstools,e2fsprogs,\
|
||||
linux-image-${DEB_ARCH},grub-efi-${DEB_ARCH},grub-pc-bin,\
|
||||
pciutils,usbutils,less,nano \
|
||||
bookworm /installer http://deb.debian.org/debian
|
||||
|
||||
echo " [container] Configuring installer environment..."
|
||||
|
||||
# Set hostname
|
||||
echo "archipelago-installer" > /installer/etc/hostname
|
||||
|
||||
# Set root password
|
||||
echo "root:archipelago" | chroot /installer chpasswd
|
||||
|
||||
# Auto-login on tty1
|
||||
mkdir -p /installer/etc/systemd/system/getty@tty1.service.d
|
||||
cat > /installer/etc/systemd/system/getty@tty1.service.d/autologin.conf <<GETTY
|
||||
[Service]
|
||||
ExecStart=
|
||||
ExecStart=-/sbin/agetty --autologin root --noclear %I \$TERM
|
||||
GETTY
|
||||
|
||||
# Create the installer auto-start systemd service
|
||||
cat > /installer/etc/systemd/system/archipelago-installer.service <<SVCFILE
|
||||
[Unit]
|
||||
Description=Archipelago Auto-Installer
|
||||
After=multi-user.target systemd-logind.service
|
||||
Wants=multi-user.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/local/bin/archipelago-start-installer
|
||||
StandardInput=tty
|
||||
StandardOutput=tty
|
||||
StandardError=tty
|
||||
TTYPath=/dev/tty1
|
||||
TTYReset=yes
|
||||
TTYVHangup=yes
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
SVCFILE
|
||||
chroot /installer systemctl enable archipelago-installer.service
|
||||
|
||||
# Create the installer start wrapper
|
||||
cat > /installer/usr/local/bin/archipelago-start-installer <<WRAPPER
|
||||
#!/bin/bash
|
||||
sleep 2
|
||||
clear
|
||||
echo ""
|
||||
echo " ARCHIPELAGO BITCOIN NODE OS"
|
||||
echo " Automatic Installer"
|
||||
echo ""
|
||||
|
||||
BOOT_MEDIA=""
|
||||
for dev in /run/archiso /cdrom /media/cdrom /mnt/iso; do
|
||||
if [ -f "\$dev/archipelago/auto-install.sh" ]; then
|
||||
BOOT_MEDIA="\$dev"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "\$BOOT_MEDIA" ]; then
|
||||
echo " Found installer at: \$BOOT_MEDIA"
|
||||
echo ""
|
||||
echo " Press Enter to start installation, or Ctrl+C for shell..."
|
||||
read
|
||||
exec bash "\$BOOT_MEDIA/archipelago/auto-install.sh"
|
||||
else
|
||||
echo " Installer not found on boot media."
|
||||
echo " Checked: /run/archiso, /cdrom, /media/cdrom, /mnt/iso"
|
||||
echo ""
|
||||
echo " Dropping to shell for manual recovery..."
|
||||
exec /bin/bash
|
||||
fi
|
||||
WRAPPER
|
||||
chmod +x /installer/usr/local/bin/archipelago-start-installer
|
||||
|
||||
if [ ! -f "$BASE_ISO" ]; then
|
||||
echo " Downloading Debian Live base (352MB)..."
|
||||
echo " (This may take 5-10 minutes depending on network speed)"
|
||||
|
||||
# Use wget without -O so --continue actually works
|
||||
# Download with the ugly SourceForge filename, then rename
|
||||
# Use Debian 12 (Bookworm) to match the rootfs — NOT Debian 13 (Trixie)
|
||||
ISO_URL="https://cdimage.debian.org/cdimage/archive/12.10.0-live/${DEB_ARCH}/iso-hybrid/debian-live-12.10.0-${DEB_ARCH}-standard.iso"
|
||||
|
||||
if command -v wget >/dev/null 2>&1; then
|
||||
cd "$WORK_DIR"
|
||||
wget --tries=10 --read-timeout=120 --continue --progress=bar:force \
|
||||
--no-check-certificate \
|
||||
"$ISO_URL" || {
|
||||
echo " ❌ Download failed or incomplete"
|
||||
echo " Partial file kept - run script again to continue"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Find the downloaded file — wget may use URL filename or follow redirects
|
||||
FOUND_ISO=$(find "$WORK_DIR" -maxdepth 1 -name "debian-live-12*.iso" -o -name "download" 2>/dev/null | head -1)
|
||||
if [ -n "$FOUND_ISO" ] && [ -f "$FOUND_ISO" ]; then
|
||||
mv "$FOUND_ISO" "$BASE_ISO"
|
||||
else
|
||||
echo " ❌ Downloaded file not found in $WORK_DIR"
|
||||
echo " Files present:"
|
||||
ls -la "$WORK_DIR"/*.iso 2>/dev/null || echo " (no .iso files)"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
# Fallback to curl (no resume support)
|
||||
curl -L --location-trusted --retry 10 --retry-delay 5 \
|
||||
--connect-timeout 60 --max-time 1800 \
|
||||
-o "$BASE_ISO" \
|
||||
"$ISO_URL" || {
|
||||
echo " ❌ Download failed"
|
||||
rm -f "$BASE_ISO"
|
||||
exit 1
|
||||
}
|
||||
# Custom initramfs hook: mount ISO boot media at /run/archiso
|
||||
mkdir -p /installer/etc/initramfs-tools/hooks
|
||||
cat > /installer/etc/initramfs-tools/hooks/archipelago <<HOOK
|
||||
#!/bin/sh
|
||||
set -e
|
||||
PREREQ=""
|
||||
prereqs() { echo "\$PREREQ"; }
|
||||
case "\$1" in prereqs) prereqs; exit 0;; esac
|
||||
. /usr/share/initramfs-tools/hook-functions
|
||||
# Ensure mount helpers and filesystem tools are in initramfs
|
||||
copy_exec /bin/mount
|
||||
copy_exec /bin/umount
|
||||
copy_exec /bin/findfs 2>/dev/null || true
|
||||
copy_exec /sbin/blkid
|
||||
manual_add_modules iso9660 vfat squashfs overlay
|
||||
HOOK
|
||||
chmod +x /installer/etc/initramfs-tools/hooks/archipelago
|
||||
|
||||
mkdir -p /installer/etc/initramfs-tools/scripts/local-bottom
|
||||
cat > /installer/etc/initramfs-tools/scripts/local-bottom/archipelago-mount <<INITSCRIPT
|
||||
#!/bin/sh
|
||||
PREREQ=""
|
||||
prereqs() { echo "\$PREREQ"; }
|
||||
case "\$1" in prereqs) prereqs; exit 0;; esac
|
||||
|
||||
. /scripts/functions
|
||||
|
||||
# Try to find and mount the Archipelago boot media
|
||||
mkdir -p /run/archiso
|
||||
log_begin_msg "Searching for Archipelago boot media..."
|
||||
|
||||
# Try CD-ROM first, then USB partitions
|
||||
for dev in /dev/sr0 /dev/sd??* /dev/nvme*p*; do
|
||||
[ -b "\$dev" ] 2>/dev/null || continue
|
||||
mount -o ro "\$dev" /run/archiso 2>/dev/null || continue
|
||||
if [ -d /run/archiso/archipelago ]; then
|
||||
log_end_msg 0
|
||||
echo "Found Archipelago media on \$dev"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Verify download size
|
||||
FINAL_SIZE=$(stat -f%z "$BASE_ISO" 2>/dev/null || stat -c%s "$BASE_ISO" 2>/dev/null || echo 0)
|
||||
if [ "$FINAL_SIZE" -lt "$EXPECTED_SIZE" ]; then
|
||||
echo " ❌ Download incomplete: got $(($FINAL_SIZE / 1024 / 1024))MB, expected 352MB"
|
||||
umount /run/archiso 2>/dev/null || true
|
||||
done
|
||||
|
||||
log_end_msg 1
|
||||
echo "Archipelago boot media not found (will retry from userspace)"
|
||||
INITSCRIPT
|
||||
chmod +x /installer/etc/initramfs-tools/scripts/local-bottom/archipelago-mount
|
||||
|
||||
# Strip docs and man pages from installer
|
||||
rm -rf /installer/usr/share/man/* /installer/usr/share/doc/*
|
||||
rm -rf /installer/var/lib/apt/lists/* /installer/var/cache/apt/*
|
||||
|
||||
# Extract kernel
|
||||
KVER=$(ls /installer/lib/modules/ | sort -V | tail -1)
|
||||
echo " [container] Kernel version: $KVER"
|
||||
cp /installer/boot/vmlinuz-$KVER /output/vmlinuz
|
||||
|
||||
# Build initramfs with our custom hooks
|
||||
chroot /installer update-initramfs -c -k $KVER
|
||||
cp /installer/boot/initrd.img-$KVER /output/initrd.img
|
||||
|
||||
# Create squashfs
|
||||
echo " [container] Creating installer squashfs..."
|
||||
mksquashfs /installer /output/filesystem.squashfs -comp xz -Xbcj x86 -noappend -quiet
|
||||
|
||||
# Build GRUB EFI image
|
||||
echo " [container] Building GRUB EFI image..."
|
||||
grub-mkimage -O x86_64-efi -o /output/BOOTX64.EFI -p /boot/grub \
|
||||
part_gpt part_msdos fat iso9660 udf normal boot linux search \
|
||||
search_fs_uuid search_fs_file search_label configfile echo cat \
|
||||
ls test true loopback gfxterm gfxmenu font png
|
||||
|
||||
# Create EFI FAT image (4MB)
|
||||
dd if=/dev/zero of=/output/efi.img bs=1M count=4 2>/dev/null
|
||||
mkfs.vfat /output/efi.img >/dev/null
|
||||
mmd -i /output/efi.img ::/EFI ::/EFI/BOOT
|
||||
mcopy -i /output/efi.img /output/BOOTX64.EFI ::/EFI/BOOT/BOOTX64.EFI
|
||||
|
||||
# Copy ISOLINUX files for legacy BIOS boot
|
||||
cp /usr/lib/ISOLINUX/isolinux.bin /output/isolinux.bin
|
||||
cp /usr/lib/syslinux/modules/bios/ldlinux.c32 /output/ldlinux.c32
|
||||
cp /usr/lib/syslinux/modules/bios/menu.c32 /output/menu.c32 2>/dev/null || true
|
||||
cp /usr/lib/syslinux/modules/bios/libutil.c32 /output/libutil.c32 2>/dev/null || true
|
||||
cp /usr/lib/ISOLINUX/isohdpfx.bin /output/isohdpfx.bin
|
||||
|
||||
# Generate GRUB fonts for theme
|
||||
echo " [container] Generating GRUB fonts..."
|
||||
apt-get install -y -qq fonts-dejavu-core grub-common >/dev/null 2>&1
|
||||
mkdir -p /output/grub-fonts
|
||||
grub-mkfont -s 12 -o /output/grub-fonts/dejavu_12.pf2 /usr/share/fonts/truetype/dejavu/DejaVuSans.ttf
|
||||
grub-mkfont -s 14 -o /output/grub-fonts/dejavu_14.pf2 /usr/share/fonts/truetype/dejavu/DejaVuSans.ttf
|
||||
grub-mkfont -s 16 -o /output/grub-fonts/dejavu_16.pf2 /usr/share/fonts/truetype/dejavu/DejaVuSans.ttf
|
||||
grub-mkfont -s 24 -o /output/grub-fonts/dejavu_24.pf2 /usr/share/fonts/truetype/dejavu/DejaVuSansMono-Bold.ttf
|
||||
|
||||
echo " [container] Done!"
|
||||
'
|
||||
|
||||
# Verify artifacts
|
||||
for artifact in vmlinuz initrd.img filesystem.squashfs BOOTX64.EFI efi.img isolinux.bin isohdpfx.bin; do
|
||||
if [ ! -f "$WORK_DIR/$artifact" ]; then
|
||||
echo " FATAL: Missing build artifact: $artifact"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo " ✅ Download complete ($(($FINAL_SIZE / 1024 / 1024))MB)"
|
||||
done
|
||||
|
||||
# Place artifacts into ISO directory structure
|
||||
cp "$WORK_DIR/vmlinuz" "$INSTALLER_ISO/live/vmlinuz"
|
||||
cp "$WORK_DIR/initrd.img" "$INSTALLER_ISO/live/initrd.img"
|
||||
cp "$WORK_DIR/filesystem.squashfs" "$INSTALLER_ISO/live/filesystem.squashfs"
|
||||
cp "$WORK_DIR/BOOTX64.EFI" "$INSTALLER_ISO/EFI/BOOT/BOOTX64.EFI"
|
||||
cp "$WORK_DIR/efi.img" "$INSTALLER_ISO/boot/grub/efi.img"
|
||||
cp "$WORK_DIR/isolinux.bin" "$INSTALLER_ISO/isolinux/isolinux.bin"
|
||||
cp "$WORK_DIR/ldlinux.c32" "$INSTALLER_ISO/isolinux/ldlinux.c32"
|
||||
cp "$WORK_DIR/menu.c32" "$INSTALLER_ISO/isolinux/menu.c32" 2>/dev/null || true
|
||||
cp "$WORK_DIR/libutil.c32" "$INSTALLER_ISO/isolinux/libutil.c32" 2>/dev/null || true
|
||||
|
||||
# Install GRUB theme
|
||||
THEME_SRC="$SCRIPT_DIR/branding/grub-theme"
|
||||
THEME_DST="$INSTALLER_ISO/boot/grub/themes/archipelago"
|
||||
mkdir -p "$THEME_DST"
|
||||
if [ -f "$THEME_SRC/theme.txt" ]; then
|
||||
cp "$THEME_SRC/theme.txt" "$THEME_DST/"
|
||||
echo " Installed GRUB theme from branding/grub-theme/"
|
||||
fi
|
||||
# Install generated fonts
|
||||
if [ -d "$WORK_DIR/grub-fonts" ]; then
|
||||
cp "$WORK_DIR/grub-fonts/"*.pf2 "$THEME_DST/"
|
||||
# Also copy unicode font for GRUB to load
|
||||
cp "$WORK_DIR/grub-fonts/dejavu_16.pf2" "$INSTALLER_ISO/boot/grub/font.pf2"
|
||||
fi
|
||||
|
||||
echo " Extracting installer base..."
|
||||
INSTALLER_ISO="$WORK_DIR/installer-iso"
|
||||
rm -rf "$INSTALLER_ISO"
|
||||
mkdir -p "$INSTALLER_ISO"
|
||||
cd "$INSTALLER_ISO"
|
||||
# 7z returns exit code 2 for warnings (symlinks in ISO) — check for key files instead
|
||||
7z x -y "$BASE_ISO" >/dev/null 2>&1 || 7za x -y "$BASE_ISO" >/dev/null 2>&1 || bsdtar -xf "$BASE_ISO" 2>/dev/null || true
|
||||
if [ ! -d "$INSTALLER_ISO/live" ] || [ ! -f "$INSTALLER_ISO/live/vmlinuz" ]; then
|
||||
echo " ❌ Failed to extract ISO. Install p7zip-full: sudo apt install p7zip-full"
|
||||
exit 1
|
||||
fi
|
||||
echo " Installer squashfs: $(du -h "$INSTALLER_ISO/live/filesystem.squashfs" | cut -f1)"
|
||||
echo " Kernel: $(du -h "$INSTALLER_ISO/live/vmlinuz" | cut -f1)"
|
||||
echo " Initrd: $(du -h "$INSTALLER_ISO/live/initrd.img" | cut -f1)"
|
||||
echo " Step 2 complete (custom minimal base, no Debian Live)"
|
||||
|
||||
# =============================================================================
|
||||
# STEP 3: Add Archipelago components
|
||||
@@ -1152,7 +1324,7 @@ echo ""
|
||||
|
||||
# Find boot media
|
||||
BOOT_MEDIA=""
|
||||
for dev in /run/live/medium /lib/live/mount/medium /cdrom; do
|
||||
for dev in /run/archiso /cdrom /media/cdrom /run/live/medium /lib/live/mount/medium /mnt/iso; do
|
||||
if [ -d "$dev/archipelago" ]; then
|
||||
BOOT_MEDIA="$dev"
|
||||
break
|
||||
@@ -1694,8 +1866,9 @@ while true; do
|
||||
--disable-save-password-bubble \
|
||||
--disable-suggestions-service \
|
||||
--password-store=basic \
|
||||
--disable-features=TranslateUI,PasswordManagerOnboarding \
|
||||
--disable-features=TranslateUI,PasswordManagerOnboarding,AutofillServerCommunication,PasswordManagerEnabled \
|
||||
--disable-component-update \
|
||||
--credentials_enable_service=false \
|
||||
--user-data-dir=/home/archipelago/.config/chromium-kiosk
|
||||
sleep 3
|
||||
done
|
||||
@@ -1869,10 +2042,8 @@ elif [ -n "${GRUB_BIOS_TARGET}" ]; then
|
||||
echo " Skipping Legacy BIOS bootloader (machine supports UEFI)"
|
||||
fi
|
||||
|
||||
# Remove any live-boot artifacts that could cause squashfs errors on boot
|
||||
# These can sneak in from Docker base image or package dependencies
|
||||
echo " Cleaning live-boot artifacts..."
|
||||
chroot /mnt/target apt-get remove -y --purge live-boot live-boot-initramfs-tools live-config 2>/dev/null || true
|
||||
# Clean any stale live-boot artifacts (should not exist in the custom rootfs,
|
||||
# but clean up defensively in case Docker base image pulled them in)
|
||||
rm -f /mnt/target/etc/initramfs-tools/conf.d/live-boot* 2>/dev/null || true
|
||||
rm -f /mnt/target/usr/share/initramfs-tools/scripts/live* 2>/dev/null || true
|
||||
rm -f /mnt/target/usr/share/initramfs-tools/hooks/live* 2>/dev/null || true
|
||||
@@ -1880,6 +2051,14 @@ rm -f /mnt/target/usr/share/initramfs-tools/hooks/live* 2>/dev/null || true
|
||||
# Suppress os-prober warning in GRUB
|
||||
echo "GRUB_DISABLE_OS_PROBER=true" >> /mnt/target/etc/default/grub
|
||||
|
||||
# Install Archipelago GRUB theme on target system
|
||||
if [ -d "$BOOT_MEDIA/boot/grub/themes/archipelago" ]; then
|
||||
mkdir -p /mnt/target/boot/grub/themes/archipelago
|
||||
cp "$BOOT_MEDIA/boot/grub/themes/archipelago/"* /mnt/target/boot/grub/themes/archipelago/
|
||||
echo 'GRUB_THEME="/boot/grub/themes/archipelago/theme.txt"' >> /mnt/target/etc/default/grub
|
||||
echo " Installed Archipelago GRUB 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..."
|
||||
@@ -1888,8 +2067,12 @@ chroot /mnt/target update-initramfs -u -k all
|
||||
chroot /mnt/target update-grub
|
||||
|
||||
# Install udev rule for mesh radio stable naming (/dev/mesh-radio)
|
||||
if [ -f /cdrom/99-mesh-radio.rules ]; then
|
||||
cp /cdrom/99-mesh-radio.rules /mnt/target/etc/udev/rules.d/99-mesh-radio.rules
|
||||
MESH_RULES=""
|
||||
for p in "$BOOT_MEDIA/99-mesh-radio.rules" /cdrom/99-mesh-radio.rules "$BOOT_MEDIA/archipelago/configs/99-mesh-radio.rules"; do
|
||||
[ -f "$p" ] && MESH_RULES="$p" && break
|
||||
done
|
||||
if [ -n "$MESH_RULES" ]; then
|
||||
cp "$MESH_RULES" /mnt/target/etc/udev/rules.d/99-mesh-radio.rules
|
||||
echo " Installed mesh radio udev rule"
|
||||
fi
|
||||
|
||||
@@ -2207,12 +2390,13 @@ read -p "Press Enter to reboot (make sure USB is removed)..."
|
||||
exec 2>/dev/null
|
||||
|
||||
# Try to eject the USB boot media to prevent booting back into installer
|
||||
BOOT_DEV=$(findmnt -n -o SOURCE /run/live/medium 2>/dev/null || findmnt -n -o SOURCE /lib/live/mount/medium 2>/dev/null || echo "")
|
||||
BOOT_DEV=$(findmnt -n -o SOURCE /run/archiso 2>/dev/null || findmnt -n -o SOURCE /cdrom 2>/dev/null || findmnt -n -o SOURCE /run/live/medium 2>/dev/null || echo "")
|
||||
if [ -n "$BOOT_DEV" ]; then
|
||||
BOOT_DISK=$(lsblk -no PKNAME "$BOOT_DEV" 2>/dev/null | head -1)
|
||||
if [ -n "$BOOT_DISK" ]; then
|
||||
umount -l /run/archiso 2>/dev/null || true
|
||||
umount -l /cdrom 2>/dev/null || true
|
||||
umount -l /run/live/medium 2>/dev/null || true
|
||||
umount -l /lib/live/mount/medium 2>/dev/null || true
|
||||
eject "/dev/$BOOT_DISK" 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
@@ -2230,227 +2414,100 @@ fi
|
||||
chmod +x "$ARCH_DIR/auto-install.sh"
|
||||
|
||||
# =============================================================================
|
||||
# STEP 5: Configure auto-start installer on boot
|
||||
# STEP 5: Configure boot loader and ISO structure
|
||||
# =============================================================================
|
||||
echo ""
|
||||
echo "📦 Step 5: Configuring auto-start..."
|
||||
echo "Step 5: Configuring boot loaders..."
|
||||
|
||||
# Create a squashfs overlay module that Debian Live will automatically load
|
||||
# This is the proper way to add files to the live filesystem
|
||||
OVERLAY_DIR="$WORK_DIR/overlay-root"
|
||||
rm -rf "$OVERLAY_DIR"
|
||||
mkdir -p "$OVERLAY_DIR/etc/profile.d"
|
||||
mkdir -p "$OVERLAY_DIR/etc/skel"
|
||||
mkdir -p "$OVERLAY_DIR/usr/local/bin"
|
||||
mkdir -p "$OVERLAY_DIR/usr/sbin"
|
||||
mkdir -p "$OVERLAY_DIR/sbin"
|
||||
# The installer squashfs (from Step 2) already contains:
|
||||
# - systemd service for auto-starting the installer
|
||||
# - auto-login on tty1
|
||||
# - custom initramfs hook for mounting boot media at /run/archiso
|
||||
# - all partitioning tools (parted, mkfs.*, cryptsetup)
|
||||
#
|
||||
# Step 5 just needs to create the GRUB and ISOLINUX boot configs.
|
||||
|
||||
# Download and extract required tools AND their libraries for offline use
|
||||
echo " Downloading partitioning tools for offline use..."
|
||||
TOOLS_DIR="$WORK_DIR/tools-extract"
|
||||
rm -rf "$TOOLS_DIR"
|
||||
mkdir -p "$TOOLS_DIR"
|
||||
# Create GRUB configuration
|
||||
echo " Writing GRUB config..."
|
||||
cat > "$INSTALLER_ISO/boot/grub/grub.cfg" <<'GRUBCFG'
|
||||
set timeout=5
|
||||
set default=0
|
||||
|
||||
$CONTAINER_CMD run --rm --platform $CONTAINER_PLATFORM \
|
||||
-v "$TOOLS_DIR:/output" \
|
||||
debian:bookworm \
|
||||
bash -c '
|
||||
apt-get update -qq
|
||||
apt-get install -y -qq parted dosfstools e2fsprogs
|
||||
|
||||
# Copy binaries
|
||||
cp /usr/sbin/parted /output/
|
||||
cp /usr/sbin/mkfs.vfat /output/ 2>/dev/null || cp /sbin/mkfs.vfat /output/ 2>/dev/null || true
|
||||
cp /usr/sbin/mkfs.ext4 /output/ 2>/dev/null || cp /sbin/mkfs.ext4 /output/ 2>/dev/null || true
|
||||
cp /usr/sbin/mke2fs /output/ 2>/dev/null || cp /sbin/mke2fs /output/ 2>/dev/null || true
|
||||
cp /sbin/mkfs.fat /output/ 2>/dev/null || true
|
||||
|
||||
# Copy required shared libraries for parted
|
||||
mkdir -p /output/lib
|
||||
cp /lib/${LIB_DIR}/libparted.so* /output/lib/ 2>/dev/null || true
|
||||
cp /usr/lib/${LIB_DIR}/libparted.so* /output/lib/ 2>/dev/null || true
|
||||
cp /lib/${LIB_DIR}/libreadline.so* /output/lib/ 2>/dev/null || true
|
||||
cp /usr/lib/${LIB_DIR}/libreadline.so* /output/lib/ 2>/dev/null || true
|
||||
cp /lib/${LIB_DIR}/libdevmapper.so* /output/lib/ 2>/dev/null || true
|
||||
cp /usr/lib/${LIB_DIR}/libdevmapper.so* /output/lib/ 2>/dev/null || true
|
||||
|
||||
# List what parted actually needs
|
||||
ldd /usr/sbin/parted 2>/dev/null | grep "=>" | awk "{print \$3}" | while read lib; do
|
||||
[ -f "$lib" ] && cp "$lib" /output/lib/ 2>/dev/null || true
|
||||
done
|
||||
|
||||
echo "Libraries bundled:"
|
||||
ls -la /output/lib/
|
||||
'
|
||||
|
||||
# Copy tools to overlay
|
||||
cp "$TOOLS_DIR/parted" "$OVERLAY_DIR/usr/sbin/" 2>/dev/null || true
|
||||
cp "$TOOLS_DIR/mkfs.vfat" "$OVERLAY_DIR/usr/sbin/" 2>/dev/null || true
|
||||
cp "$TOOLS_DIR/mkfs.fat" "$OVERLAY_DIR/sbin/" 2>/dev/null || true
|
||||
cp "$TOOLS_DIR/mkfs.ext4" "$OVERLAY_DIR/usr/sbin/" 2>/dev/null || true
|
||||
cp "$TOOLS_DIR/mke2fs" "$OVERLAY_DIR/usr/sbin/" 2>/dev/null || true
|
||||
|
||||
# Copy shared libraries
|
||||
mkdir -p "$OVERLAY_DIR/usr/lib/${LIB_DIR}"
|
||||
cp "$TOOLS_DIR/lib/"*.so* "$OVERLAY_DIR/usr/lib/${LIB_DIR}/" 2>/dev/null || true
|
||||
|
||||
chmod +x "$OVERLAY_DIR/usr/sbin/"* 2>/dev/null || true
|
||||
chmod +x "$OVERLAY_DIR/sbin/"* 2>/dev/null || true
|
||||
echo " ✅ Partitioning tools and libraries bundled"
|
||||
|
||||
# Create the auto-start profile script
|
||||
cat > "$OVERLAY_DIR/etc/profile.d/z99-archipelago-installer.sh" <<'AUTOSTART'
|
||||
#!/bin/bash
|
||||
# Auto-start Archipelago installer on login
|
||||
|
||||
# Only run once
|
||||
if [ -n "$INSTALLER_STARTED" ]; then
|
||||
return 0 2>/dev/null || exit 0
|
||||
# Load font for graphical menu
|
||||
if loadfont /boot/grub/font.pf2; then
|
||||
set gfxmode=auto
|
||||
insmod gfxterm
|
||||
insmod png
|
||||
terminal_output gfxterm
|
||||
fi
|
||||
export INSTALLER_STARTED=1
|
||||
|
||||
# Give system a moment to settle
|
||||
sleep 1
|
||||
|
||||
clear
|
||||
echo ""
|
||||
echo " ╔═══════════════════════════════════════════════════════════════════╗"
|
||||
echo " ║ ║"
|
||||
echo " ║ 🏝️ ARCHIPELAGO BITCOIN NODE OS - INSTALLER ║"
|
||||
echo " ║ ║"
|
||||
echo " ╚═══════════════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
|
||||
# Find boot media
|
||||
BOOT_MEDIA=""
|
||||
for dev in /run/live/medium /lib/live/mount/medium /cdrom /media/cdrom; do
|
||||
if [ -f "$dev/archipelago/auto-install.sh" ]; then
|
||||
BOOT_MEDIA="$dev"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "$BOOT_MEDIA" ]; then
|
||||
echo " Found installer at: $BOOT_MEDIA"
|
||||
echo ""
|
||||
echo " Press Enter to start installation, or Ctrl+C for shell..."
|
||||
read
|
||||
sudo bash "$BOOT_MEDIA/archipelago/auto-install.sh"
|
||||
# Archipelago GRUB theme
|
||||
if [ -f /boot/grub/themes/archipelago/theme.txt ]; then
|
||||
# Load theme fonts
|
||||
loadfont /boot/grub/themes/archipelago/dejavu_12.pf2
|
||||
loadfont /boot/grub/themes/archipelago/dejavu_14.pf2
|
||||
loadfont /boot/grub/themes/archipelago/dejavu_16.pf2
|
||||
loadfont /boot/grub/themes/archipelago/dejavu_24.pf2
|
||||
set theme=/boot/grub/themes/archipelago/theme.txt
|
||||
else
|
||||
echo " ⚠️ Installer not found on boot media."
|
||||
echo ""
|
||||
echo " Checked: /run/live/medium, /lib/live/mount/medium, /cdrom"
|
||||
echo ""
|
||||
echo " You can try manually:"
|
||||
echo " sudo bash /path/to/archipelago/auto-install.sh"
|
||||
echo ""
|
||||
fi
|
||||
AUTOSTART
|
||||
chmod +x "$OVERLAY_DIR/etc/profile.d/z99-archipelago-installer.sh"
|
||||
|
||||
# Also create .bashrc that sources the profile script (belt and suspenders)
|
||||
cat > "$OVERLAY_DIR/etc/skel/.bashrc" <<'BASHRC'
|
||||
# ~/.bashrc: executed by bash(1) for non-login shells.
|
||||
|
||||
# If not running interactively, don't do anything
|
||||
case $- in
|
||||
*i*) ;;
|
||||
*) return;;
|
||||
esac
|
||||
|
||||
# Source profile.d scripts
|
||||
if [ -d /etc/profile.d ]; then
|
||||
for i in /etc/profile.d/*.sh; do
|
||||
if [ -r "$i" ]; then
|
||||
. "$i"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
BASHRC
|
||||
|
||||
# Create a wrapper script that can be called directly
|
||||
cat > "$OVERLAY_DIR/usr/local/bin/archipelago-install" <<'WRAPPER'
|
||||
#!/bin/bash
|
||||
# Archipelago installer wrapper
|
||||
|
||||
BOOT_MEDIA=""
|
||||
for dev in /run/live/medium /lib/live/mount/medium /cdrom /media/cdrom; do
|
||||
if [ -f "$dev/archipelago/auto-install.sh" ]; then
|
||||
BOOT_MEDIA="$dev"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "$BOOT_MEDIA" ]; then
|
||||
exec sudo bash "$BOOT_MEDIA/archipelago/auto-install.sh"
|
||||
else
|
||||
echo "Installer not found. Searched:"
|
||||
echo " /run/live/medium, /lib/live/mount/medium, /cdrom, /media/cdrom"
|
||||
exit 1
|
||||
fi
|
||||
WRAPPER
|
||||
chmod +x "$OVERLAY_DIR/usr/local/bin/archipelago-install"
|
||||
|
||||
# Create the squashfs module
|
||||
# Debian Live automatically loads all .squashfs files from live/ directory
|
||||
echo " Creating overlay squashfs module..."
|
||||
LIVE_DIR="$INSTALLER_ISO/live"
|
||||
mkdir -p "$LIVE_DIR"
|
||||
|
||||
# Check if mksquashfs is available (may need to use Docker on macOS)
|
||||
if command -v mksquashfs >/dev/null 2>&1; then
|
||||
mksquashfs "$OVERLAY_DIR" "$LIVE_DIR/99-archipelago.squashfs" -comp xz -noappend
|
||||
else
|
||||
# Use $CONTAINER_CMD to create squashfs on macOS
|
||||
echo " Using $CONTAINER_CMD to create squashfs..."
|
||||
$CONTAINER_CMD run --rm --platform $CONTAINER_PLATFORM \
|
||||
-v "$OVERLAY_DIR:/overlay:ro" \
|
||||
-v "$LIVE_DIR:/output" \
|
||||
debian:bookworm \
|
||||
bash -c "apt-get update && apt-get install -y squashfs-tools && mksquashfs /overlay /output/99-archipelago.squashfs -comp xz -noappend"
|
||||
set menu_color_normal=light-gray/black
|
||||
set menu_color_highlight=white/dark-gray
|
||||
fi
|
||||
|
||||
echo " ✅ Created overlay module: 99-archipelago.squashfs"
|
||||
menuentry "Install Archipelago" --hotkey=i {
|
||||
linux /live/vmlinuz quiet
|
||||
initrd /live/initrd.img
|
||||
}
|
||||
|
||||
# Modify GRUB config - update branding and ensure components are loaded
|
||||
if [ -f "$INSTALLER_ISO/boot/grub/grub.cfg" ]; then
|
||||
echo " Configuring GRUB..."
|
||||
sed -i.bak \
|
||||
-e 's/Debian GNU\/Linux/Archipelago Installer/g' \
|
||||
-e 's/Live system/Install Archipelago/g' \
|
||||
"$INSTALLER_ISO/boot/grub/grub.cfg"
|
||||
|
||||
# Ensure 'components' parameter is present (loads additional squashfs modules)
|
||||
# Also add 'username=user' to ensure consistent username
|
||||
if ! grep -q "components" "$INSTALLER_ISO/boot/grub/grub.cfg"; then
|
||||
sed -i 's/boot=live/boot=live components/' "$INSTALLER_ISO/boot/grub/grub.cfg"
|
||||
fi
|
||||
fi
|
||||
menuentry "Install Archipelago (verbose)" --hotkey=v {
|
||||
linux /live/vmlinuz
|
||||
initrd /live/initrd.img
|
||||
}
|
||||
|
||||
if [ -f "$INSTALLER_ISO/isolinux/live.cfg" ]; then
|
||||
echo " Configuring ISOLINUX..."
|
||||
sed -i.bak \
|
||||
-e 's/Debian GNU\/Linux/Archipelago Installer/g' \
|
||||
-e 's/Live system/Install Archipelago/g' \
|
||||
"$INSTALLER_ISO/isolinux/live.cfg"
|
||||
|
||||
# Add components parameter
|
||||
if ! grep -q "components" "$INSTALLER_ISO/isolinux/live.cfg"; then
|
||||
sed -i 's/boot=live/boot=live components/' "$INSTALLER_ISO/isolinux/live.cfg"
|
||||
fi
|
||||
fi
|
||||
menuentry "Boot from local disk" --hotkey=b {
|
||||
set root=(hd0)
|
||||
chainloader +1
|
||||
}
|
||||
GRUBCFG
|
||||
|
||||
if [ -f "$INSTALLER_ISO/isolinux/menu.cfg" ]; then
|
||||
sed -i.bak \
|
||||
-e 's/Debian GNU\/Linux/Archipelago Installer/g' \
|
||||
"$INSTALLER_ISO/isolinux/menu.cfg"
|
||||
fi
|
||||
# Create ISOLINUX configuration (legacy BIOS boot)
|
||||
echo " Writing ISOLINUX config..."
|
||||
cat > "$INSTALLER_ISO/isolinux/isolinux.cfg" <<'ISOCFG'
|
||||
UI menu.c32
|
||||
PROMPT 0
|
||||
TIMEOUT 50
|
||||
|
||||
MENU TITLE ARCHIPELAGO INSTALLER
|
||||
MENU COLOR border 30;44 #40ffffff #00000000 std
|
||||
MENU COLOR title 1;36;44 #ff00b7ff #00000000 std
|
||||
MENU COLOR sel 7;37;40 #ffffffff #ff333333 std
|
||||
MENU COLOR unsel 37;44 #ffaaaaaa #00000000 std
|
||||
|
||||
DEFAULT install
|
||||
|
||||
LABEL install
|
||||
MENU LABEL Install Archipelago
|
||||
KERNEL /live/vmlinuz
|
||||
APPEND initrd=/live/initrd.img quiet
|
||||
MENU DEFAULT
|
||||
|
||||
LABEL install-verbose
|
||||
MENU LABEL Install Archipelago (verbose)
|
||||
KERNEL /live/vmlinuz
|
||||
APPEND initrd=/live/initrd.img
|
||||
|
||||
LABEL local
|
||||
MENU LABEL Boot from local disk
|
||||
LOCALBOOT 0x80
|
||||
ISOCFG
|
||||
|
||||
echo " Step 5 complete (GRUB + ISOLINUX configured)"
|
||||
|
||||
# =============================================================================
|
||||
# STEP 6: Create final ISO
|
||||
# =============================================================================
|
||||
echo ""
|
||||
echo "📦 Step 6: Creating bootable ISO..."
|
||||
echo "Step 6: Creating bootable ISO..."
|
||||
|
||||
if [ "$UNBUNDLED" = "1" ]; then
|
||||
OUTPUT_ISO="$OUTPUT_DIR/archipelago-installer-unbundled-${ARCH}.iso"
|
||||
@@ -2458,60 +2515,27 @@ else
|
||||
OUTPUT_ISO="$OUTPUT_DIR/archipelago-installer-${ARCH}.iso"
|
||||
fi
|
||||
|
||||
# Extract MBR from original Debian Live ISO (most reliable for hybrid boot)
|
||||
# This preserves the exact MBR that makes the ISO work as a USB drive in Balena Etcher
|
||||
echo " Extracting hybrid MBR from original Debian Live ISO..."
|
||||
# Use ISOLINUX isohdpfx.bin for hybrid USB boot (built in Step 2)
|
||||
ISOHDPFX="$WORK_DIR/isohdpfx.bin"
|
||||
dd if="$BASE_ISO" bs=1 count=432 of="$ISOHDPFX" 2>/dev/null
|
||||
|
||||
# Verify we got a valid MBR (should be 432 bytes)
|
||||
ISOHDPFX_SIZE=$(stat -c%s "$ISOHDPFX" 2>/dev/null || stat -f%z "$ISOHDPFX" 2>/dev/null || echo 0)
|
||||
if [ "$ISOHDPFX_SIZE" -ne 432 ]; then
|
||||
echo " ⚠️ MBR extraction unexpected size ($ISOHDPFX_SIZE), trying syslinux paths..."
|
||||
if [ ! -f "$ISOHDPFX" ]; then
|
||||
# Fallback to system-installed copy
|
||||
for path in \
|
||||
"/usr/lib/ISOLINUX/isohdpfx.bin" \
|
||||
"/usr/share/syslinux/isohdpfx.bin" \
|
||||
"/usr/local/share/syslinux/isohdpfx.bin"; do
|
||||
if [ -f "$path" ]; then
|
||||
ISOHDPFX="$path"
|
||||
echo " Using $path"
|
||||
echo " Using system isohdpfx.bin: $path"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Find the EFI boot image — 7z may extract it to different locations
|
||||
EFI_IMG=""
|
||||
for efi_path in \
|
||||
"$INSTALLER_ISO/boot/grub/efi.img" \
|
||||
"$INSTALLER_ISO/EFI/boot/efi.img" \
|
||||
"$INSTALLER_ISO/efi.img"; do
|
||||
if [ -f "$efi_path" ]; then
|
||||
EFI_IMG="$efi_path"
|
||||
break
|
||||
fi
|
||||
done
|
||||
# EFI boot image was built in Step 2
|
||||
EFI_IMG="$INSTALLER_ISO/boot/grub/efi.img"
|
||||
|
||||
# If no standalone efi.img, check for [BOOT] directory from 7z extraction
|
||||
if [ -z "$EFI_IMG" ] && [ -d "$INSTALLER_ISO/[BOOT]" ]; then
|
||||
# 7z extracts El Torito boot images into [BOOT]/ — the EFI image is usually entry 2
|
||||
for entry in "$INSTALLER_ISO/[BOOT]/"*; do
|
||||
# EFI images are typically > 1MB FAT filesystems
|
||||
if [ -f "$entry" ]; then
|
||||
entry_size=$(stat -c%s "$entry" 2>/dev/null || stat -f%z "$entry" 2>/dev/null || echo 0)
|
||||
if [ "$entry_size" -gt 1048576 ]; then
|
||||
mkdir -p "$INSTALLER_ISO/boot/grub"
|
||||
cp "$entry" "$INSTALLER_ISO/boot/grub/efi.img"
|
||||
EFI_IMG="$INSTALLER_ISO/boot/grub/efi.img"
|
||||
echo " Recovered EFI image from [BOOT] directory"
|
||||
break
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ -z "$EFI_IMG" ]; then
|
||||
echo " ⚠️ No EFI boot image found — ISO will only support Legacy BIOS boot"
|
||||
if [ ! -f "$EFI_IMG" ]; then
|
||||
echo " WARNING: No EFI boot image — ISO will only support Legacy BIOS boot"
|
||||
xorriso -as mkisofs -o "$OUTPUT_ISO" \
|
||||
-volid "ARCHIPELAGO" \
|
||||
-iso-level 3 \
|
||||
@@ -2523,8 +2547,6 @@ if [ -z "$EFI_IMG" ]; then
|
||||
-partition_offset 16 \
|
||||
"$INSTALLER_ISO"
|
||||
else
|
||||
# Make EFI path relative to INSTALLER_ISO for xorriso
|
||||
EFI_REL="${EFI_IMG#$INSTALLER_ISO/}"
|
||||
xorriso -as mkisofs -o "$OUTPUT_ISO" \
|
||||
-volid "ARCHIPELAGO" \
|
||||
-iso-level 3 \
|
||||
@@ -2534,7 +2556,7 @@ else
|
||||
-b isolinux/isolinux.bin \
|
||||
-no-emul-boot -boot-load-size 4 -boot-info-table \
|
||||
-eltorito-alt-boot \
|
||||
-e "$EFI_REL" \
|
||||
-e boot/grub/efi.img \
|
||||
-no-emul-boot \
|
||||
-isohybrid-gpt-basdat \
|
||||
-partition_offset 16 \
|
||||
@@ -2543,43 +2565,19 @@ fi
|
||||
|
||||
echo ""
|
||||
if [ "$UNBUNDLED" = "1" ]; then
|
||||
echo "╔════════════════════════════════════════════════════════════════╗"
|
||||
echo "║ ✅ UNBUNDLED AUTO-INSTALLER ISO CREATED! ║"
|
||||
echo "╚════════════════════════════════════════════════════════════════╝"
|
||||
echo "UNBUNDLED AUTO-INSTALLER ISO CREATED"
|
||||
echo ""
|
||||
echo "📀 Output: $OUTPUT_ISO"
|
||||
echo " Size: $(du -h "$OUTPUT_ISO" | cut -f1)"
|
||||
echo ""
|
||||
echo "🔥 Lightweight installer — apps downloaded on-demand!"
|
||||
echo ""
|
||||
echo "Features:"
|
||||
echo " • Pre-built system (no internet needed during install)"
|
||||
echo " • Auto-detects internal disk"
|
||||
echo " • One-button installation"
|
||||
echo " • Boots directly to Archipelago after install"
|
||||
echo " • NO pre-bundled apps (smaller ISO)"
|
||||
echo " • Install any app from the Marketplace (internet required)"
|
||||
echo " Output: $OUTPUT_ISO"
|
||||
echo " Size: $(du -h "$OUTPUT_ISO" | cut -f1)"
|
||||
echo ""
|
||||
echo " Lightweight installer -- apps downloaded on-demand from Marketplace"
|
||||
else
|
||||
echo "╔════════════════════════════════════════════════════════════════╗"
|
||||
echo "║ ✅ AUTO-INSTALLER ISO CREATED! ║"
|
||||
echo "╚════════════════════════════════════════════════════════════════╝"
|
||||
echo "AUTO-INSTALLER ISO CREATED"
|
||||
echo ""
|
||||
echo "📀 Output: $OUTPUT_ISO"
|
||||
echo " Size: $(du -h "$OUTPUT_ISO" | cut -f1)"
|
||||
echo ""
|
||||
echo "🔥 This is a StartOS-like automatic installer!"
|
||||
echo ""
|
||||
echo "Features:"
|
||||
echo " • Pre-built system (no internet needed during install)"
|
||||
echo " • Auto-detects internal disk"
|
||||
echo " • One-button installation"
|
||||
echo " • Boots directly to Archipelago after install"
|
||||
echo " • Pre-bundled container apps:"
|
||||
echo " - Bitcoin Knots v29"
|
||||
echo " - LND v0.18.4"
|
||||
echo " - Home Assistant"
|
||||
echo " Output: $OUTPUT_ISO"
|
||||
echo " Size: $(du -h "$OUTPUT_ISO" | cut -f1)"
|
||||
echo ""
|
||||
echo " Full installer with pre-bundled container apps"
|
||||
fi
|
||||
echo "To create USB:"
|
||||
echo " 1. Flash with: sudo dd if=$OUTPUT_ISO of=/dev/rdiskX bs=4m"
|
||||
|
||||
Reference in New Issue
Block a user