#!/bin/bash # Build proper Alpine ISO with Archipelago overlay (apkovl method) set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ALPINE_VERSION="${ALPINE_VERSION:-3.19}" ARCH="${ARCH:-x86_64}" WORK_DIR="$SCRIPT_DIR/build/overlay-iso" OUTPUT_DIR="$SCRIPT_DIR/results" echo "🏔️ Building Archipelago ISO using Alpine overlay method" echo "" echo "📋 Configuration:" echo " Alpine Version: $ALPINE_VERSION" echo " Architecture: $ARCH" echo "" # Create work directories mkdir -p "$WORK_DIR" mkdir -p "$OUTPUT_DIR" # Download base Alpine ISO if not exists BASE_ISO="$WORK_DIR/alpine-standard-${ALPINE_VERSION}.0-${ARCH}.iso" if [ ! -f "$BASE_ISO" ]; then echo "📥 Downloading Alpine base ISO..." curl -L -o "$BASE_ISO" \ "https://dl-cdn.alpinelinux.org/alpine/v${ALPINE_VERSION}/releases/${ARCH}/alpine-standard-${ALPINE_VERSION}.0-${ARCH}.iso" echo "✅ Downloaded base ISO" else echo "✅ Using cached base ISO" fi # Create overlay structure echo "📦 Creating Archipelago overlay..." OVERLAY_DIR="$WORK_DIR/overlay" rm -rf "$OVERLAY_DIR" mkdir -p "$OVERLAY_DIR" # Create overlay root OVERLAY_ROOT="$OVERLAY_DIR/archipelago-overlay" mkdir -p "$OVERLAY_ROOT"/{etc,root,usr/local/bin,var/lib/archipelago,home/archipelago} # Copy Archipelago backend if available BACKEND_BIN="$SCRIPT_DIR/build/backend/archipelago" if [ -f "$BACKEND_BIN" ]; then echo "🦀 Including Archipelago backend..." cp "$BACKEND_BIN" "$OVERLAY_ROOT/usr/local/bin/" chmod +x "$OVERLAY_ROOT/usr/local/bin/archipelago" fi # Copy Archipelago frontend if available FRONTEND_DIR="$SCRIPT_DIR/build/frontend" if [ -d "$FRONTEND_DIR" ]; then echo "🎨 Including Archipelago frontend..." mkdir -p "$OVERLAY_ROOT/usr/share/archipelago/web" cp -r "$FRONTEND_DIR"/* "$OVERLAY_ROOT/usr/share/archipelago/web/" fi # Copy app manifests APPS_DIR="$SCRIPT_DIR/../apps" if [ -d "$APPS_DIR" ]; then echo "📦 Including app manifests..." mkdir -p "$OVERLAY_ROOT/var/lib/archipelago/manifests" find "$APPS_DIR" -maxdepth 1 -type d -exec test -f {}/manifest.yml \; \ -exec cp -r {} "$OVERLAY_ROOT/var/lib/archipelago/manifests/" \; fi # Create installation script in overlay cat > "$OVERLAY_ROOT/root/install-archipelago.sh" <<'INSTALL_SCRIPT' #!/bin/sh # Archipelago installation script set -e echo "🏝️ Installing Archipelago Bitcoin Node OS" echo "" # Install required packages echo "📦 Installing packages..." apk add --no-cache \ podman \ crun \ fuse-overlayfs \ slirp4netns \ nginx \ openssh \ iptables \ iproute2 \ bash \ curl # Create archipelago user echo "👤 Creating archipelago user..." if ! id archipelago >/dev/null 2>&1; then adduser -D -s /bin/bash archipelago echo "archipelago:archipelago" | chpasswd fi # Setup data directories echo "📁 Creating data directories..." mkdir -p /var/lib/archipelago/{apps,secrets,logs,backups} chown -R archipelago:archipelago /var/lib/archipelago # Install backend if available if [ -f /usr/local/bin/archipelago ]; then echo "✅ Archipelago backend installed" fi # Configure nginx for frontend if [ -d /usr/share/archipelago/web ]; then echo "🎨 Configuring web UI..." cat > /etc/nginx/http.d/archipelago.conf <<'NGINX_EOF' server { listen 8100; server_name _; root /usr/share/archipelago/web; index index.html; location / { try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://127.0.0.1:8101/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } } NGINX_EOF rc-update add nginx default fi # Create Archipelago service if [ -f /usr/local/bin/archipelago ]; then cat > /etc/init.d/archipelago <<'SERVICE_EOF' #!/sbin/openrc-run name="Archipelago" description="Archipelago Bitcoin Node OS Backend" command="/usr/local/bin/archipelago" command_background=true pidfile="/run/archipelago.pid" depend() { need net after networking } SERVICE_EOF chmod +x /etc/init.d/archipelago rc-update add archipelago default fi # Configure networking echo "🌐 Configuring network..." setup-interfaces -a # Enable services rc-update add sshd default echo "" echo "✅ Archipelago installation complete!" echo "" echo "Next steps:" echo " 1. Reboot the system" echo " 2. Login as: archipelago / archipelago" echo " 3. Change password: passwd" echo " 4. Access UI: http://:8100" echo "" INSTALL_SCRIPT chmod +x "$OVERLAY_ROOT/root/install-archipelago.sh" # Create Alpine local.d boot script to show message mkdir -p "$OVERLAY_ROOT/etc/local.d" cat > "$OVERLAY_ROOT/etc/local.d/00-archipelago-welcome.start" <<'WELCOME_EOF' #!/bin/sh cat <<'MSG' ╔═══════════════════════════════════════════════════════════╗ ║ ║ ║ 🏝️ ARCHIPELAGO BITCOIN NODE OS ║ ║ ║ ║ To install to disk, login as root and run: ║ ║ ║ ║ # setup-alpine ║ ║ # /root/install-archipelago.sh ║ ║ ║ ╚═══════════════════════════════════════════════════════════╝ MSG WELCOME_EOF chmod +x "$OVERLAY_ROOT/etc/local.d/00-archipelago-welcome.start" # Create the overlay tarball (apkovl) echo "📦 Creating overlay tarball..." cd "$OVERLAY_DIR" tar czf archipelago.apkovl.tar.gz archipelago-overlay/ echo "✅ Overlay created: $(du -h archipelago.apkovl.tar.gz | cut -f1)" # Mount the base ISO and copy it with our overlay echo "📀 Creating final ISO with overlay..." ISO_MOUNT="$WORK_DIR/mnt" ISO_CUSTOM="$WORK_DIR/custom" mkdir -p "$ISO_MOUNT" "$ISO_CUSTOM" # Extract base ISO if command -v 7z >/dev/null 2>&1; then 7z x "$BASE_ISO" -o"$ISO_CUSTOM" -y >/dev/null elif [[ "$OSTYPE" == "darwin"* ]]; then hdiutil attach "$BASE_ISO" -mountpoint "$ISO_MOUNT" -readonly rsync -a "$ISO_MOUNT"/ "$ISO_CUSTOM"/ hdiutil detach "$ISO_MOUNT" fi # Copy Archipelago files directly to ISO (skip apkovl, put files in accessible location) echo "📋 Adding Archipelago files to ISO..." mkdir -p "$ISO_CUSTOM/archipelago" cp "$OVERLAY_DIR/archipelago.apkovl.tar.gz" "$ISO_CUSTOM/archipelago/" # Also extract directly to archipelago folder for easy access cd "$OVERLAY_DIR" tar xzf archipelago.apkovl.tar.gz cp -r archipelago-overlay/* "$ISO_CUSTOM/archipelago/" # CRITICAL: Add .boot_repository marker so Alpine's nlplug-findfs can find the boot media # This tells the initramfs that this is a valid Alpine boot repository echo "📍 Marking ISO as boot repository..." touch "$ISO_CUSTOM/.boot_repository" # Also mark the apks directories at all levels if [ -d "$ISO_CUSTOM/apks" ]; then touch "$ISO_CUSTOM/apks/.boot_repository" fi if [ -d "$ISO_CUSTOM/apks/x86_64" ]; then touch "$ISO_CUSTOM/apks/x86_64/.boot_repository" fi # Create a simple first-boot setup script cat > "$ISO_CUSTOM/archipelago/setup-archipelago.sh" <<'SETUP_EOF' #!/bin/sh # Archipelago first-boot setup set -e echo "🏝️ Setting up Archipelago overlay..." # Copy files from CD to root if [ -d /media/cdrom/archipelago/archipelago-overlay ]; then cp -r /media/cdrom/archipelago/archipelago-overlay/* / echo "✅ Archipelago files installed" elif [ -d /media/cdrom/archipelago/root ]; then cp -r /media/cdrom/archipelago/* / echo "✅ Archipelago files installed" fi # Run the installer if it exists if [ -f /root/install-archipelago.sh ]; then echo "" echo "Archipelago is now available!" echo "Run: /root/install-archipelago.sh" fi SETUP_EOF chmod +x "$ISO_CUSTOM/archipelago/setup-archipelago.sh" # Modify boot configs (remove apkovl parameter, use normal boot) echo "⚙️ Configuring boot..." # Modify boot configs to add USB delay for better hardware compatibility # Keep Alpine's boot logic intact, just add timing parameters # HP ProDesk likely boots UEFI (GRUB), so we need to modify both configs if [ -f "$ISO_CUSTOM/boot/grub/grub.cfg" ]; then # UEFI boot (GRUB) - add usbdelay and debug sed -i.bak \ -e 's/Alpine Linux/Archipelago Bitcoin Node OS/g' \ -e 's/quiet/usbdelay=5 debug_init/' \ "$ISO_CUSTOM/boot/grub/grub.cfg" fi if [ -f "$ISO_CUSTOM/boot/syslinux/syslinux.cfg" ]; then # Legacy BIOS boot (Syslinux) - add usbdelay and debug sed -i.bak \ -e 's/Alpine Linux/Archipelago Bitcoin Node OS/g' \ -e 's/quiet/usbdelay=5 debug_init/' \ "$ISO_CUSTOM/boot/syslinux/syslinux.cfg" fi # Update MOTD to show Archipelago instructions cat > "$ISO_CUSTOM/.alpine-release" <<'MOTD_EOF' 3.19.0 MOTD_EOF mkdir -p "$ISO_CUSTOM/etc" cat > "$ISO_CUSTOM/etc/motd" <<'MOTD_EOF' ╔═══════════════════════════════════════════════════════════╗ ║ ║ ║ 🏝️ ARCHIPELAGO BITCOIN NODE OS ║ ║ ║ ║ To set up Archipelago, run: ║ ║ # sh /media/cdrom/archipelago/setup-archipelago.sh ║ ║ ║ ║ Then install to disk with: ║ ║ # setup-alpine ║ ║ ║ ╚═══════════════════════════════════════════════════════════╝ MOTD_EOF # Create final ISO OUTPUT_ISO="$OUTPUT_DIR/archipelago-${ALPINE_VERSION}-hp-prodesk-uefi-x86_64.iso" echo "" echo "🔥 Creating final bootable ISO..." if [[ "$OSTYPE" == "darwin"* ]]; then if command -v xorriso >/dev/null 2>&1; then xorriso -as mkisofs -o "$OUTPUT_ISO" \ -volid "ARCHIPELAGO" \ -J -R \ -c boot/syslinux/boot.cat \ -b boot/syslinux/isolinux.bin \ -no-emul-boot -boot-load-size 4 -boot-info-table \ -eltorito-alt-boot \ -e boot/grub/efi.img \ -no-emul-boot \ -isohybrid-gpt-basdat \ -isohybrid-mbr "$ISO_CUSTOM/boot/syslinux/isohdpfx.bin" \ "$ISO_CUSTOM" 2>&1 | grep -v "xorriso : UPDATE" fi fi echo "" echo "✅ ISO created successfully!" echo "" echo "📀 Output: $OUTPUT_ISO" echo " Size: $(du -h "$OUTPUT_ISO" | cut -f1)" echo "" echo "📝 This ISO uses Alpine's overlay system (apkovl)" echo " The overlay will be automatically loaded at boot" echo ""