Implements critical firstboot orchestration: - shell-gpu.sh: GPU detection (Intel i915kms, AMD amdgpu, NVIDIA, VMware vmwgfx) - shell-nvidia.sh: NVIDIA driver version selection (590/470/390 per GPU) - shell-pkg.sh: Package repository config + Bastille cache seeding - shell-env.sh: .env generation with secrets and jail IP allocation - shell-deploy.sh: Clawdie-AI tarball extraction + npm run install-all All modules: - POSIX-compliant (no bash-isms) - Proper error handling and validation - Comprehensive logging to /var/log/clawdie-firstboot.log - Progress tracking to /var/log/clawdie-firstboot.progress - Environment variable overrides for testing Unblocks firstboot.sh which was calling undefined functions. Ready for end-to-end installation testing on bhyve VM. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
199 lines
5.7 KiB
Bash
Executable file
199 lines
5.7 KiB
Bash
Executable file
#!/bin/sh
|
|
# Clawdie Shell — Package Configuration Module
|
|
# Purpose: Configure package repositories and seed offline cache
|
|
# POSIX-compliant (no bash-isms)
|
|
|
|
set -eu
|
|
|
|
# Configuration (can be overridden for testing)
|
|
PKG_CONF_DIR="${PKG_CONF_DIR:-/etc/pkg/repos}"
|
|
FREEBSD_REPO_CONF="${FREEBSD_REPO_CONF:-$PKG_CONF_DIR/FreeBSD.conf}"
|
|
CLAWDIE_USB_REPO_CONF="${CLAWDIE_USB_REPO_CONF:-$PKG_CONF_DIR/Clawdie-USB.conf}"
|
|
USB_MOUNT_POINT="${USB_MOUNT_POINT:-/mnt/media}"
|
|
USB_PKG_PATH="${USB_PKG_PATH:-$USB_MOUNT_POINT/packages}"
|
|
BASTILLE_PKG_CACHE="${BASTILLE_PKG_CACHE:-/var/cache/pkg/bastille}"
|
|
LOG_FILE="${LOG_FILE:-/var/log/clawdie-firstboot.log}"
|
|
PROGRESS_FILE="${PROGRESS_FILE:-/var/log/clawdie-firstboot.progress}"
|
|
|
|
# ============================================================================
|
|
# MAIN ENTRY POINT
|
|
# ============================================================================
|
|
|
|
clawdie_shell_pkg_setup() {
|
|
# Main orchestrator: configure repos and seed package cache
|
|
|
|
log_msg "[pkg] Starting package configuration"
|
|
|
|
# Step 1: Detect system ABI
|
|
local abi
|
|
abi=$(clawdie_shell_pkg_detect_abi) || {
|
|
log_msg "[pkg] ERROR: Could not detect ABI"
|
|
return 1
|
|
}
|
|
log_msg "[pkg] System ABI: $abi"
|
|
|
|
# Step 2: Write FreeBSD repo config (latest or quarterly per build.cfg)
|
|
clawdie_shell_pkg_write_freebsd_conf "$abi" || {
|
|
log_msg "[pkg] ERROR: Failed to write FreeBSD repo config"
|
|
return 1
|
|
}
|
|
log_msg "[pkg] Configured FreeBSD repository"
|
|
|
|
# Step 3: Write Clawdie USB repo config (offline)
|
|
clawdie_shell_pkg_write_clawdie_conf || {
|
|
log_msg "[pkg] ERROR: Failed to write Clawdie repo config"
|
|
return 1
|
|
}
|
|
log_msg "[pkg] Configured Clawdie USB repository"
|
|
|
|
# Step 4: Seed Bastille package cache from USB
|
|
clawdie_shell_pkg_seed_cache || {
|
|
log_msg "[pkg] WARNING: Failed to seed package cache"
|
|
}
|
|
log_msg "[pkg] Package cache seeded"
|
|
|
|
echo "[PKG] SUCCESS" >> "$PROGRESS_FILE"
|
|
log_msg "[pkg] Package configuration complete"
|
|
}
|
|
|
|
# ============================================================================
|
|
# ABI DETECTION
|
|
# ============================================================================
|
|
|
|
clawdie_shell_pkg_detect_abi() {
|
|
# Detect FreeBSD system ABI
|
|
# Returns: ABI string (e.g., "FreeBSD:15:amd64")
|
|
|
|
local abi
|
|
|
|
abi=$(pkg config abi 2>/dev/null || true)
|
|
|
|
if [ -z "$abi" ]; then
|
|
# Fallback: construct from uname
|
|
local os_name os_release arch
|
|
os_name=$(uname -s)
|
|
os_release=$(uname -r | cut -d. -f1)
|
|
arch=$(uname -m)
|
|
abi="$os_name:$os_release:$arch"
|
|
fi
|
|
|
|
echo "$abi"
|
|
}
|
|
|
|
# ============================================================================
|
|
# REPOSITORY CONFIGURATION
|
|
# ============================================================================
|
|
|
|
clawdie_shell_pkg_write_freebsd_conf() {
|
|
# Write FreeBSD repository configuration
|
|
# Input: ABI string
|
|
# Reads DEFAULT_PKG_BRANCH from build.cfg (latest or quarterly)
|
|
|
|
local abi="$1"
|
|
local branch="${DEFAULT_PKG_BRANCH:-latest}"
|
|
|
|
if [ ! -d "$PKG_CONF_DIR" ]; then
|
|
mkdir -p "$PKG_CONF_DIR"
|
|
fi
|
|
|
|
# Remove existing FreeBSD.conf if present
|
|
rm -f "$FREEBSD_REPO_CONF" 2>/dev/null || true
|
|
|
|
# Write new config
|
|
cat > "$FREEBSD_REPO_CONF" <<EOF
|
|
FreeBSD: {
|
|
url: "pkg+https://pkg.FreeBSD.org/\${ABI}/$branch",
|
|
mirror_type: "srv",
|
|
enabled: yes
|
|
}
|
|
EOF
|
|
|
|
log_msg "[pkg] Wrote $FREEBSD_REPO_CONF with branch=$branch"
|
|
}
|
|
|
|
clawdie_shell_pkg_write_clawdie_conf() {
|
|
# Write Clawdie USB repository configuration (offline)
|
|
# Points to bundled packages on USB
|
|
|
|
if [ ! -d "$PKG_CONF_DIR" ]; then
|
|
mkdir -p "$PKG_CONF_DIR"
|
|
fi
|
|
|
|
# Remove existing Clawdie-USB.conf if present
|
|
rm -f "$CLAWDIE_USB_REPO_CONF" 2>/dev/null || true
|
|
|
|
# Write new config
|
|
cat > "$CLAWDIE_USB_REPO_CONF" <<EOF
|
|
Clawdie-USB: {
|
|
url: "file://$USB_PKG_PATH",
|
|
mirror_type: "none",
|
|
enabled: yes,
|
|
priority: 100
|
|
}
|
|
EOF
|
|
|
|
log_msg "[pkg] Wrote $CLAWDIE_USB_REPO_CONF pointing to $USB_PKG_PATH"
|
|
}
|
|
|
|
# ============================================================================
|
|
# PACKAGE CACHE SEEDING
|
|
# ============================================================================
|
|
|
|
clawdie_shell_pkg_seed_cache() {
|
|
# Copy USB packages to Bastille cache directory
|
|
# This allows jails to use cached packages even if offline
|
|
|
|
if [ ! -d "$USB_PKG_PATH" ]; then
|
|
log_msg "[pkg] USB packages not available: $USB_PKG_PATH"
|
|
return 0 # Not an error, just skip
|
|
fi
|
|
|
|
if [ ! -d "$BASTILLE_PKG_CACHE" ]; then
|
|
mkdir -p "$BASTILLE_PKG_CACHE"
|
|
log_msg "[pkg] Created cache directory: $BASTILLE_PKG_CACHE"
|
|
fi
|
|
|
|
# Copy .pkg files to cache
|
|
if find "$USB_PKG_PATH" -name "*.pkg" -type f 2>/dev/null | head -1 >/dev/null; then
|
|
cp "$USB_PKG_PATH"/*.pkg "$BASTILLE_PKG_CACHE" 2>/dev/null || true
|
|
log_msg "[pkg] Seeded Bastille cache from USB packages"
|
|
else
|
|
log_msg "[pkg] WARNING: No .pkg files found in $USB_PKG_PATH"
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
# ============================================================================
|
|
# VALIDATION
|
|
# ============================================================================
|
|
|
|
clawdie_shell_pkg_validate() {
|
|
# Verify package configuration
|
|
|
|
if [ ! -f "$FREEBSD_REPO_CONF" ]; then
|
|
log_msg "[pkg] ERROR: $FREEBSD_REPO_CONF not found"
|
|
return 1
|
|
fi
|
|
|
|
if ! grep -q "FreeBSD:" "$FREEBSD_REPO_CONF" 2>/dev/null; then
|
|
log_msg "[pkg] ERROR: Invalid FreeBSD.conf format"
|
|
return 1
|
|
fi
|
|
|
|
log_msg "[pkg] Package configuration validation passed"
|
|
return 0
|
|
}
|
|
|
|
# ============================================================================
|
|
# LOGGING HELPER
|
|
# ============================================================================
|
|
|
|
log_msg() {
|
|
echo "$(date '+%H:%M:%S') $1" | tee -a "$LOG_FILE" 2>/dev/null || true
|
|
}
|
|
|
|
# Only run if sourced directly (not during test)
|
|
if [ "${SHELL_PKG_TEST:-0}" -eq 0 ]; then
|
|
clawdie_shell_pkg_setup
|
|
fi
|