build agents only from internal/meta; delete the hive's local meta flake
The hive no longer renders, locks or commits a meta flake. A rebuild's MetaSync node picks the internal/meta commit and records it with the hyperhive and config pins it holds; Prebuild, Swap and Create build from it, and a head that does not pin the agent's current config fails the build naming the agent. hive-priv's meta_rev is required. Removed: meta.rs sync/lock/render, the manual-rebuild relock, the boot sweep's hyperhive bump (MetaLock), the update-meta-inputs form and its panel, MetaWindow, the hive's hyperhive_rev setting. Kept: agent_set::refresh holds what sync_agents also did (topology.json, the gateway's agent-socket map and nginx include), called from spawn, destroy, rebuild and the migration. The boot reconcile and the stale-start upgrade compare the agent's marker with the hyperhive pin of internal/meta; the dashboard's deployed chip reads the config marker a successful build writes.
This commit is contained in:
parent
cea4827918
commit
4aa11b3a94
64 changed files with 1042 additions and 3793 deletions
|
|
@ -101,13 +101,6 @@ impl std::str::FromStr for InfraContainer {
|
|||
}
|
||||
}
|
||||
|
||||
/// Host path of the meta flake a hive renders itself. The flake ref for agent
|
||||
/// `<name>` is `{META_DIR}#{name}`, derived by `hive-priv` — never passed over
|
||||
/// the wire. Must stay in sync with `hive-c0re::paths::meta_root()`
|
||||
/// (`STATE_ROOT + "/meta"`); the privsep boundary prevents importing across
|
||||
/// the crate.
|
||||
pub const META_DIR: &str = "/var/lib/hyperhive/meta";
|
||||
|
||||
/// Whether `rev` is a git commit id: 40 lowercase hex digits. The only part of
|
||||
/// the `internal/meta` flake ref that crosses the wire (`meta_rev` on
|
||||
/// `PrivRequest::UpdateContainer` and `CreateContainer`), so `hive-priv` checks
|
||||
|
|
@ -251,20 +244,18 @@ pub enum PrivRequest {
|
|||
KillContainer { name: String },
|
||||
|
||||
/// `nixos-container update <name> --flake <flake_ref>`
|
||||
/// The flake ref is derived from `name` by hive-priv: the hive's own meta
|
||||
/// flake, or `internal/meta` at `meta_rev` when that is set (the forge URL
|
||||
/// is hive-priv's own and never on the wire).
|
||||
/// The flake ref is derived from `name` and `meta_rev` by hive-priv: the
|
||||
/// swarm's `internal/meta` at that commit (the forge URL is hive-priv's
|
||||
/// own and never on the wire).
|
||||
/// When `stream` is `true`, hive-priv sends `PrivEvent::Line` messages
|
||||
/// as the process runs, then a terminal `PrivEvent::Done`.
|
||||
UpdateContainer {
|
||||
name: String,
|
||||
#[serde(default)]
|
||||
stream: bool,
|
||||
/// A commit of `internal/meta` to build from, checked by
|
||||
/// `valid_meta_rev`. `serde(default)` so a request from a hive-c0re
|
||||
/// that predates the field builds from the hive's own flake.
|
||||
#[serde(default)]
|
||||
meta_rev: Option<String>,
|
||||
/// The commit of `internal/meta` to build from, checked by
|
||||
/// `valid_meta_rev`.
|
||||
meta_rev: String,
|
||||
},
|
||||
|
||||
/// `nixos-container create <name> --flake <flake_ref>`
|
||||
|
|
@ -276,8 +267,7 @@ pub enum PrivRequest {
|
|||
name: String,
|
||||
#[serde(default)]
|
||||
stream: bool,
|
||||
#[serde(default)]
|
||||
meta_rev: Option<String>,
|
||||
meta_rev: String,
|
||||
},
|
||||
|
||||
/// `nixos-container destroy <name>`
|
||||
|
|
@ -746,29 +736,20 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
/// A hive-c0re that predates `meta_rev` sends neither field.
|
||||
/// `meta_rev` is required: there is no local flake to fall back to.
|
||||
#[test]
|
||||
fn a_request_without_meta_rev_builds_from_the_hives_own_flake() {
|
||||
fn a_request_without_meta_rev_is_refused() {
|
||||
for op in ["update_container", "create_container"] {
|
||||
let req: PrivRequest =
|
||||
serde_json::from_str(&format!(r#"{{"op":"{op}","name":"atlas"}}"#)).unwrap();
|
||||
match req {
|
||||
PrivRequest::UpdateContainer { meta_rev, .. }
|
||||
| PrivRequest::CreateContainer { meta_rev, .. } => assert_eq!(meta_rev, None),
|
||||
other => panic!("{other:?}"),
|
||||
}
|
||||
let without = format!(r#"{{"op":"{op}","name":"atlas"}}"#);
|
||||
assert!(
|
||||
serde_json::from_str::<PrivRequest>(&without).is_err(),
|
||||
"{op}"
|
||||
);
|
||||
let with = format!(
|
||||
r#"{{"op":"{op}","name":"atlas","meta_rev":"{}"}}"#,
|
||||
"b".repeat(40)
|
||||
);
|
||||
assert!(serde_json::from_str::<PrivRequest>(&with).is_ok(), "{op}");
|
||||
}
|
||||
let with: PrivRequest = serde_json::from_str(&format!(
|
||||
r#"{{"op":"update_container","name":"atlas","meta_rev":"{}"}}"#,
|
||||
"b".repeat(40)
|
||||
))
|
||||
.unwrap();
|
||||
assert!(matches!(
|
||||
with,
|
||||
PrivRequest::UpdateContainer {
|
||||
meta_rev: Some(_),
|
||||
..
|
||||
}
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue