refactor(#2390): split provision out of the create node in the spawn dag

This commit is contained in:
damocles 2026-07-13 16:04:08 +02:00 committed by mara
commit 436adf6fd0
6 changed files with 79 additions and 35 deletions

View file

@ -81,7 +81,8 @@ pub(super) async fn run_node(coord: &Arc<Coordinator>, claim: &Claim) -> Result<
match &claim.kind {
NodeKind::Prebuild { relock } => run_prebuild(coord, claim, &ctx, *relock).await,
NodeKind::Swap => run_swap(coord, claim, &ctx).await,
NodeKind::Create => run_create(coord, claim, &ctx).await,
NodeKind::Provision => run_provision(coord, claim, &ctx).await,
NodeKind::Create => run_create(claim, &ctx).await,
NodeKind::MetaLock { sweep, fanout } => {
run_meta_lock(coord, claim, &ctx, *sweep, fanout.clone()).await
}
@ -191,23 +192,35 @@ async fn run_swap(coord: &Arc<Coordinator>, claim: &Claim, ctx: &Ctx<'_>) -> Res
result.map(|()| NodeOutput::default())
}
/// First-spawn provisioning + `nixos-container create` (atomic
/// build+create — no prebuild needed).
async fn run_create(coord: &Arc<Coordinator>, claim: &Claim, ctx: &Ctx<'_>) -> Result<NodeOutput> {
/// First-spawn pre-create provisioning: proposed/applied repos, state
/// subvolume, and the meta `sync_agents` registration. Holds the
/// deploy-window gate for the commit so it can't land inside another
/// node's staged deploy window — same discipline as `Prebuild`, which
/// commits under the gate then drops it before the (store-only) build.
async fn run_provision(
coord: &Arc<Coordinator>,
claim: &Claim,
ctx: &Ctx<'_>,
) -> Result<NodeOutput> {
let name = &claim.agent;
let agent_dir = crate::paths::agent_runtime_dir(name);
let hive = coord.hive_env();
let paths = Coordinator::agent_paths(name, agent_dir);
ctx.step("nixos-container create");
// create_container registers the new agent in the meta flake
// (sync_agents commit) before `nixos-container create` — hold the
// deploy-window gate so that commit can't land inside another
// node's staged deploy window.
// Runtime dir creation and MCP listener registration are deferred to
// the tail Reconcile (converge_start_preamble + register_agent) so this
// node stays purely "provision + create", not "create + start".
ctx.step("provisioning");
let _window = crate::meta::exclusive().await;
crate::lifecycle::create_container(name, &hive, &paths).await?;
crate::lifecycle::provision_container(name, &hive, &paths).await?;
Ok(NodeOutput::default())
}
/// `nixos-container create` proper — the upstream `Provision` node
/// already registered the agent in meta, so this only reads the store
/// (no deploy-window gate needed, mirroring `Prebuild`'s build). Runtime
/// dir creation and MCP listener registration are deferred to the tail
/// `Reconcile` (`converge_start_preamble` + `register_agent`) so this
/// node stays purely "create", not "create + start".
async fn run_create(claim: &Claim, ctx: &Ctx<'_>) -> Result<NodeOutput> {
ctx.step("nixos-container create");
crate::lifecycle::create_only(&claim.agent).await?;
Ok(NodeOutput::default())
}