Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
09c1abe5b4 | ||
|
|
cb1a5cdbb8 |
1 changed files with 101 additions and 0 deletions
|
|
@ -8,6 +8,31 @@ let
|
||||||
cfg = config.services.hyperhive.gateway;
|
cfg = config.services.hyperhive.gateway;
|
||||||
hyperhiveDomain = config.services.hyperhive.domain;
|
hyperhiveDomain = config.services.hyperhive.domain;
|
||||||
matrixCfg = config.services.hyperhive.matrix;
|
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
|
in
|
||||||
{
|
{
|
||||||
# Single nginx in front of every hyperhive surface (#609 / #15 v0).
|
# Single nginx in front of every hyperhive surface (#609 / #15 v0).
|
||||||
|
|
@ -117,6 +142,42 @@ in
|
||||||
around. Requires `services.hyperhive.domain` to be set.
|
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 {
|
config = lib.mkIf cfg.enable {
|
||||||
|
|
@ -248,6 +309,46 @@ 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
|
# Everything else proxies to hive-c0re. Upgrade
|
||||||
# headers stay set so SSE (`/dashboard/stream`,
|
# headers stay set so SSE (`/dashboard/stream`,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue