swarm: carry the agent queue credential from the host into the harness
hive-c0re stats the two files `swarm-bao-queue-agent` lands and forwards them into every agent container as systemd credentials, and the harness resolves a `QueueConfig` out of them at boot. Nothing connects yet. A credential and not a bind mount, and the mode is what forces it: the secret is root:0600 and the harness runs as the unprivileged agent user, so a bind would deliver a file that user cannot open. nspawn's `--load-credential` is read by the container manager as root and re-exposed under the consuming unit's own `User=`. hive-c0re never reads the bytes either way, which is just as well — it runs as `hive-core`. Absent files stay legal and become visible rather than silent: the publisher lives on the authelia host and mints on its first boot, so "nothing at that path" is the ordinary early state of a swarm. c0re forwards nothing and logs why; the harness logs that it has no queue. The client id comes out of the delivered file rather than being rebuilt from `hiveName` in nix, which is the agreement `swarm-secret-client` states. `QueueConfig::from_env` wants it as a value, so the harness reads the file itself — assigning the variable instead would need `std::env::set_var` in a process that has already spawned threads. Refs #3805
This commit is contained in:
parent
f8dd737456
commit
353cdd9264
6 changed files with 436 additions and 7 deletions
|
|
@ -700,6 +700,12 @@ const CANONICAL_INPUTS: &[&str] = &["nixpkgs"];
|
|||
/// trivial to stub from tests (which build their own slice instead of
|
||||
/// touching process-wide env).
|
||||
const FORWARDED_VARS: &[&str] = &[
|
||||
// Where the swarm queue is and where its tokens are minted, as an agent
|
||||
// container reaches them. Both are addresses the *host* computes — the
|
||||
// queue's from the bridge IP an agent routes over, never a loopback
|
||||
// address, which inside a container is the agent itself.
|
||||
"HIVE_AGENT_NATS_URL",
|
||||
"HIVE_AGENT_OIDC_TOKEN_ENDPOINT",
|
||||
"HIVE_FORGE_URL",
|
||||
"HIVE_FORGE_PUBLIC_URL",
|
||||
"HIVE_MATRIX_URL",
|
||||
|
|
@ -724,6 +730,16 @@ const FORWARDED_VARS: &[&str] = &[
|
|||
/// answer. Half-wiring this map is not a missing nicety; it is a value that
|
||||
/// evaluates fine and is silently wrong.
|
||||
const FORWARDED_VAR_OPTIONS: &[(&str, &str)] = &[
|
||||
// Read at build time to decide whether the harness unit declares the
|
||||
// queue credential at all — see `nix/agent-modules/queue.nix`. An agent
|
||||
// whose option says no queue and whose env says otherwise logs the
|
||||
// partial-config error rather than half-connecting, which is the same
|
||||
// failure this map's doc describes and the reason both halves are wired.
|
||||
("HIVE_AGENT_NATS_URL", "hyperhive.queue.natsUrl"),
|
||||
(
|
||||
"HIVE_AGENT_OIDC_TOKEN_ENDPOINT",
|
||||
"hyperhive.queue.tokenEndpoint",
|
||||
),
|
||||
("HIVE_FORGE_URL", "hyperhive.forge.url"),
|
||||
("HIVE_MATRIX_URL", "hyperhive.matrix.url"),
|
||||
("HYPERHIVE_HIVE_NAME", "hyperhive.hiveName"),
|
||||
|
|
@ -2027,6 +2043,37 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
/// The queue coordinates travel as a pair and are wired through both
|
||||
/// halves of the forwarded-var machinery: the env var the harness reads at
|
||||
/// runtime and the option the harness *unit* is built from. An agent that
|
||||
/// got only the env var would declare no credential and then report a
|
||||
/// partial config — visible, but a rebuild away from working.
|
||||
#[test]
|
||||
fn queue_coordinates_are_forwarded_as_both_env_and_option() {
|
||||
for var in ["HIVE_AGENT_NATS_URL", "HIVE_AGENT_OIDC_TOKEN_ENDPOINT"] {
|
||||
assert!(
|
||||
FORWARDED_VARS.contains(&var),
|
||||
"{var} must be forwarded into every agent's env"
|
||||
);
|
||||
}
|
||||
let mut out = String::new();
|
||||
push_forwarded_var_options(
|
||||
&mut out,
|
||||
&[
|
||||
("HIVE_AGENT_NATS_URL", "nats://10.42.0.1:4222".to_string()),
|
||||
(
|
||||
"HIVE_AGENT_OIDC_TOKEN_ENDPOINT",
|
||||
"https://auth.t.local/api/oidc/token".to_string(),
|
||||
),
|
||||
],
|
||||
);
|
||||
assert_eq!(
|
||||
out,
|
||||
" hyperhive.queue.natsUrl = \"nats://10.42.0.1:4222\";\n\
|
||||
\x20 hyperhive.queue.tokenEndpoint = \"https://auth.t.local/api/oidc/token\";\n"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn require_service_urls_accepts_a_rendered_forge_url() {
|
||||
require_service_urls(&[
|
||||
|
|
|
|||
Loading…
Reference in a new issue