feat(#589): swarm peers option + HYPERHIVE_PEERS env wire v0
nix: services.hyperhive.peers attrset-of-submodules option; serialises
to HYPERHIVE_PEERS JSON ([{label,domain}]); forwarded to containers via
FORWARDED_VARS. dashboard.rs: peer_hives: Vec<PeerHiveView> in
StateSnapshot, derived as {name:label, url:"http://domain/"}.
identity.rs: PeerHive struct + peers() accessor for agent-side use.
This commit is contained in:
parent
cce85a6c1b
commit
348fb3792a
4 changed files with 121 additions and 0 deletions
|
|
@ -266,6 +266,24 @@ struct StateSnapshot {
|
|||
/// var, set from `services.hyperhive.swarmName`. `None` when
|
||||
/// unset — chrome omits the swarm segment of the breadcrumb.
|
||||
swarm_name: Option<String>,
|
||||
/// Peer hives in the same swarm. Parsed from `HYPERHIVE_PEERS`
|
||||
/// (JSON array of `{label,domain}` objects, emitted by the c0re
|
||||
/// NixOS module from `services.hyperhive.peers`). Empty on
|
||||
/// single-hive deploys. Feeds iris's P33RS tab (#589). Each entry
|
||||
/// exposes `name` (the operator-chosen label) and `url` (dashboard
|
||||
/// link derived as `http://<domain>/`; v0 HTTP-only - HTTPS peers
|
||||
/// require gateway TLS (#593/#594)).
|
||||
peer_hives: Vec<PeerHiveView>,
|
||||
}
|
||||
|
||||
/// One peer hive for the P33RS dashboard tab. Derived from
|
||||
/// `HYPERHIVE_PEERS` env; `url` is the peer's dashboard root so the
|
||||
/// tab can render a clickable card without knowing the remote port.
|
||||
/// v0: always `http://` - HTTPS peers need gateway TLS (#593/#594).
|
||||
#[derive(Serialize)]
|
||||
struct PeerHiveView {
|
||||
name: String,
|
||||
url: String,
|
||||
}
|
||||
|
||||
/// `OpQuestion` + computed `question_refs` / `answer_refs`. Built
|
||||
|
|
@ -475,9 +493,36 @@ async fn api_state(headers: HeaderMap, State(state): State<AppState>) -> axum::J
|
|||
forge_public_url: std::env::var("HIVE_FORGE_PUBLIC_URL").ok().filter(|s| !s.is_empty()),
|
||||
hive_name: std::env::var("HYPERHIVE_HIVE_NAME").ok().filter(|s| !s.is_empty()),
|
||||
swarm_name: std::env::var("HYPERHIVE_SWARM_NAME").ok().filter(|s| !s.is_empty()),
|
||||
peer_hives: parse_peer_hives(),
|
||||
})
|
||||
}
|
||||
|
||||
/// Parse `HYPERHIVE_PEERS` env var into dashboard-ready `PeerHiveView`
|
||||
/// entries. The env var is a JSON array of `{label, domain}` objects
|
||||
/// emitted by the c0re NixOS module from `services.hyperhive.peers`.
|
||||
/// Each entry becomes `{ name: label, url: "http://domain/" }` for the
|
||||
/// P33RS tab. Returns empty vec when unset (single-hive deploy).
|
||||
fn parse_peer_hives() -> Vec<PeerHiveView> {
|
||||
#[derive(serde::Deserialize)]
|
||||
struct Raw {
|
||||
label: String,
|
||||
domain: String,
|
||||
}
|
||||
let Ok(json) = std::env::var("HYPERHIVE_PEERS") else {
|
||||
return Vec::new();
|
||||
};
|
||||
let Ok(raw): Result<Vec<Raw>, _> = serde_json::from_str(&json) else {
|
||||
tracing::warn!("HYPERHIVE_PEERS is not valid JSON; ignoring");
|
||||
return Vec::new();
|
||||
};
|
||||
raw.into_iter()
|
||||
.map(|r| PeerHiveView {
|
||||
name: r.label,
|
||||
url: format!("http://{}/", r.domain),
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Group live containers by their assigned web UI port; clusters with
|
||||
/// more than one member are port-hash collisions the operator needs
|
||||
/// to resolve by renaming. Manager (fixed at 8000) and sub-agents
|
||||
|
|
|
|||
|
|
@ -325,6 +325,8 @@ const CANONICAL_INPUTS: &[&str] = &["nixpkgs", "nixpkgs-unstable"];
|
|||
/// touching process-wide env).
|
||||
const FORWARDED_VARS: &[&str] = &[
|
||||
"HIVE_FORGE_URL",
|
||||
"HIVE_FORGE_PUBLIC_URL",
|
||||
"HYPERHIVE_PEERS",
|
||||
"HYPERHIVE_HIVE_DOMAIN",
|
||||
"HYPERHIVE_HIVE_NAME",
|
||||
"HYPERHIVE_SWARM_NAME",
|
||||
|
|
|
|||
Loading…
Reference in a new issue