archy/build-iso-complete.sh
Dorian 6035c93289 Enhance ISO build process and documentation for Archipelago
- Updated BUILD-GUIDE.md to clarify instructions for building the Archipelago Auto-Installer ISO, emphasizing the recommended method of building directly on the target server.
- Added auto-installation of missing dependencies (xorriso, podman) when running the build script with sudo.
- Enhanced the build-auto-installer-iso.sh script to capture container images from the live server, ensuring the ISO includes the same set of applications as the dev server.
- Revised deployment documentation to stress the importance of building the Rust backend on the Linux dev server and included new instructions for capturing system-level changes for ISO builds.
- Improved UI components and added new bundled applications (BTCPay Server, Mempool Explorer, Nostr Relay, Strfry Relay, Tailscale) to enhance user experience.
2026-02-14 16:44:20 +00:00

401 lines
13 KiB
Bash
Executable File
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
#
# Archipelago Complete ISO Build System
# =====================================
#
# This script builds a complete, flashable ISO from source with one command.
# It handles backend compilation, frontend bundling, and ISO creation.
#
# Usage:
# ./build-iso-complete.sh [options]
#
# Options:
# --local Build everything locally (requires Rust + Node.js)
# --remote HOST Build on remote server (recommended for ARM -> x86 cross-compile)
# --skip-backend Skip backend compilation (use existing binary)
# --skip-frontend Skip frontend build (use existing dist)
# --clean Clean all build artifacts before building
# --help Show this help message
#
# Examples:
# ./build-iso-complete.sh --remote archipelago@192.168.1.228
# ./build-iso-complete.sh --local --clean
#
# Auto-installer from live server: when using --remote HOST, the ISO script
# (build-auto-installer-iso.sh) is run with DEV_SERVER=HOST so it captures
# backend, frontend, and container images from that host. Alternatively run
# DEV_SERVER=archipelago@192.168.1.228 ./image-recipe/build-auto-installer-iso.sh
# to build the auto-installer ISO with live capture only (no backend/frontend build).
#
set -e # Exit on error
# =============================================================================
# Configuration
# =============================================================================
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BUILD_DIR="$SCRIPT_DIR/image-recipe/build"
BACKEND_SRC="$SCRIPT_DIR/core/archipelago"
FRONTEND_SRC="$SCRIPT_DIR/neode-ui"
ISO_SCRIPT="$SCRIPT_DIR/image-recipe/build-auto-installer-iso.sh"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Build options (defaults)
BUILD_MODE="remote"
REMOTE_HOST=""
SKIP_BACKEND=false
SKIP_FRONTEND=false
CLEAN_BUILD=false
# =============================================================================
# Helper Functions
# =============================================================================
print_header() {
echo ""
echo -e "${BLUE}╔════════════════════════════════════════════════════════╗${NC}"
echo -e "${BLUE}${NC} $1"
echo -e "${BLUE}╚════════════════════════════════════════════════════════╝${NC}"
echo ""
}
print_success() {
echo -e "${GREEN}$1${NC}"
}
print_error() {
echo -e "${RED}$1${NC}"
}
print_warning() {
echo -e "${YELLOW}⚠️ $1${NC}"
}
print_info() {
echo -e "${BLUE} $1${NC}"
}
show_help() {
head -n 25 "$0" | grep "^#" | sed 's/^# //' | sed 's/^#//'
exit 0
}
check_command() {
if ! command -v "$1" &> /dev/null; then
print_error "$1 is not installed"
return 1
fi
return 0
}
# =============================================================================
# Parse Arguments
# =============================================================================
while [[ $# -gt 0 ]]; do
case $1 in
--local)
BUILD_MODE="local"
shift
;;
--remote)
BUILD_MODE="remote"
REMOTE_HOST="$2"
shift 2
;;
--skip-backend)
SKIP_BACKEND=true
shift
;;
--skip-frontend)
SKIP_FRONTEND=true
shift
;;
--clean)
CLEAN_BUILD=true
shift
;;
--help|-h)
show_help
;;
*)
print_error "Unknown option: $1"
show_help
;;
esac
done
# =============================================================================
# Pre-flight Checks
# =============================================================================
print_header "Archipelago Complete ISO Builder"
print_info "Build mode: $BUILD_MODE"
[[ -n "$REMOTE_HOST" ]] && print_info "Remote host: $REMOTE_HOST"
[[ "$SKIP_BACKEND" = true ]] && print_warning "Skipping backend build"
[[ "$SKIP_FRONTEND" = true ]] && print_warning "Skipping frontend build"
[[ "$CLEAN_BUILD" = true ]] && print_warning "Clean build enabled"
echo ""
# Check for required commands
if [[ "$BUILD_MODE" == "remote" ]] && [[ -z "$REMOTE_HOST" ]]; then
print_error "Remote build mode requires --remote HOST"
exit 1
fi
if [[ "$BUILD_MODE" == "remote" ]]; then
if ! check_command ssh; then
exit 1
fi
if ! check_command rsync; then
exit 1
fi
fi
# =============================================================================
# Step 1: Clean Build Artifacts (if requested)
# =============================================================================
if [[ "$CLEAN_BUILD" = true ]]; then
print_header "Cleaning Build Artifacts"
if [[ "$SKIP_BACKEND" = false ]]; then
print_info "Cleaning backend..."
rm -rf "$BACKEND_SRC/target"
print_success "Backend cleaned"
fi
if [[ "$SKIP_FRONTEND" = false ]]; then
print_info "Cleaning frontend..."
rm -rf "$FRONTEND_SRC/dist"
rm -rf "$FRONTEND_SRC/node_modules/.vite"
print_success "Frontend cleaned"
fi
print_info "Cleaning ISO build directory..."
rm -rf "$BUILD_DIR"
rm -rf "$SCRIPT_DIR/image-recipe/iso-workdir"
rm -rf "$SCRIPT_DIR/image-recipe/results"
print_success "ISO build artifacts cleaned"
fi
# =============================================================================
# Step 2: Build Backend
# =============================================================================
if [[ "$SKIP_BACKEND" = false ]]; then
print_header "Building Backend (Rust)"
if [[ "$BUILD_MODE" == "local" ]]; then
print_info "Building backend locally..."
cd "$BACKEND_SRC"
if ! check_command cargo; then
print_error "Rust/Cargo not installed. Install from: https://rustup.rs"
exit 1
fi
cargo build --release
# Copy to build directory
mkdir -p "$BUILD_DIR/backend"
cp target/release/archipelago "$BUILD_DIR/backend/"
chmod +x "$BUILD_DIR/backend/archipelago"
print_success "Backend built locally"
elif [[ "$BUILD_MODE" == "remote" ]]; then
print_info "Building backend on remote server: $REMOTE_HOST"
# Sync source code to remote
print_info "Syncing source code to remote..."
ssh "$REMOTE_HOST" "mkdir -p ~/archy-build"
rsync -az --delete \
--exclude 'target/' \
--exclude 'node_modules/' \
--exclude '.git/' \
"$BACKEND_SRC/" "$REMOTE_HOST:~/archy-build/core/archipelago/"
# Build on remote
print_info "Compiling backend on remote..."
ssh "$REMOTE_HOST" "cd ~/archy-build/core/archipelago && cargo build --release"
# Copy binary back
mkdir -p "$BUILD_DIR/backend"
print_info "Copying binary back to local..."
scp "$REMOTE_HOST:~/archy-build/core/archipelago/target/release/archipelago" "$BUILD_DIR/backend/"
chmod +x "$BUILD_DIR/backend/archipelago"
print_success "Backend built on remote server"
fi
# Verify binary
if [[ ! -f "$BUILD_DIR/backend/archipelago" ]]; then
print_error "Backend binary not found after build!"
exit 1
fi
BINARY_SIZE=$(du -h "$BUILD_DIR/backend/archipelago" | awk '{print $1}')
print_success "Backend binary ready ($BINARY_SIZE)"
else
print_warning "Skipping backend build (using existing binary)"
if [[ ! -f "$BUILD_DIR/backend/archipelago" ]]; then
print_error "No existing backend binary found at $BUILD_DIR/backend/archipelago"
exit 1
fi
fi
# =============================================================================
# Step 3: Build Frontend
# =============================================================================
if [[ "$SKIP_FRONTEND" = false ]]; then
print_header "Building Frontend (Vue.js)"
cd "$FRONTEND_SRC"
if ! check_command npm; then
print_error "Node.js/npm not installed. Install from: https://nodejs.org"
exit 1
fi
# Install dependencies if needed
if [[ ! -d "node_modules" ]] || [[ "$CLEAN_BUILD" = true ]]; then
print_info "Installing dependencies..."
npm install
fi
# Build frontend
print_info "Building frontend..."
npm run build
# Copy to build directory
mkdir -p "$BUILD_DIR/frontend"
cp -r dist/* "$BUILD_DIR/frontend/"
print_success "Frontend built"
# Verify dist
if [[ ! -d "$BUILD_DIR/frontend" ]] || [[ -z "$(ls -A "$BUILD_DIR/frontend")" ]]; then
print_error "Frontend build directory is empty!"
exit 1
fi
DIST_SIZE=$(du -sh "$BUILD_DIR/frontend" | awk '{print $1}')
print_success "Frontend assets ready ($DIST_SIZE)"
else
print_warning "Skipping frontend build (using existing dist)"
if [[ ! -d "$BUILD_DIR/frontend" ]] || [[ -z "$(ls -A "$BUILD_DIR/frontend")" ]]; then
print_error "No existing frontend build found at $BUILD_DIR/frontend"
exit 1
fi
fi
# =============================================================================
# Step 4: Build ISO
# =============================================================================
print_header "Building Bootable ISO"
# Check if running on remote or need to transfer
if [[ "$BUILD_MODE" == "remote" ]]; then
print_info "Transferring build artifacts to remote server..."
# Sync entire project to remote
ssh "$REMOTE_HOST" "mkdir -p ~/archy"
rsync -az --delete \
--exclude '.git/' \
--exclude 'node_modules/' \
--exclude 'core/target/' \
--exclude 'core/parmanode/' \
"$SCRIPT_DIR/" "$REMOTE_HOST:~/archy/"
print_success "Files synced to remote"
print_info "Running ISO build on remote server (auto-installer, DEV_SERVER=$REMOTE_HOST)..."
ssh -t "$REMOTE_HOST" "cd ~/archy/image-recipe && DEV_SERVER=$REMOTE_HOST sudo -E bash build-auto-installer-iso.sh" || {
print_error "ISO build failed on remote server"
exit 1
}
print_success "ISO built on remote server"
# Copy ISO back to local
ISO_NAME="archipelago-installer-x86_64.iso"
print_info "Copying ISO back to local machine..."
mkdir -p "$SCRIPT_DIR/image-recipe/results"
scp "$REMOTE_HOST:~/archy/image-recipe/results/$ISO_NAME" "$SCRIPT_DIR/image-recipe/results/"
ISO_PATH="$SCRIPT_DIR/image-recipe/results/$ISO_NAME"
else
# Local build
print_info "Running ISO build locally (auto-installer)..."
cd "$SCRIPT_DIR/image-recipe"
sudo bash build-auto-installer-iso.sh
ISO_PATH="$SCRIPT_DIR/image-recipe/results/archipelago-installer-x86_64.iso"
fi
# =============================================================================
# Step 5: Verify and Report
# =============================================================================
print_header "Build Complete!"
if [[ -f "$ISO_PATH" ]]; then
ISO_SIZE=$(du -h "$ISO_PATH" | awk '{print $1}')
ISO_MD5=$(md5 -q "$ISO_PATH" 2>/dev/null || md5sum "$ISO_PATH" | awk '{print $1}')
echo ""
echo -e "${GREEN}✅ ISO ready for flashing!${NC}"
echo ""
echo -e " 📀 ${BLUE}ISO:${NC} $ISO_PATH"
echo -e " 📏 ${BLUE}Size:${NC} $ISO_SIZE"
echo -e " 🔐 ${BLUE}MD5:${NC} $ISO_MD5"
echo ""
echo -e "${YELLOW}Next steps:${NC}"
echo ""
echo " 1. Insert USB drive"
echo " 2. Find device: ${BLUE}diskutil list${NC}"
echo " 3. Flash ISO:"
echo ""
echo " ${BLUE}cd image-recipe && ./write-usb-dd.sh /dev/diskN${NC}"
echo ""
echo " 4. Boot from USB on target device"
echo ""
# Create a flash script for convenience
cat > "$SCRIPT_DIR/flash-to-usb.sh" <<'FLASH_EOF'
#!/bin/bash
# Quick USB flash script
cd "$(dirname "$0")/image-recipe" && ./write-usb-dd.sh "$@"
FLASH_EOF
chmod +x "$SCRIPT_DIR/flash-to-usb.sh"
print_success "Created convenience script: ./flash-to-usb.sh"
else
print_error "ISO not found at expected location: $ISO_PATH"
exit 1
fi
# =============================================================================
# Done!
# =============================================================================
echo ""
echo -e "${GREEN}╔════════════════════════════════════════════════════════╗${NC}"
echo -e "${GREEN}║ 🎉 Build Complete - Ready to Flash! ║${NC}"
echo -e "${GREEN}╚════════════════════════════════════════════════════════╝${NC}"
echo ""