fix agent disk usage reading container-internal state path on the host

This commit is contained in:
damocles 2026-06-18 13:05:33 +02:00 committed by mara
commit 9a6306540b

View file

@ -83,9 +83,10 @@ fn disk_cache() -> &'static RwLock<HashMap<String, u64>> {
/// exactly the per-container-only measure we want. Best-effort: a
/// missing/unreadable path (e.g. a stopped container with no rootfs)
/// yields `None`, which the caller treats as 0.
async fn du_bytes(path: &str) -> Option<u64> {
async fn du_bytes(path: &std::path::Path) -> Option<u64> {
let out = tokio::process::Command::new("du")
.args(["-sxb", path])
.arg("-sxb")
.arg(path)
.output()
.await
.ok()?;
@ -96,14 +97,22 @@ async fn du_bytes(path: &str) -> Option<u64> {
stdout.split_whitespace().next()?.parse::<u64>().ok()
}
/// Total per-agent disk: state dir (`/agents/<name>/state`, the host
/// bind-mount) plus the container's writable rootfs
/// (`/var/lib/nixos-containers/h-<name>`). Each measured with `du -sxb`
/// so the shared nix store and other bind mounts are excluded. A path
/// that doesn't exist contributes 0.
/// Total per-agent disk: the agent's host-side state dir
/// (`/var/lib/hyperhive/agents/<name>/state`) plus the container's writable
/// rootfs (`/var/lib/nixos-containers/h-<name>`). Each measured with `du -sxb`
/// so the shared nix store and other bind mounts are excluded. A path that
/// doesn't exist contributes 0.
///
/// The state dir is resolved via [`Coordinator::agent_notes_dir`] — the same
/// host path the dashboard reads agent state from. Hardcoding the
/// container-internal bind-mount path (`/agents/<name>/state`) instead made
/// `du` fail host-side (that path only exists inside the container), so every
/// agent's state-dir contribution was 0; with the writable rootfs nearly empty
/// (almost everything is bind-mounted), that surfaced as all agents reporting
/// 0 disk.
async fn measure_agent_disk(name: &str) -> u64 {
let state_dir = format!("/agents/{name}/state");
let rootfs = format!("{NIXOS_CONTAINERS_ROOT}/h-{name}");
let state_dir = Coordinator::agent_notes_dir(name);
let rootfs = PathBuf::from(format!("{NIXOS_CONTAINERS_ROOT}/h-{name}"));
let mut total = 0u64;
for path in [state_dir, rootfs] {
if let Some(bytes) = du_bytes(&path).await {