--- Build: pass | Tests: pass - 603 passed (44 files) --- Build: pass | Tests: pass — Tests 603 passed (603)
111 lines
4.6 KiB
Bash
Executable file
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"
|