#!/bin/bash # Sorcery-Go Project Bootstrapper for an existing Source Mage chroot. # # This script is the "drop-in" installer. It: # 1. Detects the existing Source Mage layout (grimoire at # /var/lib/sorcery/codex/grimoire, spells at /var/lib/sorcery/...). # 2. Builds the Go binary (or skips if you've already run `make build`). # 3. Installs it to /usr/local/sbin/sorcery-go (NOT /usr/sbin/sorcery — # we coexist with the legacy Bash sorcery, we don't replace it). # 4. Creates the Sorcery-Go state directory at /var/lib/sorcery-go # (separate from /var/lib/sorcery so both tools can run side-by-side). # 5. Initialises the bbolt state DB and indexes the existing grimoire. # 6. Optionally loads eBPF security programs and installs the systemd # or OpenRC service. # # Supported container runtimes: LXC, Podman, Firecracker, BareMetal. # The runtime is auto-detected unless SORCERY_GO_RUNTIME is set. set -e PROJECT_ROOT="$(cd "$(dirname "$0")/.." && pwd)" cd "$PROJECT_ROOT" # --- detect environment --- SMGL_GRIMOIRE="${SORCERY_GO_GRIMOIRE:-/var/lib/sorcery/codex/grimoire}" SORCERY_GO_ROOT="${SORCERY_GO_ROOT:-/var/lib/sorcery-go}" SORCERY_GO_SPOOL="${SORCERY_GO_SPOOL:-/var/spool/sorcery-go}" SORCERY_GO_BIN="${SORCERY_GO_BIN:-/usr/local/sbin/sorcery-go}" SORCERY_GO_RUNTIME="${SORCERY_GO_RUNTIME:-auto}" if [ "$(id -u)" -ne 0 ]; then echo "⚠ bootstrap.sh needs root for /var/lib/sorcery-go and the install step." echo " Re-run with: sudo ./scripts/bootstrap.sh" exit 1 fi echo "⚡ Sorcery-Go bootstrap — drop-in for Source Mage" echo " Project root: $PROJECT_ROOT" echo " Install target: $SORCERY_GO_BIN" echo " State root: $SORCERY_GO_ROOT" echo " Spool: $SORCERY_GO_SPOOL" echo " Grimoire: $SMGL_GRIMOIRE" echo " Runtime: $SORCERY_GO_RUNTIME" echo "" # --- 1. detect existing grimoire --- if [ ! -d "$SMGL_GRIMOIRE" ]; then echo "⚠ Grimoire not found at $SMGL_GRIMOIRE" echo " Set SORCERY_GO_GRIMOIRE to your spell tree, or run inside a" echo " Source Mage chroot where /var/lib/sorcery/codex/grimoire exists." echo " Continuing with an empty grimoire — you can clone one later." fi # --- 2. build the binary --- if [ ! -x "$PROJECT_ROOT/build/sorcery" ]; then echo "→ Building sorcery-go..." if command -v go >/dev/null 2>&1; then make build else echo "✗ Go is not installed. Install go >= 1.21 and re-run." exit 1 fi fi # --- 3. install the binary --- echo "→ Installing to $SORCERY_GO_BIN..." install -m 755 "$PROJECT_ROOT/build/sorcery" "$SORCERY_GO_BIN" # Also install the smaller tools if they were built. for tool in quill cauldron warding gaze; do if [ -x "$PROJECT_ROOT/build/$tool" ]; then install -m 755 "$PROJECT_ROOT/build/$tool" "/usr/local/sbin/$tool-go" fi done # --- 4. create state directories --- echo "→ Creating state directories under $SORCERY_GO_ROOT..." mkdir -p "$SORCERY_GO_ROOT"/{state,tomb/{epitaphs,blobs},build,log,ebpf/maps} mkdir -p "$SORCERY_GO_SPOOL" chmod 700 "$SORCERY_GO_ROOT/state" chmod 700 "$SORCERY_GO_ROOT/tomb" # --- 5. apply capabilities (for OverlayFS and eBPF) --- if command -v setcap >/dev/null 2>&1; then echo "→ Applying Linux capabilities..." setcap 'cap_sys_admin,cap_chown,cap_dac_override,cap_bpf+ep' "$SORCERY_GO_BIN" || \ echo " (setcap failed — runs as root will still work)" fi # --- 6. initialise the state DB + index the grimoire --- echo "→ Initialising state DB and indexing grimoire..." export SORCERY_GO_ROOT SORCERY_GO_GRIMOIRE SORCERY_GO_SPOOL SORCERY_GO_PGP_KEYRING SORCERY_GO_RUNTIME "$SORCERY_GO_BIN" init --force # --- 7. detect and report runtime --- echo "" echo "→ Container runtime detection:" if [ "$SORCERY_GO_RUNTIME" = "auto" ]; then if command -v lxc-create >/dev/null 2>&1; then echo " ✓ LXC detected — system containers available" SORCERY_GO_RUNTIME="lxc" fi if command -v podman >/dev/null 2>&1; then echo " ✓ Podman detected — OCI containers available" [ "$SORCERY_GO_RUNTIME" = "auto" ] && SORCERY_GO_RUNTIME="podman" fi if command -v firecracker >/dev/null 2>&1; then echo " ✓ Firecracker detected — microVMs available" [ "$SORCERY_GO_RUNTIME" = "auto" ] && SORCERY_GO_RUNTIME="firecracker" fi if [ "$SORCERY_GO_RUNTIME" = "auto" ]; then echo " • No container runtime detected — using baremetal mode" SORCERY_GO_RUNTIME="baremetal" fi else echo " Runtime: $SORCERY_GO_RUNTIME (manual override)" fi echo " Active runtime: $SORCERY_GO_RUNTIME" # --- 8. optional: install service file --- if command -v systemctl >/dev/null 2>&1; then echo "→ Installing systemd unit..." install -m 644 "$PROJECT_ROOT/manifests/sorcery-go.service" \ /etc/systemd/system/sorcery-go.service systemctl daemon-reload echo " (enable with: systemctl enable --now sorcery-go)" elif [ -d /etc/init.d ]; then echo "→ Installing OpenRC service..." install -m 755 "$PROJECT_ROOT/manifests/sorcery-go.openrc" /etc/init.d/sorcery-go echo " (enable with: rc-update add sorcery-go default)" fi echo "" echo "✓ Sorcery-Go is installed and ready." echo "" echo "Quick test:" echo " sudo $SORCERY_GO_BIN cast busybox --static --default" echo " $SORCERY_GO_BIN gaze install busybox" echo " sudo $SORCERY_GO_BIN tomb list" echo "" echo "eBPF Tomb Guard:" echo " sudo $SORCERY_GO_BIN ward reinforce # Load eBPF programs" echo " sudo $SORCERY_GO_BIN ward watch # Monitor violations" echo "" echo "Sanctum management ($SORCERY_GO_RUNTIME):" echo " sudo $SORCERY_GO_BIN coven spawn sanctum-alpha" echo " sudo $SORCERY_GO_BIN reanimate --sanctum sanctum-alpha" echo "" echo "Launch the Coven Mirror WebUI:" echo " sudo $SORCERY_GO_BIN web --port 8080" echo "" echo "The Ley-Lines are humming. The Tomb is secure (eBPF-enforced)."