fix(#947): include manager in gateway agents.conf routing
This commit is contained in:
parent
aa96d76e73
commit
11d74e1e17
2 changed files with 13 additions and 12 deletions
|
|
@ -130,9 +130,11 @@ logical agent name → TCP web port:
|
||||||
|
|
||||||
Written alongside `agents.conf` on every topology change. Ports come from
|
Written alongside `agents.conf` on every topology change. Ports come from
|
||||||
`lifecycle::agent_web_port(name)` — a pure FNV-1a hash of the name,
|
`lifecycle::agent_web_port(name)` — a pure FNV-1a hash of the name,
|
||||||
reproducible from the name alone. The manager is excluded: the gateway
|
reproducible from the name alone. The manager is excluded: it always
|
||||||
routes `/` directly to c0re's dashboard upstream, not through a
|
uses a unix socket (`HIVE_WEB_SOCKET` is unconditionally set for the
|
||||||
per-agent `/agent/<name>/` prefix.
|
manager role), so its TCP port never appears in the fallback map.
|
||||||
|
The gateway routes `/agent/root/` to the manager's unix socket via
|
||||||
|
`agents.conf` alongside sub-agents.
|
||||||
|
|
||||||
The file doubles as a human-readable audit artifact — `cat agent-ports.json`
|
The file doubles as a human-readable audit artifact — `cat agent-ports.json`
|
||||||
shows every registered sub-agent and its deterministic port assignment. TCP
|
shows every registered sub-agent and its deterministic port assignment. TCP
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ use std::fmt::Write as _;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use crate::agent_sockets;
|
use crate::agent_sockets;
|
||||||
use crate::lifecycle::{self, MANAGER_NAME};
|
use crate::lifecycle;
|
||||||
|
|
||||||
const HOST_CONF_PATH: &str = "/var/lib/hyperhive/gateway/agents.conf";
|
const HOST_CONF_PATH: &str = "/var/lib/hyperhive/gateway/agents.conf";
|
||||||
|
|
||||||
|
|
@ -39,7 +39,8 @@ const PROXY_HEADER_BLOCK: &str = " proxy_http_version 1.1;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;";
|
proxy_set_header X-Forwarded-Proto $scheme;";
|
||||||
|
|
||||||
/// Render the nginx include body for `names`. Manager is filtered out.
|
/// Render the nginx include body for `names`. Manager is included so
|
||||||
|
/// `/agent/root/` is routable through the gateway.
|
||||||
///
|
///
|
||||||
/// When `frontend_dir` is `Some(path)` each agent gets split location
|
/// When `frontend_dir` is `Some(path)` each agent gets split location
|
||||||
/// blocks:
|
/// blocks:
|
||||||
|
|
@ -66,9 +67,6 @@ fn render(names: &[String], frontend_dir: Option<&str>) -> String {
|
||||||
\n# Gateway reloads nginx automatically on each update (systemd path unit).\n",
|
\n# Gateway reloads nginx automatically on each update (systemd path unit).\n",
|
||||||
);
|
);
|
||||||
for name in names {
|
for name in names {
|
||||||
if name == MANAGER_NAME {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let port = lifecycle::agent_web_port(name);
|
let port = lifecycle::agent_web_port(name);
|
||||||
let upstream = if agent_sockets::ready_marker_for(name).exists() {
|
let upstream = if agent_sockets::ready_marker_for(name).exists() {
|
||||||
format!(
|
format!(
|
||||||
|
|
@ -235,6 +233,7 @@ fn reload_gateway_nginx() {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::lifecycle::MANAGER_NAME;
|
||||||
|
|
||||||
// ── legacy mode (frontend_dir = None) ──────────────────────────────
|
// ── legacy mode (frontend_dir = None) ──────────────────────────────
|
||||||
|
|
||||||
|
|
@ -247,13 +246,13 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn render_filters_manager() {
|
fn render_includes_manager() {
|
||||||
let names: Vec<String> = [MANAGER_NAME, "iris"]
|
let names: Vec<String> = [MANAGER_NAME, "iris"]
|
||||||
.iter()
|
.iter()
|
||||||
.map(|s| (*s).to_owned())
|
.map(|s| (*s).to_owned())
|
||||||
.collect();
|
.collect();
|
||||||
let body = render(&names, None);
|
let body = render(&names, None);
|
||||||
assert!(!body.contains(&format!("/agent/{MANAGER_NAME}/")));
|
assert!(body.contains(&format!("/agent/{MANAGER_NAME}/")));
|
||||||
assert!(body.contains("/agent/iris/"));
|
assert!(body.contains("/agent/iris/"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -358,13 +357,13 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn split_mode_filters_manager() {
|
fn split_mode_includes_manager() {
|
||||||
let names: Vec<String> = [MANAGER_NAME, "iris"]
|
let names: Vec<String> = [MANAGER_NAME, "iris"]
|
||||||
.iter()
|
.iter()
|
||||||
.map(|s| (*s).to_owned())
|
.map(|s| (*s).to_owned())
|
||||||
.collect();
|
.collect();
|
||||||
let body = render(&names, Some(FAKE_FRONTEND));
|
let body = render(&names, Some(FAKE_FRONTEND));
|
||||||
assert!(!body.contains(&format!("/agent/{MANAGER_NAME}/")));
|
assert!(body.contains(&format!("/agent/{MANAGER_NAME}/")));
|
||||||
assert!(body.contains("/agent/iris/"));
|
assert!(body.contains("/agent/iris/"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue