Compare commits

..

View file

@ -8,31 +8,6 @@ let
cfg = config.services.hyperhive.gateway;
hyperhiveDomain = config.services.hyperhive.domain;
matrixCfg = config.services.hyperhive.matrix;
# Per-agent port table for `/agent/<name>/` routing (#15 v0). Single-
# sourced from `cfg.agentPortsFile` (default
# `/var/lib/hyperhive/agent-ports.json`), written by hive-c0re on every
# topology change in shape `{ "<name>": <port>, ... }`.
#
# Read at deploy time via `builtins.fromJSON (builtins.readFile ...)`
# — pure eval (the file lives outside the nix store; nix copies the
# content into the store as a fixed-output dep). When the file is
# missing (fresh install before c0re has had a chance to write it),
# default to an empty map → no per-agent routes generated → gateway
# falls back to its pre-#15 shape. The container rebuilds on every
# `hivectl gateway-sync` (operator-initiated) or on the next
# `nixos-rebuild switch`, picking up whatever c0re has written
# since the last build.
#
# mara on #740 (comment 9295) + #15 (comment 9270): the gateway
# nginx container lives in system config (not meta), so it can't
# auto-rebuild from meta-flake events — the JSON file is what
# bridges the host's nix eval to the agent-lifecycle data c0re owns.
agentPortsTable =
if cfg.agentPortsFile == null || !builtins.pathExists cfg.agentPortsFile then
{ }
else
builtins.fromJSON (builtins.readFile cfg.agentPortsFile);
in
{
# Single nginx in front of every hyperhive surface (#609 / #15 v0).
@ -142,42 +117,6 @@ in
around. Requires `services.hyperhive.domain` to be set.
'';
};
agentPortsFile = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = "/var/lib/hyperhive/agent-ports.json";
example = "/var/lib/hyperhive/agent-ports.json";
description = ''
Path to a JSON file mapping sub-agent names to their web ports
for `/agent/<name>/` routing through the gateway (#15 v0).
Shape: `{ "<name>": <port>, ... }`. Written by hive-c0re on
every topology change (the rust side knows the canonical port
allocation via `lifecycle::agent_web_port`; the gateway just
reads what it's told).
For each `<name>: <port>` entry, the gateway adds a
`location /agent/<name>/` block that `proxy_pass`es to
`http://127.0.0.1:<port>/`. Empty / missing file no
per-agent routes generated gateway falls back to its pre-#15
shape (just `/` + matrix surfaces).
**Purely additive**: the old `http://<host>:<port>/` direct
reach keeps working in parallel; this just gives the operator
a single-origin route. Manager isn't included in the map (no
per-agent prefix needed; manager already gets the `/` route
via the c0re upstream block).
Set to `null` to disable per-agent routing entirely without
creating the file. Set to a custom path if the operator's c0re
writes the table elsewhere.
**Rebuild trigger**: the gateway container picks up new entries
on the next `nixos-rebuild switch` (or `hivectl gateway-sync`
if that helper lands). c0re writes are not auto-applied to a
running gateway see the follow-up in #15 for runtime nginx
include + reload + eventual per-agent unix sockets.
'';
};
};
config = lib.mkIf cfg.enable {
@ -309,46 +248,6 @@ in
'';
};
}
//
# Per-agent UIs (#15 v0). One `/agent/<name>/`
# block per `<name>: <port>` entry in
# `agentPortsTable` (loaded from `cfg.agentPortsFile`
# — `/var/lib/hyperhive/agent-ports.json` by default,
# written by hive-c0re on every topology change).
#
# Trailing-slash pair (`/agent/<name>/` + `proxy_pass
# http://...:<port>/`) strips the `/agent/<name>`
# prefix on the upstream side, so the agent server
# receives `GET /` for the SPA root, `GET /api/state`
# for the API, `GET /screen/ws` for the websocket, etc.
# The agent's emitted asset URLs are document-relative
# (iris's #731) so they round-trip back through the
# gateway under the same prefix without the harness
# needing prefix-awareness.
#
# `X-Forwarded-Prefix` set so the harness can build
# correct absolute URLs for any case where relative
# isn't enough (server-emitted redirects, OG meta
# tags, etc.).
#
# SSE / websocket support via `proxyWebsockets = true`
# (same as the c0re `/` block below).
#
# Empty / missing `cfg.agentPortsFile` → empty table
# → no per-agent blocks; old `<host>:<port>/` direct
# reach still works.
lib.mapAttrs' (name: port: {
name = "/agent/${name}/";
value = {
proxyPass = "http://127.0.0.1:${toString port}/";
proxyWebsockets = true;
extraConfig = ''
proxy_set_header X-Forwarded-Prefix /agent/${name};
proxy_buffering off;
proxy_read_timeout 1d;
'';
};
}) agentPortsTable
// {
# Everything else proxies to hive-c0re. Upgrade
# headers stay set so SSE (`/dashboard/stream`,