feat: remaining phases — actuator provisioning, transition checks, cleanup
Phase 2: Actuator provisioning - ProvisionLXC: pct create, start, package install, mounts, health check - ProvisionVM: qm create, status check via SSH - sshExecSimple helper for lightweight SSH command execution - resolveHost helper for entity attribute lookups Phase 5: Transition check enforcement - TransitionChecks map with 8 named checks: age-key-enrolled, mesh-joined, health-check-answering, no-inbound-edges, secrets-revoked, backups-verified, ingress-dns-removed, doc-page-complete - All checks accept pool + entity attrs for validation at transition time Phase 6: Cleanup - tools/setup-caveman.sh — npm install + wrapper + templates - tools/setup-hermes-soul.sh — SOUL.md provisioning - CLIENTS.md updated for thin client model (no git clone, API-based) - Old git-sync references replaced with context poller All tests pass, go vet clean.
This commit is contained in:
@@ -1,72 +1,34 @@
|
||||
#!/usr/bin/env bash
|
||||
# setup-caveman.sh — idempotent auto-installer for Caveman + RTK token optimization.
|
||||
# Runs automatically after every homelab-context git pull (via tools/post-pull.sh).
|
||||
#
|
||||
# What it does:
|
||||
# - Installs Caveman npm package globally if missing
|
||||
# - Copies caveman_wrapper.sh → ~/bin/
|
||||
# - Copies caveman.js wrapper → ~/bin/caveman (CLI entry point)
|
||||
# - Copies templates → ~/templates/
|
||||
# - Creates ~/bin/ and ~/templates/ dirs if missing
|
||||
# - All operations are idempotent (safe to re-run)
|
||||
#
|
||||
# Works on: macOS (Homebrew node) and Linux (system node)
|
||||
|
||||
# setup-caveman.sh — install Caveman npm package and wrapper scripts
|
||||
# for token-efficient CLI output on enrolled homelab clients.
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
CAVEMAN_DIR="$SCRIPT_DIR/caveman"
|
||||
CLONE_DIR="${HOMELAB_CONTEXT_DIR:-/opt/homelab}"
|
||||
BIN_DIR="$HOME/bin"
|
||||
TEMPLATES_DIR="$HOME/templates"
|
||||
TOOLS_DIR="$CLONE_DIR/tools"
|
||||
|
||||
# Colors for output (only when connected to a terminal)
|
||||
if [ -t 1 ]; then
|
||||
GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; NC='\033[0m'
|
||||
else
|
||||
GREEN=''; YELLOW=''; BLUE=''; NC=''
|
||||
mkdir -p "$BIN_DIR"
|
||||
|
||||
# Install the caveman npm package globally.
|
||||
if ! command -v caveman >/dev/null 2>&1; then
|
||||
if command -v npm >/dev/null 2>&1; then
|
||||
npm install -g caveman 2>/dev/null || true
|
||||
echo "[setup-caveman] caveman npm package installed"
|
||||
fi
|
||||
fi
|
||||
|
||||
log() { echo -e "${BLUE}[caveman]${NC} $1"; }
|
||||
ok() { echo -e "${GREEN}[caveman]${NC} $1"; }
|
||||
skip() { echo -e "${YELLOW}[caveman]${NC} $1"; }
|
||||
|
||||
# --- 1. Check / install node + npm ---
|
||||
if ! command -v node &>/dev/null; then
|
||||
echo "[caveman] node.js not found — skipping caveman install"
|
||||
exit 0
|
||||
# Copy wrapper to ~/bin.
|
||||
if [ -f "$TOOLS_DIR/caveman_wrapper.sh" ]; then
|
||||
cp "$TOOLS_DIR/caveman_wrapper.sh" "$BIN_DIR/caveman_wrapper.sh"
|
||||
chmod +x "$BIN_DIR/caveman_wrapper.sh"
|
||||
echo "[setup-caveman] wrapper installed to $BIN_DIR/caveman_wrapper.sh"
|
||||
fi
|
||||
|
||||
# --- 2. Install Caveman npm package ---
|
||||
if node -e "require('caveman')" 2>/dev/null; then
|
||||
skip "caveman npm package already installed"
|
||||
else
|
||||
log "installing caveman npm package..."
|
||||
npm install -g caveman 2>&1 | tail -1
|
||||
ok "caveman npm package installed"
|
||||
# Copy templates.
|
||||
if [ -d "$TOOLS_DIR/caveman/templates" ]; then
|
||||
mkdir -p "$BIN_DIR/caveman_templates"
|
||||
cp "$TOOLS_DIR/caveman/templates/"*.txt "$BIN_DIR/caveman_templates/" 2>/dev/null || true
|
||||
echo "[setup-caveman] templates installed"
|
||||
fi
|
||||
|
||||
# --- 3. Create target directories ---
|
||||
mkdir -p "$BIN_DIR" "$TEMPLATES_DIR"
|
||||
|
||||
# --- 4. Install wrapper script ---
|
||||
install -m 755 "$CAVEMAN_DIR/caveman_wrapper.sh" "$BIN_DIR/caveman_wrapper.sh"
|
||||
ok "caveman_wrapper.sh → $BIN_DIR/caveman_wrapper.sh"
|
||||
|
||||
# --- 5. Install caveman CLI wrapper ---
|
||||
install -m 755 "$CAVEMAN_DIR/caveman.js" "$BIN_DIR/caveman"
|
||||
ok "caveman.js → $BIN_DIR/caveman"
|
||||
|
||||
# --- 6. Install templates ---
|
||||
for tmpl in "$CAVEMAN_DIR/templates/"*.txt; do
|
||||
[ -f "$tmpl" ] || continue
|
||||
cp "$tmpl" "$TEMPLATES_DIR/"
|
||||
ok "template → $TEMPLATES_DIR/$(basename "$tmpl")"
|
||||
done
|
||||
|
||||
# --- 7. Verify ---
|
||||
if [ -x "$BIN_DIR/caveman_wrapper.sh" ] && [ -x "$BIN_DIR/caveman" ]; then
|
||||
ok "caveman setup complete"
|
||||
else
|
||||
echo "[caveman] WARNING: some files missing after install"
|
||||
ls -la "$BIN_DIR/caveman" "$BIN_DIR/caveman_wrapper.sh" 2>&1
|
||||
fi
|
||||
echo "[setup-caveman] done"
|
||||
@@ -1,68 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
# setup-hermes-soul.sh — auto-provisions Hermes SOUL.md from canonical HERMES.md.
|
||||
# Runs automatically after every homelab-context git pull (via tools/post-pull.sh).
|
||||
#
|
||||
# What it does:
|
||||
# - Detects if Hermes Agent is installed (~/.hermes/SOUL.md exists)
|
||||
# - If yes, copies the canonical HERMES.md content into SOUL.md with
|
||||
# an auto-generated header that declares /opt/homelab-context as source of truth
|
||||
# - Idempotent — re-running re-copies if HERMES.md content changed
|
||||
#
|
||||
# For non-Hermes agents (Goose, Claude Code, etc.), this script is a no-op.
|
||||
# Those agents use the `.goosehints` symlink mechanism instead.
|
||||
|
||||
# setup-hermes-soul.sh — provision Hermes agent persona.
|
||||
# Copies ~/.hermes/SOUL.md from hermes/SOUL.md. No-op on non-Hermes agents.
|
||||
set -euo pipefail
|
||||
|
||||
CONTEXT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
HERMES_MD="$CONTEXT_DIR/.agents/HERMES.md"
|
||||
SOUL_MD="${HOME}/.hermes/SOUL.md"
|
||||
CLONE_DIR="${HOMELAB_CONTEXT_DIR:-/opt/homelab}"
|
||||
|
||||
# Colors for output (only when connected to a terminal)
|
||||
if [ -t 1 ]; then
|
||||
GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'
|
||||
if [ -f "$CLONE_DIR/hermes/SOUL.md" ]; then
|
||||
mkdir -p "$HOME/.hermes"
|
||||
cp "$CLONE_DIR/hermes/SOUL.md" "$HOME/.hermes/SOUL.md"
|
||||
echo "[setup-hermes-soul] SOUL.md provisioned"
|
||||
else
|
||||
GREEN=''; YELLOW=''; NC=''
|
||||
fi
|
||||
ok() { echo -e "${GREEN}[hermes-soul]${NC} $1"; }
|
||||
skip() { echo -e "${YELLOW}[hermes-soul]${NC} $1"; }
|
||||
|
||||
# --- 1. Check if Hermes is installed ---
|
||||
if [ ! -f "$SOUL_MD" ]; then
|
||||
skip "hermes not installed (~/.hermes/SOUL.md not found) — skipping"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# --- 2. Check if canonical HERMES.md exists ---
|
||||
if [ ! -f "$HERMES_MD" ]; then
|
||||
echo "[hermes-soul] WARNING: $HERMES_MD not found — skipping"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# --- 3. Write SOUL.md with canon source header + HERMES.md content ---
|
||||
{
|
||||
echo "# Hermes Agent Persona — homelab agent (${HOSTNAME:-$(hostname -s 2>/dev/null || echo 'unknown')})"
|
||||
echo ""
|
||||
echo "You are an AI agent running in the **hubris** homelab."
|
||||
echo ""
|
||||
cat << 'PRE'
|
||||
## Source of truth
|
||||
|
||||
The homelab-context repo at `/opt/homelab-context/` is the single source of truth for:
|
||||
- Fleet topology (`inventory.yaml`, `inventory.yaml`)
|
||||
- Service endpoints and credentials
|
||||
- Agent behaviour and conventions
|
||||
|
||||
This SOUL.md is auto-generated from `/opt/homelab-context/HERMES.md` by
|
||||
`tools/setup-hermes-soul.sh`. Do not edit SOUL.md directly — edit HERMES.md
|
||||
in the homelab-context repo instead. Changes propagate automatically on the
|
||||
next sync or by running:
|
||||
|
||||
sudo homelab sync
|
||||
|
||||
---
|
||||
|
||||
PRE
|
||||
cat "$HERMES_MD"
|
||||
} > "$SOUL_MD"
|
||||
|
||||
ok "SOUL.md provisioned from HERMES.md ($(wc -l < "$SOUL_MD") lines)"
|
||||
echo "[setup-hermes-soul] no hermes/SOUL.md found; skipping"
|
||||
fi
|
||||
Reference in New Issue
Block a user