feat(iso): stage zot agent (pinned) + populate ZOT_HOME/auth.json (Sam & Claude) #38
3 changed files with 166 additions and 0 deletions
16
build.cfg
16
build.cfg
|
|
@ -116,6 +116,22 @@ FEATURE_CLAWDIE="${FEATURE_CLAWDIE:-NO}"
|
|||
CLAWDIE_ARTIFACT_DIR="${CLAWDIE_ARTIFACT_DIR:-}"
|
||||
CLAWDIE_ENABLE="${CLAWDIE_ENABLE:-NO}"
|
||||
|
||||
# zot agent harness (the consolidation target — see colibri ADR
|
||||
# docs/ADR-agent-harness-consolidation.md). zot is a single static Go binary
|
||||
# (providers incl. DeepSeek, Telegram bot, json/rpc modes, SKILL.md, extensions).
|
||||
# Opt-in (default NO) while Pi stays the default harness during migration.
|
||||
# Pin a tag for reproducible images; zot has no FreeBSD release, so the build
|
||||
# host compiles it: (cd $ZOT_REPO && git checkout $ZOT_VERSION &&
|
||||
# GOOS=freebsd GOARCH=amd64 go build -trimpath -o bin/zot ./cmd/zot)
|
||||
FEATURE_ZOT="${FEATURE_ZOT:-NO}"
|
||||
ZOT_VERSION="${ZOT_VERSION:-v0.2.29}"
|
||||
ZOT_REPO="${ZOT_REPO:-/home/clawdie/ai/zot}"
|
||||
ZOT_ARTIFACT_DIR="${ZOT_ARTIFACT_DIR:-}"
|
||||
# Optional: bake the operator's DeepSeek key into $ZOT_HOME/auth.json (0600).
|
||||
# Leave blank to stage an auth.json.sample template the operator fills in, or
|
||||
# to configure at runtime via `zot` env / `zot telegram-bot setup`.
|
||||
ZOT_DEEPSEEK_KEY="${ZOT_DEEPSEEK_KEY:-}"
|
||||
|
||||
# Local LLM runtime (optional)
|
||||
# Choices: none | ollama | llama_cpp
|
||||
LOCAL_LLM_PROVIDER="${LOCAL_LLM_PROVIDER:-none}"
|
||||
|
|
|
|||
61
build.sh
61
build.sh
|
|
@ -123,6 +123,7 @@ echo " NVIDIA universal : ${NVIDIA_UNIVERSAL:-NO}"
|
|||
echo " Target : ${TARGET:-baremetal}"
|
||||
echo " Colibri : ${FEATURE_COLIBRI:-NO}"
|
||||
echo " Clawdie agent : ${FEATURE_CLAWDIE:-NO}"
|
||||
echo " zot agent : ${FEATURE_ZOT:-NO} (${ZOT_VERSION:-})"
|
||||
echo ""
|
||||
|
||||
# Name the output for the thing we are actually building.
|
||||
|
|
@ -371,6 +372,38 @@ preflight_clawdie_artifacts() {
|
|||
fi
|
||||
}
|
||||
|
||||
resolve_zot_paths() {
|
||||
_resolved_zot_repo="${ZOT_REPO:-${SCRIPT_DIR}/../zot}"
|
||||
case "${_resolved_zot_repo}" in
|
||||
/*) ;;
|
||||
*) _resolved_zot_repo="${SCRIPT_DIR}/${_resolved_zot_repo}" ;;
|
||||
esac
|
||||
if [ -n "${ZOT_ARTIFACT_DIR:-}" ]; then
|
||||
_resolved_zot_artifact_dir="${ZOT_ARTIFACT_DIR}"
|
||||
case "${_resolved_zot_artifact_dir}" in
|
||||
/*) ;;
|
||||
*) _resolved_zot_artifact_dir="${SCRIPT_DIR}/${_resolved_zot_artifact_dir}" ;;
|
||||
esac
|
||||
else
|
||||
_resolved_zot_artifact_dir="${_resolved_zot_repo}/bin"
|
||||
fi
|
||||
}
|
||||
|
||||
preflight_zot_artifacts() {
|
||||
[ "${FEATURE_ZOT:-NO}" = "YES" ] || return 0
|
||||
[ "${FETCH_ONLY:-0}" -eq 0 ] || return 0
|
||||
|
||||
resolve_zot_paths
|
||||
if [ ! -x "${_resolved_zot_artifact_dir}/zot" ]; then
|
||||
echo "ERROR: zot binary missing: ${_resolved_zot_artifact_dir}/zot"
|
||||
echo " zot has no FreeBSD release — build it first:"
|
||||
echo " (cd ${_resolved_zot_repo} && git checkout ${ZOT_VERSION:-v0.2.29} && \\"
|
||||
echo " GOOS=freebsd GOARCH=amd64 go build -trimpath -o bin/zot ./cmd/zot)"
|
||||
echo " Or set FEATURE_ZOT=NO to skip zot staging."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
override_networkmgr_package() {
|
||||
_networkmgr_pkg=$(find "${PKG_REPO_DIR}/All/Hashed" -maxdepth 1 -type f -name 'networkmgr-*.pkg' | sort | tail -1)
|
||||
if [ -z "${_networkmgr_pkg:-}" ]; then
|
||||
|
|
@ -854,6 +887,32 @@ install_colibri_service() {
|
|||
fi
|
||||
}
|
||||
|
||||
install_zot_agent() {
|
||||
[ "${FEATURE_ZOT:-NO}" = "YES" ] || {
|
||||
echo " zot agent staging disabled (FEATURE_ZOT=${FEATURE_ZOT:-NO})"
|
||||
return 0
|
||||
}
|
||||
|
||||
echo " Staging zot agent (${ZOT_VERSION:-})..."
|
||||
resolve_zot_paths
|
||||
|
||||
env \
|
||||
ZOT_ARTIFACT_DIR="${_resolved_zot_artifact_dir}" \
|
||||
ZOT_OPERATOR="clawdie" \
|
||||
ZOT_DEEPSEEK_KEY="${ZOT_DEEPSEEK_KEY:-}" \
|
||||
"${SCRIPT_DIR}/scripts/stage-zot-iso.sh" "${MOUNT_POINT}"
|
||||
|
||||
# zot state lives in the operator's home; own it as the operator.
|
||||
if /usr/sbin/pw -R "${MOUNT_POINT}" usershow clawdie >/dev/null 2>&1; then
|
||||
chroot "${MOUNT_POINT}" chown -R clawdie:clawdie /home/clawdie/.local 2>/dev/null || true
|
||||
fi
|
||||
|
||||
if [ ! -x "${MOUNT_POINT}/usr/local/bin/zot" ]; then
|
||||
echo "ERROR: zot binary missing from live image"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
install_clawdie_service() {
|
||||
[ "${FEATURE_CLAWDIE:-NO}" = "YES" ] || {
|
||||
echo " Clawdie agent staging disabled (FEATURE_CLAWDIE=${FEATURE_CLAWDIE:-NO})"
|
||||
|
|
@ -1832,6 +1891,7 @@ EOF
|
|||
|
||||
preflight_colibri_artifacts
|
||||
preflight_clawdie_artifacts
|
||||
preflight_zot_artifacts
|
||||
|
||||
# --- step 1: fetch FreeBSD memstick ---
|
||||
MEMSTICK="${CACHE_DIR}/FreeBSD-${FREEBSD_VERSION}-${FREEBSD_ARCH}-memstick.img"
|
||||
|
|
@ -2223,6 +2283,7 @@ install_live_runtime_packages
|
|||
configure_live_operator_session
|
||||
install_colibri_service
|
||||
install_clawdie_service
|
||||
install_zot_agent
|
||||
install_nvidia_universal_repo
|
||||
|
||||
# Copy payload
|
||||
|
|
|
|||
89
scripts/stage-zot-iso.sh
Executable file
89
scripts/stage-zot-iso.sh
Executable file
|
|
@ -0,0 +1,89 @@
|
|||
#!/bin/sh
|
||||
# Stage the prebuilt `zot` agent binary + credentials into an image root.
|
||||
#
|
||||
# zot is the agent-harness consolidation target (one static Go binary). It has no
|
||||
# FreeBSD release, so build it on the host first and point ZOT_ARTIFACT_DIR here:
|
||||
# (cd ../zot && git checkout "$ZOT_VERSION" \
|
||||
# && GOOS=freebsd GOARCH=amd64 go build -trimpath -o bin/zot ./cmd/zot)
|
||||
#
|
||||
# Credentials: zot resolves provider keys as --api-key -> provider env var ->
|
||||
# $ZOT_HOME/auth.json. This stages auth.json (DeepSeek) under the operator's
|
||||
# default ZOT_HOME (~/.local/state/zot). The Telegram token is configured
|
||||
# separately at runtime via `zot telegram-bot setup` (it lives in zot state).
|
||||
#
|
||||
# Usage:
|
||||
# ZOT_ARTIFACT_DIR=/path/to/bin scripts/stage-zot-iso.sh /path/to/image-root
|
||||
|
||||
set -eu
|
||||
|
||||
if [ "${1:-}" = "" ]; then
|
||||
echo "usage: $0 DESTDIR" >&2
|
||||
exit 64
|
||||
fi
|
||||
|
||||
DESTDIR=$1
|
||||
ZOT_ARTIFACT_DIR=${ZOT_ARTIFACT_DIR:?set ZOT_ARTIFACT_DIR to the dir holding the built zot binary}
|
||||
ZOT_OPERATOR=${ZOT_OPERATOR:-clawdie}
|
||||
ZOT_DEEPSEEK_KEY=${ZOT_DEEPSEEK_KEY:-}
|
||||
|
||||
BIN_SRC="${ZOT_ARTIFACT_DIR}/zot"
|
||||
BIN_DIR="${DESTDIR}/usr/local/bin"
|
||||
# zot's default ZOT_HOME on FreeBSD is ~/.local/state/zot
|
||||
ZOT_HOME_REL=".local/state/zot"
|
||||
OP_HOME="${DESTDIR}/home/${ZOT_OPERATOR}"
|
||||
ZOT_HOME="${OP_HOME}/${ZOT_HOME_REL}"
|
||||
|
||||
if [ ! -x "${BIN_SRC}" ]; then
|
||||
echo "missing executable zot artifact: ${BIN_SRC}" >&2
|
||||
echo "hint: (cd \$ZOT_REPO && GOOS=freebsd GOARCH=amd64 go build -trimpath -o bin/zot ./cmd/zot)" >&2
|
||||
exit 66
|
||||
fi
|
||||
|
||||
mkdir -p "${BIN_DIR}" "${ZOT_HOME}"
|
||||
install -m 0555 "${BIN_SRC}" "${BIN_DIR}/zot"
|
||||
|
||||
# auth.json: bake the DeepSeek key if provided (0600), else leave a template.
|
||||
if [ -n "${ZOT_DEEPSEEK_KEY}" ]; then
|
||||
umask 077
|
||||
cat > "${ZOT_HOME}/auth.json" <<EOF
|
||||
{
|
||||
"deepseek": { "api_key": "${ZOT_DEEPSEEK_KEY}" }
|
||||
}
|
||||
EOF
|
||||
chmod 0600 "${ZOT_HOME}/auth.json"
|
||||
_cred_note="auth.json baked with DeepSeek key (0600)"
|
||||
else
|
||||
cat > "${ZOT_HOME}/auth.json.sample" <<'EOF'
|
||||
{
|
||||
"deepseek": { "api_key": "sk-REPLACE-ME" }
|
||||
}
|
||||
EOF
|
||||
_cred_note="auth.json.sample staged (operator copies to auth.json, chmod 0600)"
|
||||
fi
|
||||
|
||||
cat > "${ZOT_HOME}/README.iso" <<EOF
|
||||
zot agent — ISO staging notes
|
||||
=============================
|
||||
|
||||
Binary: /usr/local/bin/zot (pinned build; FreeBSD-native, no release tarball)
|
||||
State (ZOT_HOME): ~/.local/state/zot (config.json, auth.json, sessions/, logs/)
|
||||
|
||||
Credentials (zot order: --api-key -> provider env -> auth.json):
|
||||
- ${_cred_note}
|
||||
- or export DEEPSEEK_API_KEY at runtime.
|
||||
|
||||
Telegram bridge (token stored in zot state, not auth.json):
|
||||
zot telegram-bot setup # paste BotFather token
|
||||
zot telegram-bot start
|
||||
|
||||
Supervision contract for Colibri glasspane:
|
||||
zot --json "..." # newline-delimited json events
|
||||
zot rpc # json-rpc loop
|
||||
EOF
|
||||
|
||||
cat <<EOF
|
||||
Staged zot into ${DESTDIR}
|
||||
binary : ${BIN_DIR}/zot (from ${BIN_SRC})
|
||||
state : home/${ZOT_OPERATOR}/${ZOT_HOME_REL}
|
||||
creds : ${_cred_note}
|
||||
EOF
|
||||
Loading…
Add table
Reference in a new issue