354 lines
11 KiB
Bash
354 lines
11 KiB
Bash
|
|
#!/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://<your-ip>: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 ""
|