feat(#2006): add services.hyperhive.manageRootAgent to opt out of root-agent auto-management

This commit is contained in:
damocles 2026-06-26 22:23:28 +02:00 committed by mara
commit 4fa17de387
2 changed files with 50 additions and 5 deletions

View file

@ -164,12 +164,33 @@ pub async fn rebuild_agent(
result
}
/// Whether hive-c0re auto-manages the root/manager agent — creating it on
/// startup and restarting it when present-but-stopped. Controlled by the
/// host option `services.hyperhive.manageRootAgent`, threaded in via the
/// `HYPERHIVE_MANAGE_ROOT_AGENT` env var. Defaults to enabled when the
/// var is unset (back-compat: the root agent was always managed before
/// this opt-out existed); only an explicit `false` / `0` / `no` disables.
fn manage_root_agent() -> bool {
match std::env::var("HYPERHIVE_MANAGE_ROOT_AGENT") {
Ok(v) => !matches!(v.trim().to_ascii_lowercase().as_str(), "false" | "0" | "no"),
Err(_) => true,
}
}
/// Auto-create the manager container on startup if it isn't already there.
/// hive-c0re manages the manager end-to-end: operators no longer declare
/// `containers.h-ruth` in their host NixOS config. Bypasses the approval
/// queue — the root/manager is auto-managed by default (an operator opt-out
/// is a separate host setting). Idempotent.
/// queue — the root/manager is auto-managed by default. Operators who
/// don't want a root agent at all set `services.hyperhive.manageRootAgent
/// = false`, which short-circuits this whole function. Idempotent.
pub async fn ensure_root_agent(coord: &Arc<Coordinator>) -> Result<()> {
if !manage_root_agent() {
tracing::info!(
"root-agent auto-management disabled (services.hyperhive.manageRootAgent = false) - \
skipping root agent create/start"
);
return Ok(());
}
let existing = lifecycle::list().await.unwrap_or_default();
let current_rev = current_flake_rev(&coord.hyperhive_flake);
if existing
@ -201,9 +222,10 @@ pub async fn ensure_root_agent(coord: &Arc<Coordinator>) -> Result<()> {
// install) is brought back up here: the startup sweep's rebuild only
// restarts a container that was already running, so without this it
// stays down until a manual `nixos-container start`. The sub-agent
// `was_running` guard is intentionally left untouched. (An operator
// opt-out of this whole auto-management is tracked as a separate
// host setting.)
// `was_running` guard is intentionally left untouched. (Operators
// opt out of this whole auto-management with
// `services.hyperhive.manageRootAgent = false`, gated at the top of
// this function.)
if !lifecycle::is_running(MANAGER_NAME).await {
tracing::info!("manager container present but not running — starting");
if let Err(e) = lifecycle::start(MANAGER_NAME).await {