- Updated Cargo.toml to remove unnecessary package backtrace optimizations. - Changed default bind host and port in config.rs for broader accessibility. - Renamed state_manager to _state_manager in server.rs for clarity. - Updated user field to _user in PodmanClient and DockerRuntime for consistency. - Modified build-debian-iso.sh to enhance welcome message and backend startup instructions. - Improved archipelago-menu.sh to display backend status and updated Web UI URL. - Enhanced install-to-disk.sh for better package management and user creation during installation.
512 lines
19 KiB
Bash
Executable File
512 lines
19 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# Build Archipelago Bitcoin Node OS ISO - Debian Live Edition
|
|
# Based on Debian Live for reliable USB boot (like StartOS)
|
|
#
|
|
# Usage: ./build-debian-iso.sh
|
|
#
|
|
|
|
set -e
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
WORK_DIR="$SCRIPT_DIR/build/debian-iso"
|
|
OUTPUT_DIR="$SCRIPT_DIR/results"
|
|
DEBIAN_VERSION="bookworm"
|
|
ARCH="amd64"
|
|
|
|
echo "╔════════════════════════════════════════════════════════╗"
|
|
echo "║ Building Archipelago - Debian Live Edition ║"
|
|
echo "╚════════════════════════════════════════════════════════╝"
|
|
echo ""
|
|
|
|
# Create directories
|
|
mkdir -p "$WORK_DIR"
|
|
mkdir -p "$OUTPUT_DIR"
|
|
|
|
# Download Debian Live ISO if not exists
|
|
BASE_ISO="$WORK_DIR/debian-live-12-${ARCH}-standard.iso"
|
|
if [ ! -f "$BASE_ISO" ] || [ $(stat -f%z "$BASE_ISO" 2>/dev/null || echo 0) -lt 100000000 ]; then
|
|
echo "📥 Downloading Debian Live 12 (Bookworm) Standard ISO..."
|
|
rm -f "$BASE_ISO"
|
|
# Use SourceForge respin which has up-to-date Debian 12 Live
|
|
curl -L -o "$BASE_ISO" \
|
|
"https://sourceforge.net/projects/debian-live-respin-iso/files/standard/live-image-debian12.11-standard-20250522-amd64.hybrid.iso/download"
|
|
echo "✅ Downloaded Debian Live ISO"
|
|
else
|
|
echo "✅ Using cached Debian Live ISO"
|
|
fi
|
|
|
|
# Extract ISO
|
|
echo ""
|
|
echo "📦 Extracting Debian Live ISO..."
|
|
ISO_CUSTOM="$WORK_DIR/custom"
|
|
rm -rf "$ISO_CUSTOM"
|
|
mkdir -p "$ISO_CUSTOM"
|
|
|
|
cd "$ISO_CUSTOM"
|
|
7z x -y "$BASE_ISO" >/dev/null 2>&1 || 7z x -y "$BASE_ISO"
|
|
|
|
echo "✅ Extracted ISO"
|
|
|
|
# Add Archipelago files
|
|
echo ""
|
|
echo "📋 Adding Archipelago files..."
|
|
|
|
ARCHIPELAGO_DIR="$ISO_CUSTOM/archipelago"
|
|
mkdir -p "$ARCHIPELAGO_DIR"
|
|
mkdir -p "$ARCHIPELAGO_DIR/bin"
|
|
mkdir -p "$ARCHIPELAGO_DIR/scripts"
|
|
|
|
# Copy the pre-built backend if it exists
|
|
if [ -d "$SCRIPT_DIR/../core/target/release" ]; then
|
|
echo "🦀 Including Archipelago backend..."
|
|
cp "$SCRIPT_DIR/../core/target/release/archipelago" "$ARCHIPELAGO_DIR/bin/" 2>/dev/null || true
|
|
fi
|
|
|
|
# Copy the frontend build if it exists
|
|
if [ -d "$SCRIPT_DIR/../web/dist/neode-ui" ]; then
|
|
echo "🎨 Including Archipelago Web UI..."
|
|
cp -r "$SCRIPT_DIR/../web/dist/neode-ui" "$ARCHIPELAGO_DIR/web-ui"
|
|
elif [ -d "$SCRIPT_DIR/../neode-ui/dist" ]; then
|
|
echo "🎨 Including Archipelago frontend..."
|
|
cp -r "$SCRIPT_DIR/../neode-ui/dist" "$ARCHIPELAGO_DIR/web-ui" 2>/dev/null || true
|
|
fi
|
|
|
|
# Copy app manifests
|
|
if [ -d "$SCRIPT_DIR/../apps" ]; then
|
|
echo "📦 Including app manifests..."
|
|
cp -r "$SCRIPT_DIR/../apps" "$ARCHIPELAGO_DIR/apps" 2>/dev/null || true
|
|
fi
|
|
|
|
# Copy setup scripts
|
|
if [ -d "$SCRIPT_DIR/archipelago-scripts" ]; then
|
|
echo "📜 Including setup scripts..."
|
|
cp "$SCRIPT_DIR/archipelago-scripts/"*.sh "$ARCHIPELAGO_DIR/scripts/" 2>/dev/null || true
|
|
chmod +x "$ARCHIPELAGO_DIR/scripts/"*.sh
|
|
fi
|
|
|
|
# Create main setup script for Archipelago
|
|
cat > "$ARCHIPELAGO_DIR/setup-archipelago.sh" <<'SETUP_EOF'
|
|
#!/bin/bash
|
|
#
|
|
# Archipelago Setup Script for Debian Live
|
|
#
|
|
echo ""
|
|
echo "╔═══════════════════════════════════════════════════════════╗"
|
|
echo "║ 🏝️ ARCHIPELAGO BITCOIN NODE OS - Debian Edition ║"
|
|
echo "╚═══════════════════════════════════════════════════════════╝"
|
|
echo ""
|
|
|
|
# Find the boot media
|
|
BOOT_MEDIA=""
|
|
for dev in /run/live/medium /lib/live/mount/medium /cdrom /media/cdrom; do
|
|
if [ -d "$dev/archipelago" ]; then
|
|
BOOT_MEDIA="$dev"
|
|
break
|
|
fi
|
|
done
|
|
|
|
if [ -z "$BOOT_MEDIA" ]; then
|
|
echo "❌ Could not find Archipelago files on boot media"
|
|
echo " Looking in: /run/live/medium, /lib/live/mount/medium, /cdrom"
|
|
exit 1
|
|
fi
|
|
|
|
echo "📍 Found Archipelago at: $BOOT_MEDIA/archipelago"
|
|
echo ""
|
|
|
|
# Copy files to system
|
|
if [ -d "$BOOT_MEDIA/archipelago/bin" ]; then
|
|
echo "📋 Installing Archipelago binaries..."
|
|
sudo cp -r "$BOOT_MEDIA/archipelago/bin/"* /usr/local/bin/ 2>/dev/null || true
|
|
fi
|
|
|
|
if [ -d "$BOOT_MEDIA/archipelago/apps" ]; then
|
|
echo "📋 Installing app manifests..."
|
|
sudo mkdir -p /etc/archipelago
|
|
sudo cp -r "$BOOT_MEDIA/archipelago/apps" /etc/archipelago/ 2>/dev/null || true
|
|
fi
|
|
|
|
if [ -d "$BOOT_MEDIA/archipelago/scripts" ]; then
|
|
echo "📋 Installing setup scripts..."
|
|
sudo mkdir -p /opt/archipelago
|
|
sudo cp -r "$BOOT_MEDIA/archipelago/scripts" /opt/archipelago/ 2>/dev/null || true
|
|
sudo chmod +x /opt/archipelago/scripts/*.sh
|
|
fi
|
|
|
|
echo ""
|
|
echo "✅ Archipelago installed!"
|
|
echo ""
|
|
|
|
# Automatically launch the menu
|
|
sleep 1
|
|
exec /opt/archipelago/scripts/archipelago-menu.sh
|
|
SETUP_EOF
|
|
|
|
chmod +x "$ARCHIPELAGO_DIR/setup-archipelago.sh"
|
|
|
|
# Create auto-start script that runs on login
|
|
cat > "$ARCHIPELAGO_DIR/auto-start.sh" <<'AUTOSTART_EOF'
|
|
#!/bin/bash
|
|
#
|
|
# Archipelago Auto-Start - Runs on first login
|
|
#
|
|
|
|
# Find boot media
|
|
BOOT_MEDIA=""
|
|
for dev in /run/live/medium /lib/live/mount/medium /cdrom; do
|
|
if [ -d "$dev/archipelago" ]; then
|
|
BOOT_MEDIA="$dev"
|
|
break
|
|
fi
|
|
done
|
|
|
|
# Install essential tools on first boot (required for disk installer)
|
|
if [ ! -f /tmp/.archipelago-tools-installed ]; then
|
|
clear
|
|
echo ""
|
|
echo " ╔═══════════════════════════════════════════════════════════╗"
|
|
echo " ║ 🏝️ ARCHIPELAGO - First Boot Setup ║"
|
|
echo " ╚═══════════════════════════════════════════════════════════╝"
|
|
echo ""
|
|
echo " 📦 Installing required tools..."
|
|
echo ""
|
|
|
|
# Update and install essential tools
|
|
sudo apt-get update -qq 2>/dev/null
|
|
sudo apt-get install -y parted debootstrap dosfstools e2fsprogs 2>/dev/null
|
|
|
|
echo " ✅ Tools installed"
|
|
touch /tmp/.archipelago-tools-installed
|
|
sleep 1
|
|
fi
|
|
|
|
# Get IP address
|
|
IP=$(hostname -I 2>/dev/null | awk '{print $1}')
|
|
|
|
# Start web UI in background if not already running
|
|
if [ -n "$BOOT_MEDIA" ] && ! pgrep -f "http.server" >/dev/null; then
|
|
WEB_UI_DIR="$BOOT_MEDIA/archipelago/web-ui"
|
|
if [ -d "$WEB_UI_DIR" ]; then
|
|
cd "$WEB_UI_DIR"
|
|
nohup python3 -m http.server 80 --bind 0.0.0.0 >/dev/null 2>&1 &
|
|
fi
|
|
fi
|
|
|
|
clear
|
|
echo ""
|
|
echo " ╔═══════════════════════════════════════════════════════════╗"
|
|
echo " ║ ║"
|
|
echo " ║ 🏝️ ARCHIPELAGO BITCOIN NODE OS ║"
|
|
echo " ║ ║"
|
|
echo " ║ Your sovereign Bitcoin infrastructure ║"
|
|
echo " ║ ║"
|
|
echo " ╚═══════════════════════════════════════════════════════════╝"
|
|
echo ""
|
|
if [ -n "$IP" ]; then
|
|
echo " ┌─────────────────────────────────────────────────────────────┐"
|
|
echo " │ 🌐 Web UI: http://$IP "
|
|
echo " └─────────────────────────────────────────────────────────────┘"
|
|
echo ""
|
|
fi
|
|
echo " Type 'archipelago' to open the setup menu"
|
|
echo ""
|
|
|
|
# Check if already set up
|
|
if [ -f ~/.archipelago-setup-done ]; then
|
|
return 2>/dev/null || exit 0
|
|
fi
|
|
|
|
# First time - run setup automatically
|
|
if [ -n "$BOOT_MEDIA" ] && [ -f "$BOOT_MEDIA/archipelago/setup-archipelago.sh" ]; then
|
|
echo ""
|
|
read -p " Press Enter to continue to setup menu..."
|
|
bash "$BOOT_MEDIA/archipelago/setup-archipelago.sh"
|
|
fi
|
|
AUTOSTART_EOF
|
|
|
|
chmod +x "$ARCHIPELAGO_DIR/auto-start.sh"
|
|
|
|
# Create a simple 'archipelago-menu' command wrapper (don't overwrite the backend binary!)
|
|
cat > "$ARCHIPELAGO_DIR/bin/archipelago-menu" <<'CMD_EOF'
|
|
#!/bin/bash
|
|
# Archipelago menu command - launches the setup menu
|
|
|
|
if [ -f /opt/archipelago/scripts/archipelago-menu.sh ]; then
|
|
exec /opt/archipelago/scripts/archipelago-menu.sh
|
|
else
|
|
# Find on boot media
|
|
for dev in /run/live/medium /lib/live/mount/medium /cdrom; do
|
|
if [ -f "$dev/archipelago/scripts/archipelago-menu.sh" ]; then
|
|
exec bash "$dev/archipelago/scripts/archipelago-menu.sh"
|
|
fi
|
|
done
|
|
echo "Archipelago menu not found. Run setup first:"
|
|
echo " sh /run/live/medium/archipelago/setup-archipelago.sh"
|
|
fi
|
|
CMD_EOF
|
|
|
|
chmod +x "$ARCHIPELAGO_DIR/bin/archipelago-menu"
|
|
|
|
# Verify the real backend binary is there
|
|
if [ -f "$ARCHIPELAGO_DIR/bin/archipelago" ]; then
|
|
echo " Backend binary: $(file "$ARCHIPELAGO_DIR/bin/archipelago" | grep -o 'ELF.*' || echo 'included')"
|
|
fi
|
|
|
|
# Create SSH auto-start script for live environment
|
|
mkdir -p "$ISO_CUSTOM/etc/live/config.conf.d"
|
|
cat > "$ISO_CUSTOM/etc/live/config.conf.d/archipelago.conf" <<'LIVE_CONF_EOF'
|
|
# Archipelago live config
|
|
LIVE_HOSTNAME="archipelago"
|
|
LIVE_USER_DEFAULT_GROUPS="audio cdrom dip floppy video plugdev netdev powerdev scanner bluetooth sudo"
|
|
LIVE_CONF_EOF
|
|
|
|
# Create rc.local to start SSH on boot (works in live environment)
|
|
mkdir -p "$ISO_CUSTOM/etc/rc.local.d"
|
|
cat > "$ISO_CUSTOM/etc/rc.local.d/archipelago-ssh.sh" <<'RCLOCAL_EOF'
|
|
#!/bin/bash
|
|
# Enable SSH in live environment
|
|
|
|
# Install and start SSH if not running
|
|
if ! systemctl is-active --quiet ssh 2>/dev/null; then
|
|
# Try to start SSH (may already be installed)
|
|
systemctl start ssh 2>/dev/null || true
|
|
|
|
# If SSH not installed, install it
|
|
if ! command -v sshd >/dev/null 2>&1; then
|
|
apt-get update -qq
|
|
apt-get install -y openssh-server
|
|
systemctl start ssh
|
|
fi
|
|
fi
|
|
|
|
# Set password for user (live user is typically 'user' with empty password)
|
|
echo "user:archipelago" | chpasswd 2>/dev/null || true
|
|
echo "root:archipelago" | chpasswd 2>/dev/null || true
|
|
|
|
# Allow password auth
|
|
sed -i 's/#PasswordAuthentication.*/PasswordAuthentication yes/' /etc/ssh/sshd_config 2>/dev/null
|
|
sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/' /etc/ssh/sshd_config 2>/dev/null
|
|
systemctl restart ssh 2>/dev/null || true
|
|
RCLOCAL_EOF
|
|
chmod +x "$ISO_CUSTOM/etc/rc.local.d/archipelago-ssh.sh"
|
|
|
|
# Also create a systemd service that runs early
|
|
mkdir -p "$ISO_CUSTOM/etc/systemd/system"
|
|
cat > "$ISO_CUSTOM/etc/systemd/system/archipelago-ssh.service" <<'SERVICE_EOF'
|
|
[Unit]
|
|
Description=Archipelago SSH Setup
|
|
After=network-online.target
|
|
Wants=network-online.target
|
|
|
|
[Service]
|
|
Type=oneshot
|
|
ExecStart=/bin/bash -c 'apt-get update -qq && apt-get install -y openssh-server && echo "user:archipelago" | chpasswd && echo "root:archipelago" | chpasswd && sed -i "s/#PasswordAuthentication.*/PasswordAuthentication yes/" /etc/ssh/sshd_config && sed -i "s/PasswordAuthentication no/PasswordAuthentication yes/" /etc/ssh/sshd_config && systemctl restart ssh'
|
|
RemainAfterExit=yes
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
SERVICE_EOF
|
|
|
|
# Enable the service
|
|
mkdir -p "$ISO_CUSTOM/etc/systemd/system/multi-user.target.wants"
|
|
ln -sf ../archipelago-ssh.service "$ISO_CUSTOM/etc/systemd/system/multi-user.target.wants/archipelago-ssh.service"
|
|
|
|
# Create system-wide profile script that runs on ANY login
|
|
mkdir -p "$ISO_CUSTOM/etc/profile.d"
|
|
cat > "$ISO_CUSTOM/etc/profile.d/z99-archipelago.sh" <<'PROFILE_EOF'
|
|
#!/bin/bash
|
|
# Archipelago auto-start - runs on login (z99 = runs last)
|
|
|
|
# Only run once per session and only in interactive shells
|
|
if [ -n "$ARCHIPELAGO_STARTED" ] || [ ! -t 0 ]; then
|
|
return 0 2>/dev/null || exit 0
|
|
fi
|
|
export ARCHIPELAGO_STARTED=1
|
|
|
|
# Find archipelago directory
|
|
BOOT_MEDIA=""
|
|
for dev in /run/live/medium /lib/live/mount/medium /cdrom; do
|
|
if [ -d "$dev/archipelago" ]; then
|
|
BOOT_MEDIA="$dev"
|
|
break
|
|
fi
|
|
done
|
|
|
|
# Get IP address
|
|
IP=$(hostname -I 2>/dev/null | awk '{print $1}')
|
|
[ -z "$IP" ] && IP=$(ip -4 addr show | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | grep -v '127.0.0.1' | head -1)
|
|
|
|
# Show welcome banner ALWAYS
|
|
clear
|
|
echo ""
|
|
echo " ╔═══════════════════════════════════════════════════════════╗"
|
|
echo " ║ ║"
|
|
echo " ║ 🏝️ ARCHIPELAGO BITCOIN NODE OS ║"
|
|
echo " ║ ║"
|
|
echo " ║ Your sovereign Bitcoin infrastructure ║"
|
|
echo " ║ ║"
|
|
echo " ╚═══════════════════════════════════════════════════════════╝"
|
|
echo ""
|
|
if [ -n "$IP" ]; then
|
|
echo " ┌─────────────────────────────────────────────────────────────┐"
|
|
echo " │ 🌐 Web UI: http://$IP:5678 │"
|
|
echo " │ 📡 SSH: ssh user@$IP (password: archipelago) │"
|
|
echo " └─────────────────────────────────────────────────────────────┘"
|
|
echo ""
|
|
fi
|
|
|
|
if [ -z "$BOOT_MEDIA" ]; then
|
|
echo " ⚠️ Boot media not found at /run/live/medium"
|
|
echo ""
|
|
echo " Manual commands:"
|
|
echo " archipelago - Start backend server"
|
|
echo " archipelago-menu - Open setup menu"
|
|
echo ""
|
|
return 0 2>/dev/null || exit 0
|
|
fi
|
|
|
|
echo " 📍 Boot media: $BOOT_MEDIA"
|
|
echo ""
|
|
|
|
# Install archipelago commands if not present
|
|
if [ ! -f /usr/local/bin/archipelago ] && [ -f "$BOOT_MEDIA/archipelago/bin/archipelago" ]; then
|
|
sudo cp "$BOOT_MEDIA/archipelago/bin/archipelago" /usr/local/bin/ 2>/dev/null
|
|
sudo chmod +x /usr/local/bin/archipelago 2>/dev/null
|
|
fi
|
|
|
|
if [ ! -f /usr/local/bin/archipelago-menu ] && [ -f "$BOOT_MEDIA/archipelago/bin/archipelago-menu" ]; then
|
|
sudo cp "$BOOT_MEDIA/archipelago/bin/archipelago-menu" /usr/local/bin/ 2>/dev/null
|
|
sudo chmod +x /usr/local/bin/archipelago-menu 2>/dev/null
|
|
fi
|
|
|
|
# Copy scripts to /opt
|
|
if [ ! -d /opt/archipelago/scripts ] && [ -d "$BOOT_MEDIA/archipelago/scripts" ]; then
|
|
sudo mkdir -p /opt/archipelago
|
|
sudo cp -r "$BOOT_MEDIA/archipelago/scripts" /opt/archipelago/ 2>/dev/null
|
|
sudo chmod +x /opt/archipelago/scripts/*.sh 2>/dev/null
|
|
fi
|
|
|
|
# Start web backend in background if available
|
|
if command -v archipelago >/dev/null 2>&1; then
|
|
if ! pgrep -f "archipelago" >/dev/null 2>&1; then
|
|
echo " 🚀 Starting Archipelago backend on port 5678..."
|
|
nohup archipelago >/tmp/archipelago.log 2>&1 &
|
|
sleep 2
|
|
else
|
|
echo " ✅ Archipelago backend already running"
|
|
fi
|
|
fi
|
|
|
|
echo ""
|
|
echo " Commands:"
|
|
echo " archipelago-menu - Open interactive setup menu"
|
|
echo " archipelago - Start/restart backend server"
|
|
echo ""
|
|
read -p " Press Enter to open the setup menu (or Ctrl+C to skip)... "
|
|
|
|
# Launch the menu
|
|
if [ -f /opt/archipelago/scripts/archipelago-menu.sh ]; then
|
|
exec bash /opt/archipelago/scripts/archipelago-menu.sh
|
|
elif [ -f "$BOOT_MEDIA/archipelago/scripts/archipelago-menu.sh" ]; then
|
|
exec bash "$BOOT_MEDIA/archipelago/scripts/archipelago-menu.sh"
|
|
fi
|
|
PROFILE_EOF
|
|
|
|
chmod +x "$ISO_CUSTOM/etc/profile.d/z99-archipelago.sh"
|
|
|
|
# Also add to /etc/skel/.bashrc as fallback for new user sessions
|
|
mkdir -p "$ISO_CUSTOM/etc/skel"
|
|
cat >> "$ISO_CUSTOM/etc/skel/.bashrc" <<'BASHRC_EOF'
|
|
|
|
# Archipelago auto-start fallback
|
|
if [ -z "$ARCHIPELAGO_STARTED" ] && [ -t 0 ]; then
|
|
[ -f /etc/profile.d/z99-archipelago.sh ] && source /etc/profile.d/z99-archipelago.sh
|
|
fi
|
|
BASHRC_EOF
|
|
|
|
# Modify GRUB config for Archipelago branding
|
|
echo ""
|
|
echo "⚙️ Configuring boot..."
|
|
|
|
if [ -f "$ISO_CUSTOM/boot/grub/grub.cfg" ]; then
|
|
sed -i.bak \
|
|
-e 's/Debian GNU\/Linux/Archipelago Bitcoin Node OS/g' \
|
|
-e 's/Live system/Archipelago Live/g' \
|
|
"$ISO_CUSTOM/boot/grub/grub.cfg"
|
|
fi
|
|
|
|
if [ -f "$ISO_CUSTOM/isolinux/menu.cfg" ]; then
|
|
sed -i.bak \
|
|
-e 's/Debian GNU\/Linux/Archipelago Bitcoin Node OS/g' \
|
|
-e 's/Live system/Archipelago Live/g' \
|
|
"$ISO_CUSTOM/isolinux/menu.cfg"
|
|
fi
|
|
|
|
if [ -f "$ISO_CUSTOM/isolinux/live.cfg" ]; then
|
|
sed -i.bak \
|
|
-e 's/Live system/Archipelago Live/g' \
|
|
"$ISO_CUSTOM/isolinux/live.cfg"
|
|
fi
|
|
|
|
# Create final ISO
|
|
OUTPUT_ISO="$OUTPUT_DIR/archipelago-debian-12-x86_64.iso"
|
|
echo ""
|
|
echo "🔥 Creating final bootable ISO..."
|
|
|
|
if command -v xorriso >/dev/null 2>&1; then
|
|
# Create proper hybrid ISO with MBR for USB boot
|
|
# Need to extract MBR from isolinux or use system syslinux
|
|
|
|
# Check for isohdpfx.bin in various locations
|
|
ISOHDPFX=""
|
|
for path in \
|
|
"/usr/local/share/syslinux/isohdpfx.bin" \
|
|
"/usr/share/syslinux/isohdpfx.bin" \
|
|
"/opt/homebrew/share/syslinux/isohdpfx.bin" \
|
|
"$ISO_CUSTOM/isolinux/isohdpfx.bin"; do
|
|
if [ -f "$path" ]; then
|
|
ISOHDPFX="$path"
|
|
break
|
|
fi
|
|
done
|
|
|
|
if [ -z "$ISOHDPFX" ]; then
|
|
echo "⚠️ No isohdpfx.bin found, extracting from isolinux.bin..."
|
|
# Extract first 432 bytes from isolinux.bin as MBR
|
|
dd if="$ISO_CUSTOM/isolinux/isolinux.bin" of="$WORK_DIR/isohdpfx.bin" bs=432 count=1 2>/dev/null
|
|
ISOHDPFX="$WORK_DIR/isohdpfx.bin"
|
|
fi
|
|
|
|
echo " Using MBR: $ISOHDPFX"
|
|
|
|
xorriso -as mkisofs -o "$OUTPUT_ISO" \
|
|
-volid "ARCHIPELAGO" \
|
|
-J -R \
|
|
-isohybrid-mbr "$ISOHDPFX" \
|
|
-c isolinux/boot.cat \
|
|
-b isolinux/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 \
|
|
"$ISO_CUSTOM"
|
|
else
|
|
echo "❌ xorriso not found. Please install it: brew install xorriso"
|
|
exit 1
|
|
fi
|
|
|
|
echo ""
|
|
echo "✅ ISO created successfully!"
|
|
echo ""
|
|
echo "📀 Output: $OUTPUT_ISO"
|
|
echo " Size: $(du -h "$OUTPUT_ISO" | cut -f1)"
|
|
echo ""
|
|
echo "🔥 This is Debian Live-based - reliable USB boot like StartOS!"
|
|
echo ""
|
|
echo "To create USB:"
|
|
echo " 1. Use Balena Etcher to flash the ISO"
|
|
echo " 2. Or: sudo dd if=$OUTPUT_ISO of=/dev/sdX bs=4M status=progress"
|
|
echo ""
|