fix(firstboot): run installer as root so rc.d service is installed

shell-deploy.sh was dropping to the clawdie user before running
just install. setup/service.ts checks isRoot() to decide whether
to install the rc.d service or generate start/stop wrappers — so
running as clawdie meant the agent was never registered with
FreeBSD's service manager and never started at boot.

Fix: run the installer as root. setup/service.ts already handles
privilege separation correctly when invoked as root: it writes
/usr/local/etc/rc.d/{agent}, adds -u {agent} to daemon args so
the running process is never root, and chowns data/logs/groups to
the agent user to prevent EACCES on first write.

Also adds DB_RUNTIME to the generated .env seed so operators can
see the jail vs host postgres option without reading the docs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Sam & Claude 2026-04-16 08:42:50 +00:00 committed by 123kupola
parent e6f91d4517
commit 68f1c1fad7
2 changed files with 12 additions and 7 deletions

View file

@ -354,13 +354,13 @@ clawdie_shell_deploy_run_install_all() {
fi
log_msg "[deploy] Installer command: ${run_cmd}"
if [ "$(id -u)" -eq 0 ]; then
# Running as root, drop to clawdie user
su - clawdie -c "cd $CLAWDIE_AI_DIR && $run_cmd" 2>&1 | tee -a "$LOG_FILE" || return 1
else
# Running as clawdie user directly
$run_cmd 2>&1 | tee -a "$LOG_FILE" || return 1
fi
# Run as root regardless — setup/service.ts requires root to install the rc.d
# service, write /usr/local/etc/rc.d/{agent}, and run sysrc. When root,
# setup/service.ts handles privilege drop automatically: it chowns runtime dirs
# (data/, logs/, groups/) to the agent user and adds -u {agent} to daemon args
# so the running process is never root. Dropping to clawdie here would cause
# setup/service.ts to fall back to start/stop wrapper scripts instead of rc.d.
( cd "$CLAWDIE_AI_DIR" && $run_cmd ) 2>&1 | tee -a "$LOG_FILE" || return 1
return 0
}

View file

@ -123,6 +123,11 @@ EMBED_MODEL="${EMBED_MODEL:-BAAI/bge-m3}"
EMBED_API_KEY="${EMBED_API_KEY:-}"
EMBED_DIMENSIONS="${EMBED_DIMENSIONS:-1024}"
# === Database ===
# DB_RUNTIME=jail — PostgreSQL runs inside a bastille jail (default, provisioned by installer)
# DB_RUNTIME=host — PostgreSQL runs on the host; set DB_HOST to warden0 gateway IP
DB_RUNTIME="jail"
# === Network Configuration (warden0) ===
AGENT_SUBNET_BASE="$AGENT_SUBNET_BASE"
WARDEN_SUBNET_BASE="$AGENT_SUBNET_BASE"