add per-agent url to host.sock agent status rows
This commit is contained in:
parent
29c94ea9e6
commit
4fae3f13cb
2 changed files with 53 additions and 1 deletions
|
|
@ -109,9 +109,11 @@ impl From<ContainerView> for hive_sh4re::container::AgentStatusRow {
|
||||||
/// syntactically, just always empty, until iris's frontend follow-up
|
/// syntactically, just always empty, until iris's frontend follow-up
|
||||||
/// decides whether to drop the column entirely. `port`, `cpu_quota`,
|
/// decides whether to drop the column entirely. `port`, `cpu_quota`,
|
||||||
/// `memory_max` have no equivalent on the row at all and are simply
|
/// `memory_max` have no equivalent on the row at all and are simply
|
||||||
/// not carried over.
|
/// not carried over. `url` has no source on `ContainerView` at all —
|
||||||
|
/// see [`agent_url`].
|
||||||
fn from(v: ContainerView) -> Self {
|
fn from(v: ContainerView) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
url: agent_url(&v.name),
|
||||||
name: v.name,
|
name: v.name,
|
||||||
running: v.running,
|
running: v.running,
|
||||||
failed: v.failed,
|
failed: v.failed,
|
||||||
|
|
@ -128,6 +130,30 @@ impl From<ContainerView> for hive_sh4re::container::AgentStatusRow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This agent's own web UI, behind the gateway. `None` when the hive's
|
||||||
|
/// domain isn't configured — same env var, same "empty string counts as
|
||||||
|
/// unset" filter `server.rs::hive_urls()` uses for `HiveUrls::home`, kept
|
||||||
|
/// in sync with it by reading the one env var directly rather than
|
||||||
|
/// threading a resolved domain through `HiveEnv` for a value nothing else
|
||||||
|
/// needs pre-resolved.
|
||||||
|
fn agent_url(name: &str) -> Option<String> {
|
||||||
|
let domain = std::env::var("HYPERHIVE_HIVE_DOMAIN")
|
||||||
|
.ok()
|
||||||
|
.filter(|v| !v.is_empty())?;
|
||||||
|
Some(agent_url_for_domain(&domain, name))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The pure half of [`agent_url`], split out so the path-scheme formatting
|
||||||
|
/// is testable without an env var in the loop. `/agent/<name>/` is the
|
||||||
|
/// gateway's real path scheme
|
||||||
|
/// (`nix/host-modules/hive-gateway/vhosts.nix`'s per-agent `agentLocations`
|
||||||
|
/// block) — computed once here so a client (trollshell's sidebar, the
|
||||||
|
/// dashboard) never has to derive it and silently drift if that scheme
|
||||||
|
/// ever changes.
|
||||||
|
fn agent_url_for_domain(domain: &str, name: &str) -> String {
|
||||||
|
format!("https://{domain}/agent/{name}/")
|
||||||
|
}
|
||||||
|
|
||||||
/// Build the full container list. Wraps `lifecycle::list()` and
|
/// Build the full container list. Wraps `lifecycle::list()` and
|
||||||
/// resolves every per-agent attribute the dashboard surfaces.
|
/// resolves every per-agent attribute the dashboard surfaces.
|
||||||
///
|
///
|
||||||
|
|
@ -548,5 +574,21 @@ mod tests {
|
||||||
// No source for reminders on this side (see the `From` impl's doc
|
// No source for reminders on this side (see the `From` impl's doc
|
||||||
// comment) — always the stub, never left uninitialised.
|
// comment) — always the stub, never left uninitialised.
|
||||||
assert_eq!(row.pending_reminders, 0);
|
assert_eq!(row.pending_reminders, 0);
|
||||||
|
// `url` depends on process-global env (`HYPERHIVE_HIVE_DOMAIN`), so
|
||||||
|
// it isn't asserted here — mutating env vars in a test race with
|
||||||
|
// every other test in this binary. `agent_url_for_domain` below
|
||||||
|
// covers the actual path-formatting logic without touching env.
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The pure half of the per-agent URL: given a domain, is the path
|
||||||
|
/// exactly `/agent/<name>/`? (`agent_url` itself, the thin env-reading
|
||||||
|
/// wrapper, is intentionally untested — see the note on the test
|
||||||
|
/// above.)
|
||||||
|
#[test]
|
||||||
|
fn agent_url_for_domain_uses_the_gateways_real_path_scheme() {
|
||||||
|
assert_eq!(
|
||||||
|
super::agent_url_for_domain("hive.example.com", "alice"),
|
||||||
|
"https://hive.example.com/agent/alice/"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,16 @@ pub struct AgentStatusRow {
|
||||||
/// `None`.
|
/// `None`.
|
||||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
pub status_set_at: Option<DateTime<Utc>>,
|
pub status_set_at: Option<DateTime<Utc>>,
|
||||||
|
/// This agent's own web UI, behind the gateway
|
||||||
|
/// (`https://<hive-domain>/agent/<name>/`) — the same URL the operator
|
||||||
|
/// dashboard's "open" action uses. `None` when the hive's domain isn't
|
||||||
|
/// configured (`HYPERHIVE_HIVE_DOMAIN` unset), same condition
|
||||||
|
/// `HostRequest::Urls`'s `HiveUrls::home` is `None` under. Present here
|
||||||
|
/// (not just derivable from `HiveUrls`) so a client never has to build
|
||||||
|
/// this path itself — see `hive-c0re/container_view.rs`'s `agent_url`
|
||||||
|
/// for why a client deriving it is the wrong shape to depend on.
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
pub url: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// One matrix identity an agent can act as, surfaced in `GetAgentMeta`'s
|
/// One matrix identity an agent can act as, surfaced in `GetAgentMeta`'s
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue