Merge pull request 'feat: stage the simplified clawdie agent into the ISO (Sam & Claude)' (#5) from feat/clawdie-staging-onto-live-boot into main
Reviewed-on: #5
This commit is contained in:
commit
d028cc1e49
4 changed files with 267 additions and 0 deletions
13
build.cfg
13
build.cfg
|
|
@ -81,6 +81,19 @@ COLIBRI_ARTIFACT_DIR="${COLIBRI_ARTIFACT_DIR:-}"
|
||||||
COLIBRI_DAEMON_ENABLE="${COLIBRI_DAEMON_ENABLE:-NO}"
|
COLIBRI_DAEMON_ENABLE="${COLIBRI_DAEMON_ENABLE:-NO}"
|
||||||
COLIBRI_COST_MODE="${COLIBRI_COST_MODE:-smart}"
|
COLIBRI_COST_MODE="${COLIBRI_COST_MODE:-smart}"
|
||||||
|
|
||||||
|
# Clawdie agent — the simplified, operator-friendly Colibri lane.
|
||||||
|
# One small Rust binary (glasspane + herdr + DeepSeek/Telegram), built from the
|
||||||
|
# same ../colibri checkout. Opt-in (default NO) so it does not disturb the
|
||||||
|
# current default build; flip to YES for the simplified operator image.
|
||||||
|
# The two credentials are normally baked into the binary at build time:
|
||||||
|
# (cd ../colibri && CLAWDIE_TG_TOKEN=... CLAWDIE_DEEPSEEK_KEY=... \
|
||||||
|
# cargo build --release -p clawdie)
|
||||||
|
# Leave them blank to ship a "bring your own key" binary configured via the
|
||||||
|
# rc.d env file (/usr/local/etc/clawdie/clawdie.env) at runtime instead.
|
||||||
|
FEATURE_CLAWDIE="${FEATURE_CLAWDIE:-NO}"
|
||||||
|
CLAWDIE_ARTIFACT_DIR="${CLAWDIE_ARTIFACT_DIR:-}"
|
||||||
|
CLAWDIE_ENABLE="${CLAWDIE_ENABLE:-YES}"
|
||||||
|
|
||||||
# Local LLM runtime (optional)
|
# Local LLM runtime (optional)
|
||||||
# Choices: none | ollama | llama_cpp
|
# Choices: none | ollama | llama_cpp
|
||||||
LOCAL_LLM_PROVIDER="${LOCAL_LLM_PROVIDER:-none}"
|
LOCAL_LLM_PROVIDER="${LOCAL_LLM_PROVIDER:-none}"
|
||||||
|
|
|
||||||
101
build.sh
101
build.sh
|
|
@ -121,6 +121,7 @@ echo " Pkg : ${DEFAULT_PKG_BRANCH}"
|
||||||
echo " GPU : ${GPU_DRIVER:-auto-detect}"
|
echo " GPU : ${GPU_DRIVER:-auto-detect}"
|
||||||
echo " Target : ${TARGET:-baremetal}"
|
echo " Target : ${TARGET:-baremetal}"
|
||||||
echo " Colibri : ${FEATURE_COLIBRI:-NO}"
|
echo " Colibri : ${FEATURE_COLIBRI:-NO}"
|
||||||
|
echo " Clawdie : ${FEATURE_CLAWDIE:-NO}"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# Name the output for the thing we are actually building.
|
# Name the output for the thing we are actually building.
|
||||||
|
|
@ -310,6 +311,41 @@ preflight_colibri_artifacts() {
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# clawdie shares the ../colibri checkout; CLAWDIE_ARTIFACT_DIR overrides where
|
||||||
|
# the prebuilt `clawdie` binary is found.
|
||||||
|
resolve_clawdie_paths() {
|
||||||
|
resolve_colibri_paths
|
||||||
|
_resolved_clawdie_repo="${_resolved_colibri_repo}"
|
||||||
|
if [ -n "${CLAWDIE_ARTIFACT_DIR:-}" ]; then
|
||||||
|
_resolved_clawdie_artifact_dir="${CLAWDIE_ARTIFACT_DIR}"
|
||||||
|
case "${_resolved_clawdie_artifact_dir}" in
|
||||||
|
/*) ;;
|
||||||
|
*) _resolved_clawdie_artifact_dir="${SCRIPT_DIR}/${_resolved_clawdie_artifact_dir}" ;;
|
||||||
|
esac
|
||||||
|
else
|
||||||
|
_resolved_clawdie_artifact_dir="${_resolved_clawdie_repo}/target/release"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
preflight_clawdie_artifacts() {
|
||||||
|
[ "${FEATURE_CLAWDIE:-NO}" = "YES" ] || return 0
|
||||||
|
[ "${FETCH_ONLY:-0}" -eq 0 ] || return 0
|
||||||
|
|
||||||
|
resolve_clawdie_paths
|
||||||
|
_clawdie_rc="${_resolved_clawdie_repo}/packaging/freebsd/clawdie.in"
|
||||||
|
if [ ! -f "${_clawdie_rc}" ]; then
|
||||||
|
echo "ERROR: clawdie rc.d source missing: ${_clawdie_rc}"
|
||||||
|
echo " Set COLIBRI_REPO=/path/to/colibri or FEATURE_CLAWDIE=NO."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ ! -x "${_resolved_clawdie_artifact_dir}/clawdie" ]; then
|
||||||
|
echo "ERROR: clawdie release binary missing: ${_resolved_clawdie_artifact_dir}/clawdie"
|
||||||
|
echo " Build first: (cd ${_resolved_clawdie_repo} && cargo build --release -p clawdie)"
|
||||||
|
echo " Or set FEATURE_CLAWDIE=NO to skip clawdie staging."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
override_networkmgr_package() {
|
override_networkmgr_package() {
|
||||||
_networkmgr_pkg=$(find "${PKG_REPO_DIR}/All/Hashed" -maxdepth 1 -type f -name 'networkmgr-*.pkg' | sort | tail -1)
|
_networkmgr_pkg=$(find "${PKG_REPO_DIR}/All/Hashed" -maxdepth 1 -type f -name 'networkmgr-*.pkg' | sort | tail -1)
|
||||||
if [ -z "${_networkmgr_pkg:-}" ]; then
|
if [ -z "${_networkmgr_pkg:-}" ]; then
|
||||||
|
|
@ -745,6 +781,69 @@ install_colibri_service() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
install_clawdie_service() {
|
||||||
|
[ "${FEATURE_CLAWDIE:-NO}" = "YES" ] || {
|
||||||
|
echo " Clawdie agent staging disabled (FEATURE_CLAWDIE=${FEATURE_CLAWDIE:-NO})"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
echo " Staging Clawdie agent..."
|
||||||
|
|
||||||
|
resolve_clawdie_paths
|
||||||
|
|
||||||
|
env \
|
||||||
|
COLIBRI_REPO="${_resolved_clawdie_repo}" \
|
||||||
|
CLAWDIE_ARTIFACT_DIR="${_resolved_clawdie_artifact_dir}" \
|
||||||
|
CLAWDIE_STAGE_ENABLE="${CLAWDIE_ENABLE:-YES}" \
|
||||||
|
"${SCRIPT_DIR}/scripts/stage-clawdie-iso.sh" "${MOUNT_POINT}"
|
||||||
|
|
||||||
|
if ! /usr/sbin/pw -R "${MOUNT_POINT}" groupshow clawdie >/dev/null 2>&1; then
|
||||||
|
/usr/sbin/pw -R "${MOUNT_POINT}" groupadd clawdie
|
||||||
|
fi
|
||||||
|
if ! /usr/sbin/pw -R "${MOUNT_POINT}" usershow clawdie >/dev/null 2>&1; then
|
||||||
|
/usr/sbin/pw -R "${MOUNT_POINT}" useradd clawdie \
|
||||||
|
-g clawdie \
|
||||||
|
-d /var/db/clawdie \
|
||||||
|
-s /usr/sbin/nologin \
|
||||||
|
-c "Clawdie Agent"
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p \
|
||||||
|
"${MOUNT_POINT}/var/db/clawdie" \
|
||||||
|
"${MOUNT_POINT}/var/run/clawdie" \
|
||||||
|
"${MOUNT_POINT}/var/log/clawdie"
|
||||||
|
chroot "${MOUNT_POINT}" chown -R clawdie:clawdie \
|
||||||
|
/var/db/clawdie \
|
||||||
|
/var/run/clawdie \
|
||||||
|
/var/log/clawdie
|
||||||
|
chmod 0750 \
|
||||||
|
"${MOUNT_POINT}/var/db/clawdie" \
|
||||||
|
"${MOUNT_POINT}/var/run/clawdie" \
|
||||||
|
"${MOUNT_POINT}/var/log/clawdie"
|
||||||
|
|
||||||
|
set_config_line "${MOUNT_POINT}/etc/rc.conf" "clawdie_enable=\"${CLAWDIE_ENABLE:-YES}\""
|
||||||
|
set_config_line "${MOUNT_POINT}/etc/rc.conf" 'clawdie_user="clawdie"'
|
||||||
|
set_config_line "${MOUNT_POINT}/etc/rc.conf" 'clawdie_group="clawdie"'
|
||||||
|
set_config_line "${MOUNT_POINT}/etc/rc.conf" 'clawdie_data_dir="/var/db/clawdie"'
|
||||||
|
set_config_line "${MOUNT_POINT}/etc/rc.conf" 'clawdie_run_dir="/var/run/clawdie"'
|
||||||
|
set_config_line "${MOUNT_POINT}/etc/rc.conf" 'clawdie_socket="/var/run/clawdie/clawdie.sock"'
|
||||||
|
set_config_line "${MOUNT_POINT}/etc/rc.conf" 'clawdie_logfile="/var/log/clawdie/clawdie.log"'
|
||||||
|
set_config_line "${MOUNT_POINT}/etc/rc.conf" 'clawdie_host="$(hostname)"'
|
||||||
|
|
||||||
|
if [ ! -x "${MOUNT_POINT}/usr/local/bin/clawdie" ]; then
|
||||||
|
echo "ERROR: clawdie binary missing from live image"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ ! -x "${MOUNT_POINT}/usr/local/etc/rc.d/clawdie" ]; then
|
||||||
|
echo "ERROR: clawdie rc.d script missing from live image"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if ! /usr/sbin/pw -R "${MOUNT_POINT}" usershow clawdie >/dev/null 2>&1; then
|
||||||
|
echo "ERROR: clawdie service user missing from live image"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
install_live_npm_globals() {
|
install_live_npm_globals() {
|
||||||
echo " Installing bundled npm globals into live image..."
|
echo " Installing bundled npm globals into live image..."
|
||||||
|
|
||||||
|
|
@ -1517,6 +1616,7 @@ EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
preflight_colibri_artifacts
|
preflight_colibri_artifacts
|
||||||
|
preflight_clawdie_artifacts
|
||||||
|
|
||||||
# --- step 1: fetch FreeBSD memstick ---
|
# --- step 1: fetch FreeBSD memstick ---
|
||||||
MEMSTICK="${CACHE_DIR}/FreeBSD-${FREEBSD_VERSION}-${FREEBSD_ARCH}-memstick.img"
|
MEMSTICK="${CACHE_DIR}/FreeBSD-${FREEBSD_VERSION}-${FREEBSD_ARCH}-memstick.img"
|
||||||
|
|
@ -1907,6 +2007,7 @@ rm -f "${MOUNT_POINT}/etc/installerconfig"
|
||||||
install_live_runtime_packages
|
install_live_runtime_packages
|
||||||
configure_live_operator_session
|
configure_live_operator_session
|
||||||
install_colibri_service
|
install_colibri_service
|
||||||
|
install_clawdie_service
|
||||||
|
|
||||||
# Copy payload
|
# Copy payload
|
||||||
# Rebuild payload paths from scratch inside the reusable work image. A failed
|
# Rebuild payload paths from scratch inside the reusable work image. A failed
|
||||||
|
|
|
||||||
107
scripts/stage-clawdie-iso.sh
Executable file
107
scripts/stage-clawdie-iso.sh
Executable file
|
|
@ -0,0 +1,107 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Stage the prebuilt `clawdie` FreeBSD binary + rc.d service into an image root.
|
||||||
|
#
|
||||||
|
# `clawdie` is the simplified, operator-friendly Colibri agent: one small binary
|
||||||
|
# (glasspane + herdr + DeepSeek/Telegram). This script does NOT build it — build
|
||||||
|
# or provide the artifact first, optionally with baked credentials:
|
||||||
|
#
|
||||||
|
# (cd ../colibri && CLAWDIE_TG_TOKEN=... CLAWDIE_DEEPSEEK_KEY=... \
|
||||||
|
# cargo build --release -p clawdie)
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# COLIBRI_REPO=../colibri scripts/stage-clawdie-iso.sh /path/to/image-root
|
||||||
|
# CLAWDIE_ARTIFACT_DIR=/path/to/release scripts/stage-clawdie-iso.sh /path/to/image-root
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
if [ "${1:-}" = "" ]; then
|
||||||
|
echo "usage: $0 DESTDIR" >&2
|
||||||
|
exit 64
|
||||||
|
fi
|
||||||
|
|
||||||
|
DESTDIR=$1
|
||||||
|
SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||||
|
REPO_ROOT=$(CDPATH= cd -- "${SCRIPT_DIR}/.." && pwd)
|
||||||
|
COLIBRI_REPO=${COLIBRI_REPO:-"${REPO_ROOT}/../colibri"}
|
||||||
|
CLAWDIE_ARTIFACT_DIR=${CLAWDIE_ARTIFACT_DIR:-"${COLIBRI_REPO}/target/release"}
|
||||||
|
CLAWDIE_STAGE_ENABLE=${CLAWDIE_STAGE_ENABLE:-YES}
|
||||||
|
|
||||||
|
BIN_DIR="${DESTDIR}/usr/local/bin"
|
||||||
|
RC_DIR="${DESTDIR}/usr/local/etc/rc.d"
|
||||||
|
ETC_DIR="${DESTDIR}/usr/local/etc/clawdie"
|
||||||
|
DB_DIR="${DESTDIR}/var/db/clawdie"
|
||||||
|
RUN_DIR="${DESTDIR}/var/run/clawdie"
|
||||||
|
LOG_DIR="${DESTDIR}/var/log/clawdie"
|
||||||
|
RC_SOURCE="${COLIBRI_REPO}/packaging/freebsd/clawdie.in"
|
||||||
|
|
||||||
|
require_file() {
|
||||||
|
if [ ! -f "$1" ]; then
|
||||||
|
echo "missing required clawdie artifact: $1" >&2
|
||||||
|
exit 66
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
require_exec() {
|
||||||
|
if [ ! -x "$1" ]; then
|
||||||
|
echo "missing executable clawdie artifact: $1" >&2
|
||||||
|
echo "hint: (cd ${COLIBRI_REPO} && cargo build --release -p clawdie)" >&2
|
||||||
|
exit 66
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
require_file "${RC_SOURCE}"
|
||||||
|
require_exec "${CLAWDIE_ARTIFACT_DIR}/clawdie"
|
||||||
|
mkdir -p "${BIN_DIR}" "${RC_DIR}" "${ETC_DIR}" "${DB_DIR}" "${RUN_DIR}" "${LOG_DIR}"
|
||||||
|
|
||||||
|
install -m 0555 "${CLAWDIE_ARTIFACT_DIR}/clawdie" "${BIN_DIR}/clawdie"
|
||||||
|
install -m 0555 "${RC_SOURCE}" "${RC_DIR}/clawdie"
|
||||||
|
|
||||||
|
cat > "${ETC_DIR}/rc.conf.sample" <<EOF
|
||||||
|
# Clawdie agent service defaults for the Clawdie ISO.
|
||||||
|
# Merge into /etc/rc.conf or /etc/rc.conf.d/clawdie.
|
||||||
|
clawdie_enable="${CLAWDIE_STAGE_ENABLE}"
|
||||||
|
clawdie_user="clawdie"
|
||||||
|
clawdie_group="clawdie"
|
||||||
|
clawdie_data_dir="/var/db/clawdie"
|
||||||
|
clawdie_run_dir="/var/run/clawdie"
|
||||||
|
clawdie_socket="/var/run/clawdie/clawdie.sock"
|
||||||
|
clawdie_logfile="/var/log/clawdie/clawdie.log"
|
||||||
|
clawdie_host="\$(hostname)"
|
||||||
|
clawdie_env_file="/usr/local/etc/clawdie/clawdie.env"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Per-host credential override template (binary keeps its baked build-flag
|
||||||
|
# defaults; this file is optional and only read if present + readable).
|
||||||
|
if [ ! -f "${ETC_DIR}/clawdie.env" ]; then
|
||||||
|
cat > "${ETC_DIR}/clawdie.env.sample" <<'EOF'
|
||||||
|
# Optional per-host credential overrides for clawdie.
|
||||||
|
# Copy to clawdie.env (chmod 0600) to override the baked build-flag values.
|
||||||
|
# CLAWDIE_TG_TOKEN=123456:telegram-bot-token
|
||||||
|
# CLAWDIE_DEEPSEEK_KEY=sk-deepseek-key
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat > "${ETC_DIR}/README.iso" <<'EOF'
|
||||||
|
Clawdie agent ISO staging notes
|
||||||
|
===============================
|
||||||
|
|
||||||
|
The ISO build creates the clawdie user/group and enables the rc.d service
|
||||||
|
according to build.cfg. Out of the box clawdie offers exactly: a Telegram bot
|
||||||
|
and a DeepSeek lane — both normally baked at build time. Runtime validation:
|
||||||
|
|
||||||
|
service clawdie start
|
||||||
|
service clawdie status
|
||||||
|
sockstat | grep clawdie # Herdr socket bound
|
||||||
|
service clawdie stop
|
||||||
|
|
||||||
|
Lifted on purpose: cost modes, quotas, multi-provider fallback, per-user limits.
|
||||||
|
EOF
|
||||||
|
|
||||||
|
chmod 0750 "${DB_DIR}" "${RUN_DIR}" "${LOG_DIR}"
|
||||||
|
|
||||||
|
cat <<EOF
|
||||||
|
Staged clawdie into ${DESTDIR}
|
||||||
|
artifact : ${CLAWDIE_ARTIFACT_DIR}/clawdie
|
||||||
|
rc.d : ${RC_SOURCE}
|
||||||
|
enable : ${CLAWDIE_STAGE_ENABLE}
|
||||||
|
EOF
|
||||||
|
|
@ -187,6 +187,52 @@ rm -rf /tmp/colibri-*
|
||||||
`colibri-tui` is optional in the staging script, but desired for this operator
|
`colibri-tui` is optional in the staging script, but desired for this operator
|
||||||
USB target and should be verified with the other three binaries.
|
USB target and should be verified with the other three binaries.
|
||||||
|
|
||||||
|
### Clawdie agent preflight (optional simplified lane)
|
||||||
|
|
||||||
|
`FEATURE_CLAWDIE` (default `NO`) stages the simplified `clawdie` agent — one
|
||||||
|
small binary (glasspane + herdr + DeepSeek/Telegram) built from the same
|
||||||
|
`../colibri` checkout. Enable it for the simplified operator image. The two
|
||||||
|
credentials are normally baked at build time:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd /home/clawdie/colibri
|
||||||
|
CLAWDIE_TG_TOKEN="<telegram-bot-token>" \
|
||||||
|
CLAWDIE_DEEPSEEK_KEY="<deepseek-key>" \
|
||||||
|
cargo build --release -p clawdie
|
||||||
|
|
||||||
|
ls -lh target/release/clawdie
|
||||||
|
file target/release/clawdie
|
||||||
|
```
|
||||||
|
|
||||||
|
Leave the flags unset to ship a "bring your own key" binary configured via the
|
||||||
|
rc.d env file (`/usr/local/etc/clawdie/clawdie.env`) at runtime. Same cleanup
|
||||||
|
invariant as Colibri: do **not** `cargo clean` until the ISO build has consumed
|
||||||
|
`../colibri/target/release/clawdie`. ISO-repo preflight:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd /home/clawdie/clawdie-iso
|
||||||
|
sh -n build.sh
|
||||||
|
sh -n scripts/stage-clawdie-iso.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
See `../colibri/docs/CLAWDIE-BUILD.md` and `../colibri/docs/CLAWDIE-AGENT-WIKI.md`.
|
||||||
|
|
||||||
|
### Next build: carry the XFCE operator-USB fixes
|
||||||
|
|
||||||
|
The next operator-USB image must retain the proven XFCE/live-GUI fixes
|
||||||
|
(`PLAN-OPERATOR-USB-NEXT.md`, `doc/AMD-ASUS-XFCE-LIVE-USB-FINDINGS.md`):
|
||||||
|
|
||||||
|
- **SDDM over LightDM** — load-bearing; do not revert (LightDM was the silent
|
||||||
|
live-GUI blocker on Intel + AMD).
|
||||||
|
- **`clawdie-live-gpu`** pre-SDDM rc.d KMS pick (conservative; NVIDIA/AMD safe).
|
||||||
|
- **Hardened USB-root power policy** (`b9290ab`): `powerdxx`, C3 C-state default,
|
||||||
|
`hw.usb.no_suspend=1`, boot-time `power_profile`.
|
||||||
|
- Base fixes already landed: resolver bootstrap, internal-audio preference,
|
||||||
|
touchpad XInput guards, loader branding, hardware-report capture.
|
||||||
|
|
||||||
|
Real hardware remains final proof for XFCE/session/input/audio — bhyve and
|
||||||
|
static image inspection are build gates only.
|
||||||
|
|
||||||
## Choose fetch mode
|
## Choose fetch mode
|
||||||
|
|
||||||
Use the lightest safe flag:
|
Use the lightest safe flag:
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue