diff --git a/hive-c0re/src/lifecycle.rs b/hive-c0re/src/lifecycle.rs index 31a3304..3debb67 100644 --- a/hive-c0re/src/lifecycle.rs +++ b/hive-c0re/src/lifecycle.rs @@ -592,6 +592,10 @@ const HOST_AGENTS_ROOT: &str = "/var/lib/hyperhive/agents"; /// `APPLIED_STATE_ROOT` in coordinator.rs. const HOST_APPLIED_ROOT: &str = "/var/lib/hyperhive/applied"; +/// On-host meta repo root, mirrored RO into the manager. Matches +/// `meta::meta_dir()` but duplicated here so lifecycle stays a leaf. +const HOST_META_ROOT: &str = "/var/lib/hyperhive/meta"; + fn set_nspawn_flags( container: &str, runtime_dir: &Path, @@ -607,6 +611,14 @@ fn set_nspawn_flags( notes = notes_dir.display(), ); if container == MANAGER_NAME { + use std::fmt::Write as _; + // systemd-nspawn refuses to start a container whose bind + // source doesn't exist. The meta repo is created by the + // startup migration, but make sure the directory is there + // before the manager comes up in case set_nspawn_flags fires + // first (e.g. cold start with no agents). + std::fs::create_dir_all(HOST_META_ROOT) + .with_context(|| format!("create {HOST_META_ROOT}"))?; // Manager edits sub-agent proposed/ repos and its own. RW so it can // git-commit. Sub-agents see only their own /run/hive socket and // /root/.claude (no /agents or /applied). @@ -617,7 +629,11 @@ fn set_nspawn_flags( // denied tags into its proposed clones and diff against // what's actually deployed. RO bind makes destructive git // plumbing inside the container unable to corrupt applied. - use std::fmt::Write as _; + // + // /meta is a third RO mount exposing the system-wide deploy + // flake (`git log /meta --oneline` shows every deploy across + // every agent; `cat /meta/flake.lock` resolves which sha each + // agent is pinned at right now). let _ = write!( binds, " --bind={HOST_AGENTS_ROOT}:{CONTAINER_MANAGER_AGENTS_MOUNT}", @@ -626,6 +642,11 @@ fn set_nspawn_flags( binds, " --bind-ro={HOST_APPLIED_ROOT}:{CONTAINER_MANAGER_APPLIED_MOUNT}", ); + let _ = write!( + binds, + " --bind-ro={HOST_META_ROOT}:{mount}", + mount = crate::meta::CONTAINER_MANAGER_META_MOUNT, + ); } let bind_flag = format!("EXTRA_NSPAWN_FLAGS=\"{binds}\""); let mut lines: Vec = original