remove the hive's local build of agent closures
A rebuild or create downloads the closure the swarm built and applies it; with none to deploy it fails and changes nothing. hive-priv takes a store path instead of an internal/meta commit and builds nothing.
This commit is contained in:
parent
70538fb209
commit
4590b04cac
1 changed files with 632 additions and 1351 deletions
|
|
@ -101,10 +101,7 @@ impl std::str::FromStr for InfraContainer {
|
|||
}
|
||||
}
|
||||
|
||||
/// 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
|
||||
/// it before it builds a ref.
|
||||
/// Whether `rev` is a git commit id: 40 lowercase hex digits.
|
||||
#[must_use]
|
||||
pub fn valid_meta_rev(rev: &str) -> bool {
|
||||
rev.len() == 40 && rev.bytes().all(|b| matches!(b, b'0'..=b'9' | b'a'..=b'f'))
|
||||
|
|
@ -113,7 +110,8 @@ pub fn valid_meta_rev(rev: &str) -> bool {
|
|||
/// Whether `path` is a store path in the shape nix prints one: `/nix/store/`,
|
||||
/// 32 lowercase letters or digits, `-`, then a name of the characters store
|
||||
/// names allow. The path crosses the wire in [`PrivRequest::RealiseClosure`],
|
||||
/// so `hive-priv` checks it before it hands it to nix.
|
||||
/// [`PrivRequest::UpdateContainer`] and [`PrivRequest::CreateContainer`], so
|
||||
/// `hive-priv` checks it before it hands it to nix.
|
||||
#[must_use]
|
||||
pub fn valid_closure_path(path: &str) -> bool {
|
||||
let Some(rest) = path.strip_prefix("/nix/store/") else {
|
||||
|
|
@ -137,20 +135,6 @@ pub fn valid_closure_path(path: &str) -> bool {
|
|||
/// cache that is down.
|
||||
pub const SIGNATURE_REFUSED: &str = "no signature by the swarm cache's key";
|
||||
|
||||
/// The flake the swarm publishes at `internal/meta`, at `rev`:
|
||||
/// `git+<forge_base>/internal/meta.git?rev=<rev>`. `forge_base` is the forge's
|
||||
/// `http` origin, which the hive's git credential helper answers for.
|
||||
///
|
||||
/// One definition for `hive-c0re`'s prebuild and `hive-priv`'s build, so both
|
||||
/// name the same flake.
|
||||
#[must_use]
|
||||
pub fn meta_flake_url(forge_base: &str, rev: &str) -> String {
|
||||
format!(
|
||||
"git+{}/internal/meta.git?rev={rev}",
|
||||
forge_base.trim_end_matches('/')
|
||||
)
|
||||
}
|
||||
|
||||
/// Root of per-agent state directories on the host.
|
||||
/// Subdirectory layout: `<AGENT_STATE_ROOT>/<name>/state/<file>`.
|
||||
/// Used by `WriteAgentStateFile` to derive the write path so the
|
||||
|
|
@ -278,31 +262,28 @@ pub enum PrivRequest {
|
|||
/// in the container. nixos-container has no kill verb.
|
||||
KillContainer { name: String },
|
||||
|
||||
/// `nixos-container update <name> --flake <flake_ref>`
|
||||
/// 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).
|
||||
/// Point `name`'s container profile at `toplevel`, then reload the unit if
|
||||
/// it runs. hive-priv never builds: `toplevel` is a closure already in the
|
||||
/// store (see `RealiseClosure`).
|
||||
/// 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,
|
||||
/// The commit of `internal/meta` to build from, checked by
|
||||
/// `valid_meta_rev`.
|
||||
meta_rev: String,
|
||||
/// The agent's system closure, checked by `valid_closure_path`.
|
||||
toplevel: String,
|
||||
},
|
||||
|
||||
/// `nixos-container create <name> --flake <flake_ref>`
|
||||
/// The flake ref is derived from `name` (and `meta_rev`) as for
|
||||
/// `UpdateContainer`.
|
||||
/// `nixos-container create <name> --system-path <toplevel>`
|
||||
/// `toplevel` is as for `UpdateContainer`.
|
||||
/// When `stream` is `true`, hive-priv sends `PrivEvent::Line` messages
|
||||
/// as the process runs, then a terminal `PrivEvent::Done`.
|
||||
CreateContainer {
|
||||
name: String,
|
||||
#[serde(default)]
|
||||
stream: bool,
|
||||
meta_rev: String,
|
||||
toplevel: String,
|
||||
},
|
||||
|
||||
/// `nix-store --realise <store_path>` from the swarm's binary cache, never
|
||||
|
|
@ -718,7 +699,7 @@ pub enum PrivEvent {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{InfraContainer, PrivRequest, meta_flake_url, valid_closure_path, valid_meta_rev};
|
||||
use super::{InfraContainer, PrivRequest, valid_closure_path, valid_meta_rev};
|
||||
|
||||
#[test]
|
||||
fn infra_control_names_no_c0re_or_swarm_service() {
|
||||
|
|
@ -765,15 +746,6 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_meta_flake_url_names_internal_meta_at_the_rev() {
|
||||
let rev = "a".repeat(40);
|
||||
assert_eq!(
|
||||
meta_flake_url("http://forge.t.local/", &rev),
|
||||
format!("git+http://forge.t.local/internal/meta.git?rev={rev}")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn only_a_store_path_is_a_closure_path() {
|
||||
let hash = "0123456789abcdfghijklmnpqrsvwxyz";
|
||||
|
|
@ -814,9 +786,9 @@ mod tests {
|
|||
assert!(serde_json::from_str::<PrivRequest>(without).is_err());
|
||||
}
|
||||
|
||||
/// `meta_rev` is required: there is no local flake to fall back to.
|
||||
/// `toplevel` is required: hive-priv has no flake to build one from.
|
||||
#[test]
|
||||
fn a_request_without_meta_rev_is_refused() {
|
||||
fn a_request_without_a_toplevel_is_refused() {
|
||||
for op in ["update_container", "create_container"] {
|
||||
let without = format!(r#"{{"op":"{op}","name":"atlas"}}"#);
|
||||
assert!(
|
||||
|
|
@ -824,8 +796,8 @@ mod tests {
|
|||
"{op}"
|
||||
);
|
||||
let with = format!(
|
||||
r#"{{"op":"{op}","name":"atlas","meta_rev":"{}"}}"#,
|
||||
"b".repeat(40)
|
||||
r#"{{"op":"{op}","name":"atlas","toplevel":"/nix/store/{}-nixos-system-atlas"}}"#,
|
||||
"b".repeat(32)
|
||||
);
|
||||
assert!(serde_json::from_str::<PrivRequest>(&with).is_ok(), "{op}");
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue