clawdie-iso/live/operator-session/colibri-live-rebuild
Sam & Claude 14248b6a20 feat(colibri): gate test-agent staging by build mode (Sam & Pi)
Add COLIBRI_STAGE_TEST_AGENT with dev/release defaults so validation builds can include colibri-test-agent while production/release operator USB images omit it by default. Keep poudriere guidance test-friendly and document binary roles in BUILD.md.\n\nValidation: sh -n build.sh scripts/stage-colibri-iso.sh live/operator-session/colibri-live-rebuild; ./scripts/check-format.sh; ./scripts/test-release-gate.sh; build.cfg default/override checks.
2026-06-21 07:55:24 +02:00

110 lines
4.6 KiB
Bash
Executable file

#!/bin/sh
# colibri-live-rebuild — rebuild and redeploy Colibri on a running live USB.
#
# Automates docs/LIVE-COLIBRI-REBUILD.md so a booted operator USB can rebuild the
# control plane from source in one command — field repair/validation without a
# full ISO rebuild. FreeBSD live image only; privileged steps go through `mdo`
# (the live image has no sudo). It does NOT replace the release ISO process.
#
# Usage:
# colibri-live-rebuild # rebuild from the build checkout's current HEAD
# colibri-live-rebuild --ref main # check out a branch/tag/commit first
# colibri-live-rebuild --build-dir DIR # use an alternate build checkout
set -eu
REF=""
BUILD_DIR="/home/clawdie/ai/colibri-build"
SEED_SRC="/home/clawdie/ai/colibri" # git-backed source staged on the image
REMOTE="https://code.smilepowered.org/clawdie/colibri.git"
BINS="colibri-daemon colibri colibri-mcp colibri-tui"
if [ "${COLIBRI_STAGE_TEST_AGENT:-NO}" = "YES" ]; then
BINS="${BINS} colibri-test-agent"
fi
usage() { echo "usage: colibri-live-rebuild [--ref <branch|commit>] [--build-dir <path>]"; exit "${1:-0}"; }
while [ $# -gt 0 ]; do
case "$1" in
--ref) REF="${2:?--ref needs a value}"; shift 2 ;;
--build-dir) BUILD_DIR="${2:?--build-dir needs a value}"; shift 2 ;;
-h|--help) usage 0 ;;
*) echo "unknown argument: $1" >&2; usage 1 ;;
esac
done
command -v cargo >/dev/null 2>&1 || { echo "ERROR: cargo not found — pkg install rust" >&2; exit 1; }
command -v git >/dev/null 2>&1 || { echo "ERROR: git not found — pkg install git" >&2; exit 1; }
command -v mdo >/dev/null 2>&1 || { echo "ERROR: mdo not found — this targets the FreeBSD live image" >&2; exit 1; }
# 1. Obtain/refresh a working build checkout (kept separate from the shipped
# read-only source at SEED_SRC). Clone from the on-image source when present
# so a first rebuild works offline; otherwise from Forgejo.
if [ ! -d "${BUILD_DIR}/.git" ]; then
if [ -d "${SEED_SRC}/.git" ]; then
echo "==> cloning build checkout from staged source ${SEED_SRC}"
git clone "file://${SEED_SRC}" "${BUILD_DIR}"
git -C "${BUILD_DIR}" remote set-url origin "${REMOTE}" || true
else
echo "==> cloning build checkout from ${REMOTE}"
git clone "${REMOTE}" "${BUILD_DIR}"
fi
fi
git -C "${BUILD_DIR}" fetch --prune origin 2>/dev/null || echo "WARN: fetch failed (offline?) — using current checkout"
if [ -n "${REF}" ]; then
echo "==> checking out ${REF}"
git -C "${BUILD_DIR}" checkout "${REF}"
git -C "${BUILD_DIR}" pull --ff-only 2>/dev/null || true
fi
# 2. Build the release binaries.
echo "==> building colibri release binaries (this takes a few minutes)"
( cd "${BUILD_DIR}" && cargo build --release \
-p colibri-daemon -p colibri-client -p colibri-mcp -p colibri-glasspane-tui )
REL="${BUILD_DIR}/target/release"
for b in ${BINS}; do
[ -x "${REL}/${b}" ] || { echo "ERROR: expected build output missing: ${REL}/${b}" >&2; exit 1; }
done
# 3. Stop the service and clear stale runtime files.
echo "==> stopping colibri_daemon"
mdo -u root service colibri_daemon stop 2>/dev/null || true
mdo -u root pkill -f colibri-daemon 2>/dev/null || true
mdo -u root rm -f /var/run/colibri/colibri.sock \
/var/run/colibri/colibri-daemon.pid \
/var/run/colibri/colibri-daemon-supervisor.pid
# 4. Install binaries + rc.d script.
echo "==> installing binaries + rc.d script"
for b in ${BINS}; do
mdo -u root install -m 0555 "${REL}/${b}" "/usr/local/bin/${b}"
done
mdo -u root install -m 0555 "${BUILD_DIR}/packaging/freebsd/colibri_daemon.in" \
/usr/local/etc/rc.d/colibri_daemon
mdo -u root chown -R colibri:colibri /var/run/colibri /var/db/colibri /var/log/colibri 2>/dev/null || true
# 5. Restart and validate.
echo "==> starting colibri_daemon"
mdo -u root service colibri_daemon start
sleep 2
mdo -u root service colibri_daemon status || true
colibri status || { echo "ERROR: 'colibri status' could not reach the socket after restart" >&2; exit 1; }
# 6. Record what was installed.
commit=$(git -C "${BUILD_DIR}" rev-parse HEAD 2>/dev/null || echo unknown)
branch=$(git -C "${BUILD_DIR}" symbolic-ref --short -q HEAD 2>/dev/null || echo detached)
now=$(date -u +%Y-%m-%dT%H:%M:%SZ)
_rec=$(mktemp)
cat > "${_rec}" <<JSON
{
"repo": "${REMOTE}",
"branch": "${branch}",
"commit": "${commit}",
"installed_at": "${now}",
"note": "Built and installed on running live USB by colibri-live-rebuild"
}
JSON
mdo -u root install -m 0644 "${_rec}" /var/db/colibri/live-rebuild.json
rm -f "${_rec}"
echo "==> done: colibri ${commit} (${branch}) is live on this USB"
echo " record: /var/db/colibri/live-rebuild.json"