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:
parent
d1ee3d8cc5
commit
3cb7be29cf
5 changed files with 106 additions and 19 deletions
|
|
@ -449,3 +449,27 @@ fn is_actionable_nix_line_keeps_warnings_and_errors_demotes_chatter() {
|
|||
assert!(!is_actionable_nix_line(line), "{line}");
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn a_hung_systemctl_reads_as_unknown_within_the_bound() {
|
||||
let started = tokio::time::Instant::now();
|
||||
let got = output_within(
|
||||
std::time::Duration::from_millis(20),
|
||||
std::future::pending::<std::io::Result<()>>(),
|
||||
&["is-active"],
|
||||
)
|
||||
.await;
|
||||
assert!(got.is_none());
|
||||
assert!(started.elapsed() < std::time::Duration::from_secs(5));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn a_systemctl_answer_inside_the_bound_passes_through() {
|
||||
let got = output_within(
|
||||
std::time::Duration::from_secs(5),
|
||||
async { Ok(7_u8) },
|
||||
&["is-active"],
|
||||
)
|
||||
.await;
|
||||
assert_eq!(got, Some(7));
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue