Enhance README and RPC for package management
- Added instructions to README.md for building an ISO from source and flashing it to USB. - Introduced a new RPC method for package installation, including security checks and container management. - Updated Docker and Podman integration in build scripts to support both container runtimes. - Enhanced Nginx configuration for improved timeout settings and WebSocket support. - Added new app metadata for additional applications in the Docker package scanner.
This commit is contained in:
Executable
+394
@@ -0,0 +1,394 @@
|
||||
#!/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
|
||||
#
|
||||
|
||||
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-debian-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..."
|
||||
ssh -t "$REMOTE_HOST" "cd ~/archy/image-recipe && sudo bash build-debian-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-debian-12-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..."
|
||||
cd "$SCRIPT_DIR/image-recipe"
|
||||
sudo bash build-debian-iso.sh
|
||||
|
||||
ISO_PATH="$SCRIPT_DIR/image-recipe/results/archipelago-debian-12-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 ""
|
||||
Reference in New Issue
Block a user