Watch
0
0
Fork
You've already forked hyperhive
0

hive-c0re: bound the read-only container listing and systemctl status calls

priv_client::list_containers now waits at most 30s (LIST_WAIT) for
hive-priv's `nixos-container list`, via the existing `within` helper. Its
periodic callers (crash_watch, agent_sockets, swarm_agent_status, wanted,
mcp_sockets, swarm_status via container_view) already treat an Err as a
skipped cycle, so a hung listing no longer stops their loops for good.

lifecycle::is_running / unit_state run `systemctl is-active` with
kill_on_drop and a 10s timeout (IS_ACTIVE_TIMEOUT); a timeout warns and
reads as not-running / UnitState::Other, the same as a systemctl that
could not be spawned. The new lifecycle::running_state returns None for
that case, and crash_watch keeps the agent's previous observation on None
so a hung systemctl is neither reported as a crash nor as a recovery.

`call` itself and every mutating op (start/stop/destroy/send-snapshot/
daemon-reload) stay unbounded.

Closes #5061
This commit is contained in:
atlas 2026-10-09 15:30:32 +02:00
commit 3cb7be29cf
5 changed files with 106 additions and 19 deletions

View file

@ -271,8 +271,16 @@ pub async fn destroy_container(name: &str) -> Result<()> {
.await?)
}
/// How long hive-c0re waits for hive-priv's `nixos-container list`. Periodic
/// workers await the listing inline, so a hung one must reach them as an
/// error they skip a cycle on, not as a wait that stops their loop.
const LIST_WAIT: std::time::Duration = std::time::Duration::from_secs(30);
/// # Errors
/// Returns an error if the hive-priv call fails or doesn't answer within
/// [`LIST_WAIT`], or `nixos-container list` exits non-zero.
pub async fn list_containers() -> Result<String> {
let (stdout, _) = check(call(&PrivRequest::ListContainers).await?)?;
let (stdout, _) = check(within(LIST_WAIT, call(&PrivRequest::ListContainers)).await?)?;
Ok(stdout)
}