feat(#2290): maintain /etc/tmpfiles.d/hyperhive-agents.conf for boot safety

Root cause of the boot outage: container@h-* units try to start before
hive-c0re reaches ensure_runtime, so bind-mount source dirs are missing.

Fix: hive-c0re (via hive-priv, which runs as root) writes
/etc/tmpfiles.d/hyperhive-agents.conf whenever the agent set changes.
systemd-tmpfiles-setup.service (sysinit.target) reads it at every boot
BEFORE any container units start, pre-creating:

  /run/hyperhive/agents/<name>  — MCP socket dir (bind -> /run/hive)
  /run/hive-agent/<name>        — web socket dir (bind -> /run/hive-agent)

This alone removes the outage class: even if hive-c0re is slow to start,
the bind-mount sources exist and container units can activate.

Added:
- PrivRequest::SyncAgentTmpfiles { agents } in hive-sh4re
- sync_agent_tmpfiles() in hive-priv: generates content, writes atomically,
  calls systemd-tmpfiles --create to apply immediately
- priv_client::sync_agent_tmpfiles() wrapper
- lifecycle::sync_tmpfiles() best-effort helper (list + priv call)
- Call sites: hive-c0re startup, handle_spawn success, destroy success
This commit is contained in:
atlas 2026-07-08 22:59:04 +02:00 committed by mara
commit 9d1f5ebe76
7 changed files with 128 additions and 0 deletions

View file

@ -512,6 +512,21 @@ pub enum PrivRequest {
/// Logical agent name (validated by `validate_agent_name`).
agent_name: String,
},
/// Write `/etc/tmpfiles.d/hyperhive-agents.conf` for the given agent set
/// and immediately apply it with `systemd-tmpfiles --create`. Each entry
/// declares the per-agent runtime dirs (`/run/hyperhive/agents/<name>` and
/// `/run/hive-agent/<name>`) so systemd recreates them at every boot before
/// any container units start — preventing bind-mount source missing errors
/// when container@h-* units race hive-c0re after a reboot.
///
/// Called at hive-c0re startup and after every agent spawn / destroy.
/// Agents are logical names (validated by `validate_agent_name`).
SyncAgentTmpfiles {
/// Logical agent names (e.g. `"atlas"`, `"ruth"`). hive-priv validates
/// each name before writing any path component derived from it.
agents: Vec<String>,
},
}
/// Response from the privileged helper.