fix(#3434): InitAgentConfigRepo does not need the hive name
Seeding a config repo is the same work whichever hive the agent is bound for, and an agent's config states nothing about where it runs -- so the node has no use for the address. It stays on the request, where it is parsed and checked against the roster, and reaches its consumer when the node that sends a deploy message exists. That leaves this endpoint validating a field it carries no further, which is the intended end state: the request shape is the breaking half, and settling it once is cheaper for every caller than doing it twice. `data()`'s two repo-and-agent arms now share a body. Merged rather than kept apart -- `label()` is what distinguishes the nodes to a viewer.
This commit is contained in:
parent
8b55a8b9fd
commit
f2790ab360
1 changed files with 20 additions and 31 deletions
|
|
@ -65,24 +65,12 @@ enum SwarmNodeKind {
|
|||
/// Seed `repo` with `agent.nix` + `flake.nix`. See
|
||||
/// `forge::Client::seed_agent_config`.
|
||||
///
|
||||
/// `hive` is the **address** this agent's creation was aimed at — the
|
||||
/// hive a deploy message gets sent to over the queue — and not a
|
||||
/// property of the agent. Seeding does not use it: it rides on the
|
||||
/// graph because that is the only thing carrying the operator's choice
|
||||
/// forward from the API boundary, where it was checked against the
|
||||
/// roster once. The node that routes on it is the deploy node in the
|
||||
/// deploy-coordination work; until that lands the field is carried and
|
||||
/// rendered, not acted on.
|
||||
///
|
||||
/// Carrying the validated value rather than re-reading the roster at
|
||||
/// node time is deliberate — the roster is loaded at startup, and a
|
||||
/// node that looked it up again would be answering a question the
|
||||
/// operator already answered.
|
||||
InitAgentConfigRepo {
|
||||
repo: String,
|
||||
agent: String,
|
||||
hive: String,
|
||||
},
|
||||
/// Deliberately carries no hive: seeding a config repo is the same
|
||||
/// work whichever hive the agent is bound for, and an agent's config
|
||||
/// states nothing about where it runs. The hive is an address the
|
||||
/// swarm routes a deploy message to — it belongs on the node that
|
||||
/// sends that message, not on this one.
|
||||
InitAgentConfigRepo { repo: String, agent: String },
|
||||
}
|
||||
|
||||
impl hive_jobq_wire::WireNode for SwarmNodeKind {
|
||||
|
|
@ -103,16 +91,13 @@ impl hive_jobq_wire::WireNode for SwarmNodeKind {
|
|||
SwarmNodeKind::CreateRepo { repo } => {
|
||||
serde_json::json!({ "repo": repo })
|
||||
}
|
||||
SwarmNodeKind::AddRepoMember { repo, agent } => {
|
||||
// Same rendering, and that is not a coincidence to be split
|
||||
// apart later: both nodes act on one repo for one agent, and
|
||||
// `label()` is what tells a viewer which of the two it is.
|
||||
SwarmNodeKind::AddRepoMember { repo, agent }
|
||||
| SwarmNodeKind::InitAgentConfigRepo { repo, agent } => {
|
||||
serde_json::json!({ "repo": repo, "agent": agent })
|
||||
}
|
||||
// Rendered with `hive` because it is the one place the graph
|
||||
// states where this creation was aimed — nothing persists it,
|
||||
// so a viewer watching the job is the only reader there is
|
||||
// until the deploy node routes on it.
|
||||
SwarmNodeKind::InitAgentConfigRepo { repo, agent, hive } => {
|
||||
serde_json::json!({ "repo": repo, "agent": agent, "hive": hive })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -191,10 +176,7 @@ async fn run_swarm_node(
|
|||
Err(e) => Outcome::Failed(format!("{e:#}")),
|
||||
},
|
||||
},
|
||||
// `hive` is deliberately not destructured: seeding writes no hive
|
||||
// into the agent's config, so this node carries the address without
|
||||
// consuming it. See the variant's doc.
|
||||
SwarmNodeKind::InitAgentConfigRepo { repo, agent, .. } => match deps.forge {
|
||||
SwarmNodeKind::InitAgentConfigRepo { repo, agent } => match deps.forge {
|
||||
None => Outcome::Failed(
|
||||
"no forge configured on this host (SWARM_CONTROLLER_FORGE_URL / \
|
||||
SWARM_CONTROLLER_FORGE_TOKEN_FILE unset)"
|
||||
|
|
@ -591,6 +573,13 @@ async fn get_hives_status(
|
|||
/// would have been the friendlier migration and would have left every
|
||||
/// creation in the state this endpoint exists to avoid — one nothing can
|
||||
/// address.
|
||||
///
|
||||
/// Validated here and carried no further: none of the nodes this endpoint
|
||||
/// queues talks to a hive, so none of them needs the address. It reaches
|
||||
/// its consumer when the node that *sends* a deploy message exists, and
|
||||
/// that node takes it from this field. Settling the request shape now is
|
||||
/// the point — it is the breaking half, and doing it once is cheaper for
|
||||
/// every caller than doing it again later.
|
||||
#[derive(Clone, Debug, Deserialize, ToSchema)]
|
||||
struct CreateAgentRequest {
|
||||
name: String,
|
||||
|
|
@ -701,7 +690,7 @@ async fn create_agent(
|
|||
})
|
||||
.after_ok(create_repo);
|
||||
let _init_config = b
|
||||
.node(SwarmNodeKind::InitAgentConfigRepo { repo, agent, hive })
|
||||
.node(SwarmNodeKind::InitAgentConfigRepo { repo, agent })
|
||||
.after_ok(create_repo);
|
||||
vec![create_identity.guid()]
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in a new issue