feat(#2290): StartableAgent token — start_with_fallback requires preamble proof
- lifecycle::StartableAgent: opaque token produced only by converge_start_preamble. #[must_use] with a hint to call start_with_fallback(token). - lifecycle::converge_start_preamble(name, hive, paths): runs ensure_agent_runtime_dir + write_dropins, returns StartableAgent. The only way to obtain a token. - lifecycle::start_with_fallback(token: StartableAgent): public API now requires the token. Callers that skip the preamble get a compile error, not a runtime outage. - lifecycle::start_with_fallback_inner(name): private; used internally by rebuild_no_meta where the preamble is already enforced structurally (write_dropins was called on the line above). - exec.rs ReconcileAction::Start: migrated to converge_start_preamble + start_with_fallback(token). The write_dropins + start_with_fallback two-step is now a single typed pipeline.
This commit is contained in:
parent
15fc33d2e1
commit
950a13bc69
2 changed files with 56 additions and 19 deletions
|
|
@ -253,27 +253,20 @@ async fn run_reconcile(
|
|||
.transient
|
||||
.is_none()
|
||||
.then(|| coord.transient_guard(name, crate::coordinator::TransientKind::Starting));
|
||||
// Converge the ephemeral host-side state before the start:
|
||||
// `/run/hyperhive/agents/<name>` + `/run/hive-agent/<name>`
|
||||
// (both nspawn bind sources — tmpfs, empty after a host
|
||||
// reboot; nspawn refuses to start with a missing source)
|
||||
// and the resource-limits drop-in under
|
||||
// `/run/systemd/system/`. Rebuild DAGs get this from their
|
||||
// Prebuild/Swap nodes; the bare-Reconcile templates (boot
|
||||
// reconcile, plain start/restart) otherwise start with
|
||||
// nothing under /run and fail.
|
||||
//
|
||||
// Dir creation is the pure-filesystem part (no Coordinator
|
||||
// dep). The MCP listener is reconciled by mcp_sockets::spawn_poll
|
||||
// whose first tick fires immediately on daemon start — the
|
||||
// container boot takes longer than the 10 s interval anyway.
|
||||
crate::lifecycle::ensure_agent_runtime_dir(name)?;
|
||||
// Run the typed start preamble: ensures the runtime dir
|
||||
// exists and writes the nspawn/resource-limits drop-ins.
|
||||
// The returned StartableAgent token is the only way to call
|
||||
// start_with_fallback — omitting this becomes a compile error.
|
||||
// MCP listener registration is handled by mcp_sockets::spawn_poll
|
||||
// (first tick immediate); the container boot takes longer than
|
||||
// the 10 s interval so the listener is ready in time.
|
||||
let agent_dir = Coordinator::agent_dir(name);
|
||||
let hive = coord.hive_env();
|
||||
let paths = Coordinator::agent_paths(name, agent_dir);
|
||||
crate::lifecycle::write_dropins(name, &hive, &paths).await?;
|
||||
let token =
|
||||
crate::lifecycle::converge_start_preamble(name, &hive, &paths).await?;
|
||||
ctx.step("nixos-container start");
|
||||
crate::lifecycle::start_with_fallback(name).await?;
|
||||
crate::lifecycle::start_with_fallback(token).await?;
|
||||
coord.kick_agent(name, "container started");
|
||||
coord.rescan_containers_and_emit().await;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue