gateway: hot-reload agents.conf at runtime (#869)
Replace eval-time per-agent nginx location baking with a runtime
include file. c0re writes /var/lib/hyperhive/agents.conf (nginx
location blocks, UDS or TCP per agent) on every topology change and
on the 10s marker poll. The gateway container bind-mounts
/var/lib/hyperhive/ at /run/hive-state/ and nginx includes
/run/hive-state/agents.conf. A systemd path unit inside the container
watches the file for changes and fires `nginx -s reload` on each
atomic rename from c0re — no nixos-rebuild switch needed when agents
start, stop, or flip useUnixSocket.
- new hive-c0re/src/gateway_nginx.rs: write() + render()
- lib.rs + meta.rs + agent_sockets::spawn_poll: hook in write()
- hive-gateway.nix: drop agentPortsTable/agentSocketsTable/
agentUpstreamFor/lib.mapAttrs', add /run/hive-state bind-mount,
include directive, systemd path unit + reload service, tmpfiles
for /var/lib/hyperhive + agents.conf seed
- docs/gateway.md: update vhost table + Per-agent UDS section
This commit is contained in:
parent
f1d2063a84
commit
07434e8f50
7 changed files with 337 additions and 173 deletions
|
|
@ -7,7 +7,7 @@ Single nginx in front of every hyperhive web surface. Container `hive-gateway`,
|
|||
| URL | vhost | upstream | source |
|
||||
| --- | --- | --- | --- |
|
||||
| `<hive>/` | `_` (catch-all) | hive-c0re dashboard (`7000`) | always |
|
||||
| `<hive>/agent/<name>/` | `_` | per-agent harness on `agent_web_port(name)` | `agentPortsFile` JSON |
|
||||
| `<hive>/agent/<name>/` | `_` | per-agent harness (UDS or TCP) | `agents.conf` (runtime-generated) |
|
||||
| `<hive>/.well-known/matrix/{client,server}` | `_` | inline JSON (no upstream) | `matrix.enable && domain != null` |
|
||||
| `<hive>/matrix/` (deprecated) | `_` | 301 → `matrix.<hive>/` | `matrix.gui.enable` |
|
||||
| `forge.<hive>/` | `forge.<hive>` | forgejo (`3000`) | `forge.behindGateway` |
|
||||
|
|
@ -89,21 +89,27 @@ unix-domain socket as each agent opts in. The mechanism:
|
|||
harness has actually bound the socket appear there. Without this
|
||||
filter, the gateway would `proxy_pass` to a non-existent socket
|
||||
for every sub-agent that hasn't opted in yet.
|
||||
4. **Gateway side**. Reads `agent-sockets.json` at request-handling
|
||||
time and routes `/agent/<name>/` to
|
||||
`http://unix:/run/hive-agent/<name>/web.sock:/`. Whole
|
||||
`/run/hive-agent/` is bind-mounted read-only into the gateway
|
||||
container so it can reach every published socket.
|
||||
4. **Gateway side**. `gateway_nginx::write` generates
|
||||
`/var/lib/hyperhive/agents.conf` — a plain nginx include file with
|
||||
one `location /agent/<name>/` block per agent. UDS upstream
|
||||
(`http://unix:/run/hive-agent/<name>/web.sock:/`) when `.bound`
|
||||
marker present; TCP loopback otherwise. The gateway container
|
||||
bind-mounts `/var/lib/hyperhive/` at `/run/hive-state/`; nginx
|
||||
includes `/run/hive-state/agents.conf`. A systemd path unit
|
||||
(`hive-gateway-agents-conf.path`) inside the container watches the
|
||||
file and fires `nginx -s reload` on every atomic rename from c0re
|
||||
— no `nixos-rebuild` needed (#869).
|
||||
|
||||
c0re re-fires `agent_sockets::write` every 10s so newly-bound
|
||||
markers get picked up without needing a container-start hook in
|
||||
every lifecycle path. `write()` is idempotent: steady-state cost is
|
||||
one stat per agent per tick.
|
||||
c0re regenerates `agents.conf` (and fires the path unit → reload) on
|
||||
two triggers: every topology change (new/removed agents) and every
|
||||
10s marker poll tick (`agent_sockets::spawn_poll`). `write()` is
|
||||
idempotent — skips the rename when content is unchanged so the path
|
||||
unit doesn't fire spuriously.
|
||||
|
||||
Transition: agents that haven't flipped `useUnixSocket = true` still
|
||||
appear in `agent-ports.json` (the legacy TCP map) and the gateway
|
||||
falls back to TCP for them. A future cleanup will drop the TCP map +
|
||||
the harness's TCP bind once every agent's flipped.
|
||||
Transition: agents that haven't flipped `useUnixSocket = true` get a
|
||||
TCP loopback upstream in `agents.conf` (deterministic port from
|
||||
`agent_web_port(name)`). A future cleanup will drop the TCP fallback
|
||||
once every agent's flipped.
|
||||
|
||||
## Dashboard link shape (gateway vs direct)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue