Phase 6a: per-container web UI (axum); per-agent port hashed from name

This commit is contained in:
müde 2026-05-14 23:39:06 +02:00
parent 14cb107125
commit d0f954bbc1
9 changed files with 112 additions and 4 deletions

View file

@ -19,6 +19,24 @@ pub const CONTAINER_RUNTIME_MOUNT: &str = "/run/hive";
const GIT_NAME: &str = "hive-c0re";
const GIT_EMAIL: &str = "hive-c0re@hyperhive";
/// Sub-agent web UI port range. Deterministic from the agent's name (FNV-1a
/// hash mod range size), so the dashboard can compute the same port without
/// asking hive-c0re.
const WEB_PORT_BASE: u16 = 8100;
const WEB_PORT_RANGE: u16 = 900;
/// Returns the per-agent web UI port. Same hash on both sides — manager,
/// dashboard, and agent harness all agree.
#[must_use]
pub fn agent_web_port(name: &str) -> u16 {
let mut hash: u32 = 2_166_136_261;
for b in name.bytes() {
hash ^= u32::from(b);
hash = hash.wrapping_mul(16_777_619);
}
WEB_PORT_BASE + (hash % u32::from(WEB_PORT_RANGE)) as u16
}
pub fn container_name(name: &str) -> String {
format!("{AGENT_PREFIX}{name}")
}
@ -125,6 +143,7 @@ pub async fn setup_applied(applied_dir: &Path, name: &str, hyperhive_flake: &str
std::fs::create_dir_all(applied_dir)
.with_context(|| format!("create {}", applied_dir.display()))?;
let port = agent_web_port(name);
let flake_body = format!(
r#"{{
description = "hyperhive sub-agent {name}";
@ -143,6 +162,10 @@ pub async fn setup_applied(applied_dir: &Path, name: &str, hyperhive_flake: &str
[init]
defaultBranch = main
'';
systemd.services.hive-ag3nt.environment = {{
HIVE_PORT = "{port}";
HIVE_LABEL = "{name}";
}};
}}
];
}};