fix(#888): use gateway forge URL in dashboard links
Dashboard links to the forge were hardcoded as http://<hostname>:3000, which breaks when the operator accesses the dashboard through hive-gateway (forge is served at forge.<domain> with no port). - nix/modules/hive-c0re.nix: inject HIVE_FORGE_PUBLIC_URL when forge.behindGateway = true (e.g. http://forge.pr1ma.darkest.space) - hive-c0re/src/dashboard.rs: expose forge_url: Option<String> in StateSnapshot, reading from HIVE_FORGE_PUBLIC_URL - frontend/packages/dashboard/src/tabs.js: use state.forge_url when present; fall back to http://<hostname>:3000 for gateway-off / local-dev deploys
This commit is contained in:
parent
61b9c23613
commit
d3ca857659
5 changed files with 37 additions and 3 deletions
|
|
@ -1063,7 +1063,9 @@ window.marked = marked;
|
|||
const metaLinks = $('meta-links');
|
||||
if (metaLinks && Array.isArray(s.links)) {
|
||||
metaLinks.replaceChildren();
|
||||
const forgeBase = `http://${window.location.hostname}:3000`;
|
||||
// Prefer forge_public_url from state (set when the gateway serves
|
||||
// forge at its sub-domain); fall back to :3000 for local-dev.
|
||||
const forgeBase = s.forge_public_url || `http://${window.location.hostname}:3000`;
|
||||
s.links.forEach((lnk, i) => {
|
||||
const href = lnk.kind === 'forge' ? forgeBase + (lnk.url || '')
|
||||
: lnk.kind === 'external' ? (lnk.url || '')
|
||||
|
|
|
|||
|
|
@ -580,7 +580,11 @@ window.marked = marked;
|
|||
// and must never reach the HTML parser.
|
||||
const navStrip = el('span', { class: 'nav-strip' });
|
||||
head.append(navStrip);
|
||||
const forgeBase = `http://${hostname}:3000`;
|
||||
// Forge public URL: prefer state.forge_public_url (set by the NixOS
|
||||
// module when forge.behindGateway=true, e.g.
|
||||
// "https://forge.pr1ma.darkest.space"), fall back to
|
||||
// "<hostname>:3000" for gateway-off / local-dev deploys.
|
||||
const forgeBase = (s && s.forge_public_url) || `http://${hostname}:3000`;
|
||||
// Container nav-strip links resolve against the same base as the
|
||||
// primary `name` link — gateway-prefixed when the gateway is in
|
||||
// front, direct TCP otherwise. Strips the trailing slash so
|
||||
|
|
@ -1786,7 +1790,11 @@ window.marked = marked;
|
|||
// forge link base — only when the hive-forge container is up.
|
||||
const fs = window.__hyperhive_state;
|
||||
const hostname = (fs && fs.hostname) || window.location.hostname;
|
||||
const forgeBase = (fs && fs.forge_present) ? `http://${hostname}:3000` : null;
|
||||
// Prefer state.forge_public_url (set when forge.behindGateway=true,
|
||||
// e.g. "https://forge.pr1ma.darkest.space") over the direct :3000 port.
|
||||
const forgeBase = (fs && fs.forge_present)
|
||||
? (fs.forge_public_url || `http://${hostname}:3000`)
|
||||
: null;
|
||||
|
||||
const ul = el('ul', { class: 'approvals' });
|
||||
for (const a of pending) {
|
||||
|
|
|
|||
|
|
@ -436,6 +436,12 @@ struct StateSnapshot {
|
|||
/// this directly. See [`docs/web-ui/dashboard.md::Container row`] for the
|
||||
/// frontend resolver + which links appear in which conditions.
|
||||
links: Vec<AgentLink>,
|
||||
/// Public URL of the forge served by hive-gateway (e.g.
|
||||
/// `"https://forge.pr1ma.darkest.space"`). Sourced from
|
||||
/// `HIVE_FORGE_PUBLIC_URL`; `None` when `forge.behindGateway=false`
|
||||
/// or the env var is absent. The frontend uses this to build forge
|
||||
/// nav-strip links instead of hardcoding `<hostname>:3000`.
|
||||
forge_public_url: Option<String>,
|
||||
/// Human name of this hive instance (e.g. `"pr1ma"`). Sourced
|
||||
/// from `HYPERHIVE_HIVE_NAME`; `None` when unset. The frontend
|
||||
/// uses this for the page `<title>` and header label so browser
|
||||
|
|
@ -585,6 +591,7 @@ async fn api_state(State(state): State<AppState>) -> axum::Json<StateSnapshot> {
|
|||
ctx_usage,
|
||||
cost_usage,
|
||||
links: agent_links(&state.label, state.gui_vnc_port.is_some()),
|
||||
forge_public_url: std::env::var("HIVE_FORGE_PUBLIC_URL").ok().filter(|s| !s.is_empty()),
|
||||
hive_name: crate::identity::hive_name(),
|
||||
swarm_name: crate::identity::swarm_name(),
|
||||
})
|
||||
|
|
|
|||
|
|
@ -250,6 +250,12 @@ struct StateSnapshot {
|
|||
/// local-dev deploys keep working. See `docs/gateway.md::Vhost
|
||||
/// map`.
|
||||
gateway_enabled: bool,
|
||||
/// Public URL of the forge vhost served by hive-gateway (e.g.
|
||||
/// `"http://forge.pr1ma.darkest.space"`). Sourced from the
|
||||
/// `HIVE_FORGE_PUBLIC_URL` env var, which the c0re NixOS module
|
||||
/// sets when `forge.behindGateway = true`. `None` when absent —
|
||||
/// the frontend falls back to `http://<hostname>:3000`.
|
||||
forge_public_url: Option<String>,
|
||||
/// Human name of this single-host hive instance (e.g. `"pr1ma"`).
|
||||
/// Sourced from `HYPERHIVE_HIVE_NAME` env var, set by the c0re
|
||||
/// NixOS module from `services.hyperhive.hiveName`. `None` when
|
||||
|
|
@ -466,6 +472,7 @@ async fn api_state(headers: HeaderMap, State(state): State<AppState>) -> axum::J
|
|||
let s = v.to_string_lossy().to_ascii_lowercase();
|
||||
matches!(s.as_str(), "1" | "true" | "yes")
|
||||
}),
|
||||
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()),
|
||||
})
|
||||
|
|
|
|||
|
|
@ -299,6 +299,16 @@ in
|
|||
# When true the dashboard builds same-origin `/agent/<name>/`
|
||||
# links; when false it falls back to direct `<host>:<port>` TCP.
|
||||
HIVE_GATEWAY_ENABLED = "1";
|
||||
}
|
||||
// lib.optionalAttrs (config.services.hyperhive.forge.enable && config.services.hyperhive.forge.behindGateway) {
|
||||
# Public URL of the forge vhost served by hive-gateway. The
|
||||
# dashboard uses this to build browser-facing forge links
|
||||
# instead of hardcoding `<hostname>:3000`, which breaks when
|
||||
# the operator accesses the dashboard through the gateway
|
||||
# (forge sub-domain has no port; direct port URL would be
|
||||
# wrong). Absent when `behindGateway = false` — dashboard
|
||||
# falls back to `<hostname>:3000`.
|
||||
HIVE_FORGE_PUBLIC_URL = "https://${config.services.hyperhive.forge.domain}";
|
||||
};
|
||||
serviceConfig = {
|
||||
ExecStart = "${cfg.package}/bin/hive-c0re --socket /run/hyperhive/host.sock serve --hyperhive-flake ${cfg.hyperhiveFlake} --dashboard-port ${toString cfg.dashboardPort} --operator-pronouns ${lib.escapeShellArg cfg.operatorPronouns} --context-window-tokens ${lib.escapeShellArg (builtins.toJSON cfg.contextWindowTokens)}";
|
||||
|
|
|
|||
Loading…
Reference in a new issue