240 lines
7.4 KiB
Bash
Executable file
240 lines
7.4 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
#
|
|
# provision.sh — configure any LAN machine for the Lilith platform
|
|
#
|
|
# Unified entrypoint that auto-detects host role and runs the appropriate
|
|
# setup modules. Supports black (devops), apricot (GPU dev), and plum (macOS).
|
|
#
|
|
# Usage:
|
|
# ./provision.sh # auto-detect host, full setup
|
|
# ./provision.sh --check # verify only, no changes
|
|
# ./provision.sh --dns # DNS + CA cert + NPM only
|
|
# ./provision.sh --services # host-specific services only
|
|
# ./provision.sh --full # everything (default)
|
|
# ./provision.sh --host plum # override auto-detection
|
|
#
|
|
# Idempotent — safe to re-run at any time.
|
|
#
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
MODULES_DIR="$SCRIPT_DIR/modules"
|
|
|
|
# ============================================================================
|
|
# Source modules
|
|
# ============================================================================
|
|
|
|
source "$MODULES_DIR/common.sh"
|
|
source "$MODULES_DIR/dns-client.sh"
|
|
|
|
# ============================================================================
|
|
# Argument parsing
|
|
# ============================================================================
|
|
|
|
MODE="full"
|
|
HOST_OVERRIDE=""
|
|
CHECK_ONLY=false
|
|
|
|
parse_args() {
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--check|-c)
|
|
MODE="check"
|
|
CHECK_ONLY=true
|
|
;;
|
|
--dns)
|
|
MODE="dns"
|
|
;;
|
|
--services)
|
|
MODE="services"
|
|
;;
|
|
--full|-f)
|
|
MODE="full"
|
|
;;
|
|
--host|-H)
|
|
shift
|
|
HOST_OVERRIDE="${1:-}"
|
|
if [[ -z "$HOST_OVERRIDE" ]]; then
|
|
log_error "--host requires a value (black, apricot, plum)"
|
|
exit 1
|
|
fi
|
|
;;
|
|
--help|-h)
|
|
print_usage
|
|
exit 0
|
|
;;
|
|
*)
|
|
log_error "Unknown argument: $1"
|
|
print_usage
|
|
exit 1
|
|
;;
|
|
esac
|
|
shift
|
|
done
|
|
}
|
|
|
|
print_usage() {
|
|
cat <<'EOF'
|
|
provision.sh — configure any LAN machine for the Lilith platform
|
|
|
|
Usage:
|
|
./provision.sh # auto-detect host, full setup
|
|
./provision.sh --check # verify only, no changes
|
|
./provision.sh --dns # DNS + CA cert + NPM only
|
|
./provision.sh --services # host-specific services only
|
|
./provision.sh --full # everything (default)
|
|
./provision.sh --host plum # override auto-detection
|
|
|
|
Hosts:
|
|
black (10.0.0.11) Ubuntu 24.04 — devops + staging
|
|
apricot (10.0.0.13) Fedora Atomic (Bluefin) — GPU dev
|
|
plum (10.0.0.123) macOS Sequoia — dev MacBook
|
|
|
|
Modes:
|
|
--check, -c Read-only verification (no changes)
|
|
--dns DNS client + CA cert + NPM registry only
|
|
--services Host-specific services only
|
|
--full, -f Everything (default)
|
|
--host, -H Override hostname detection
|
|
--help, -h Show this help
|
|
EOF
|
|
}
|
|
|
|
# ============================================================================
|
|
# Host detection + module loading
|
|
# ============================================================================
|
|
|
|
resolve_host() {
|
|
if [[ -n "$HOST_OVERRIDE" ]]; then
|
|
PROVISION_HOST_OVERRIDE="$HOST_OVERRIDE"
|
|
fi
|
|
|
|
HOST_ROLE=$(detect_host) || exit 1
|
|
}
|
|
|
|
load_host_module() {
|
|
local module_file="$MODULES_DIR/${HOST_ROLE}.sh"
|
|
if [[ ! -f "$module_file" ]]; then
|
|
log_error "Host module not found: $module_file"
|
|
exit 1
|
|
fi
|
|
source "$module_file"
|
|
}
|
|
|
|
# ============================================================================
|
|
# Pre-flight
|
|
# ============================================================================
|
|
|
|
preflight() {
|
|
detect_os
|
|
|
|
log_info "Host: $(hostname -s 2>/dev/null || hostname) → role: $HOST_ROLE"
|
|
log_info "OS: $OS_NAME $OS_VERSION"
|
|
log_info "Package manager: $(detect_package_manager)"
|
|
log_info "Mode: $MODE"
|
|
|
|
if is_atomic; then
|
|
log_info "Immutable OS detected (Fedora Atomic)"
|
|
fi
|
|
}
|
|
|
|
# ============================================================================
|
|
# Summary table
|
|
# ============================================================================
|
|
|
|
print_summary() {
|
|
log_section "Summary"
|
|
|
|
echo ""
|
|
echo -e "${BOLD}Host:${NC} $(hostname -s 2>/dev/null || hostname) ($HOST_ROLE)"
|
|
echo -e "${BOLD}Mode:${NC} $MODE"
|
|
echo -e "${BOLD}OS:${NC} $OS_NAME $OS_VERSION"
|
|
echo ""
|
|
|
|
case "$HOST_ROLE" in
|
|
black)
|
|
echo -e "${BOLD}Services:${NC}"
|
|
echo " DNS server: dnsmasq (systemd)"
|
|
echo " Reverse proxy: nginx (docker)"
|
|
echo " Git forge: forgejo (docker)"
|
|
echo " NPM registry: verdaccio (docker)"
|
|
echo " CI runner: forgejo-runner (docker)"
|
|
echo " Backup: restic-rest-server (docker)"
|
|
echo " SEO: serpbear (docker)"
|
|
echo " SSO: sso-api + postgres + redis (docker)"
|
|
echo " Database: postgresql (systemd)"
|
|
echo " NFS: nfs-server (systemd)"
|
|
echo " PM2: landing-api, webmap-router, status-dashboard"
|
|
echo " systemd: marketplace-api, messenger-imessage, host-status-monitor"
|
|
;;
|
|
apricot)
|
|
echo -e "${BOLD}Configuration:${NC}"
|
|
echo " DNS: → 10.0.0.11 (resolved)"
|
|
echo " CA cert: Lilith Platform CA"
|
|
echo " NPM: → npm.black.local"
|
|
echo " Feature DBs: analytics, i18n, seo, conv-assistant"
|
|
echo " Dev nginx: *.apricot.local (podman)"
|
|
echo " CUDA/ML: toolkit + PyTorch"
|
|
echo " Backups: restic → black:8000"
|
|
echo " VPN: WireGuard wg0"
|
|
echo " Monitoring: host-status-monitor"
|
|
;;
|
|
plum)
|
|
echo -e "${BOLD}Configuration:${NC}"
|
|
echo " DNS: → 10.0.0.11 (networksetup)"
|
|
echo " CA cert: Lilith Platform CA (System Keychain)"
|
|
echo " NPM: → npm.black.local"
|
|
echo " Conv. asst: LaunchAgent"
|
|
echo " Backups: restic LaunchAgent → black:8000"
|
|
echo " Monitoring: host-status-monitor LaunchAgent"
|
|
;;
|
|
esac
|
|
echo ""
|
|
}
|
|
|
|
# ============================================================================
|
|
# Main
|
|
# ============================================================================
|
|
|
|
main() {
|
|
parse_args "$@"
|
|
resolve_host
|
|
load_host_module
|
|
|
|
local mode_label
|
|
case "$MODE" in
|
|
check) mode_label="Verification" ;;
|
|
dns) mode_label="DNS + CA + NPM" ;;
|
|
services) mode_label="Host Services" ;;
|
|
full) mode_label="Full Provisioning" ;;
|
|
esac
|
|
|
|
log_banner "Provision: $HOST_ROLE — $mode_label"
|
|
preflight
|
|
|
|
case "$MODE" in
|
|
check)
|
|
host_verify
|
|
;;
|
|
dns)
|
|
host_dns_setup
|
|
;;
|
|
services)
|
|
host_services_setup
|
|
;;
|
|
full)
|
|
host_dns_setup
|
|
host_services_setup
|
|
;;
|
|
esac
|
|
|
|
print_summary
|
|
|
|
if [[ "$MODE" == "check" ]]; then
|
|
log_info "Verification complete — no changes were made"
|
|
else
|
|
log_info "Provisioning complete"
|
|
fi
|
|
}
|
|
|
|
main "$@"
|