clawdie-ai/docs/internal/scripts/setup-controlplane-jail.sh
Clawdie AI cc37d2c8cf Public/internal docs restructure; CMS/verify cleanup (Sam & Codex)
---

Build: pass | Tests: pass - 603 passed (44 files)

---
Build: pass | Tests: pass — Tests  603 passed (603)
2026-04-05 06:29:19 +00:00

111 lines
4.6 KiB
Bash
Executable file

#!/bin/sh
# setup-controlplane-jail.sh — create the agent controlplane jail
#
# Usage: sudo sh docs/internal/scripts/setup-controlplane-jail.sh
#
# Reads .env from the project root. Idempotent — safe to re-run.
#
# What it does:
# 1. Create a thin bastille jail at WORKER_JAIL_IP (.2)
# 2. Install Node 24, git, python, dev tools
# 3. Mount /home/<agent> into jail (agent code lives there)
# 4. npm-global ZFS dataset auto-mounts via its ZFS mountpoint property
# 5. Install and enable the agent rc.d service
set -e
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
cd "${PROJECT_ROOT}"
# ── Read .env ─────────────────────────────────────────────────────────────────
env_get() {
local key="$1" default="$2"
local val
val=$(grep -m1 "^${key}=" .env 2>/dev/null | cut -d= -f2- | sed "s/^['\"]//;s/['\"]$//")
printf '%s' "${val:-$default}"
}
AGENT_NAME=$(env_get AGENT_NAME clawdie)
SUBNET_BASE=$(env_get AGENT_SUBNET_BASE "$(env_get JAIL_SUBNET_BASE 10.0.1)")
CP_IP=$(env_get WORKER_JAIL_IP "${SUBNET_BASE}.2")
JAIL="${AGENT_NAME}-controlplane"
AGENT_HOME="/home/${AGENT_NAME}"
CLAWDIE_AI_DIR=$(env_get CLAWDIE_AI_DIR "${AGENT_HOME}/clawdie-ai")
FREEBSD_REL=$(freebsd-version -u | cut -d- -f1,2)
JAIL_ROOT="/usr/local/bastille/jails/${JAIL}/root"
echo "==> Controlplane jail setup"
echo " Jail: ${JAIL} @ ${CP_IP}"
echo " Agent: ${AGENT_NAME} (home: ${AGENT_HOME})"
echo ""
# ── 1. Create jail ────────────────────────────────────────────────────────────
if bastille list 2>/dev/null | grep -qw "${JAIL}"; then
echo "==> Jail ${JAIL} already exists — skipping creation"
else
echo "==> Creating jail ${JAIL}"
bastille create "${JAIL}" "${FREEBSD_REL}" "${CP_IP}"
fi
# ── 2. Install packages ───────────────────────────────────────────────────────
echo "==> Installing Node 24 and dev tools"
bastille pkg "${JAIL}" install -y \
node24 npm-node24 \
bash git-lite \
python311 python312 uv \
sudo tmux jq \
postgresql17-client \
ripgrep ca_root_nss
# ── 3. Mount agent home ───────────────────────────────────────────────────────
# The agent code lives on the host at /home/<agent>. We nullfs-mount it
# into the jail so the rc.d service can exec dist/index.js directly.
#
# IMPORTANT: thin jails symlink /home -> usr/home. The fstab mount target
# must use the real path (usr/home) or bastille will refuse to start the jail
# with: "mount.fstab: /root/home is a symbolic link"
MOUNT_TARGET="${JAIL_ROOT}/usr/home/${AGENT_NAME}"
FSTAB="/usr/local/bastille/jails/${JAIL}/fstab"
if ! grep -q "^${AGENT_HOME} " "${FSTAB}" 2>/dev/null; then
echo "==> Mounting ${AGENT_HOME} into jail (via usr/home)"
mkdir -p "${MOUNT_TARGET}"
echo "${AGENT_HOME} ${MOUNT_TARGET} nullfs rw 0 0" >> "${FSTAB}"
fi
if ! mount | grep -q "${MOUNT_TARGET}"; then
mount -t nullfs "${AGENT_HOME}" "${MOUNT_TARGET}"
fi
# ── 4. npm-global ─────────────────────────────────────────────────────────────
# The npm-global ZFS dataset (zroot/clawdie-runtime/shared/npm-global) has
# its ZFS mountpoint set to ${JAIL_ROOT}/opt/npm. ZFS mounts it automatically
# at boot. Do NOT add it to fstab — that causes double-mount errors.
# To create the dataset the first time:
# zfs create -o mountpoint=${JAIL_ROOT}/opt/npm \
# zroot/clawdie-runtime/shared/npm-global
echo "==> npm-global: auto-mounted via ZFS mountpoint (no fstab entry needed)"
# ── 5. rc.d service ───────────────────────────────────────────────────────────
RC_SRC="/usr/local/etc/rc.d/${AGENT_NAME}"
RC_DST="${JAIL_ROOT}/usr/local/etc/rc.d/${AGENT_NAME}"
if [ -f "${RC_SRC}" ]; then
echo "==> Installing rc.d/${AGENT_NAME} into jail"
cp "${RC_SRC}" "${RC_DST}"
chmod +x "${RC_DST}"
bastille sysrc "${JAIL}" "${AGENT_NAME}_enable=YES"
else
echo "WARN: ${RC_SRC} not found — install manually after npm run build"
fi
echo ""
echo "==> Done. Start with: bastille cmd ${JAIL} service ${AGENT_NAME} start"
echo " Verify: bastille cmd ${JAIL} pgrep -la node"