diff --git a/hive-c0re/src/lifecycle.rs b/hive-c0re/src/lifecycle.rs index ddb1e6a..1a0a3d6 100644 --- a/hive-c0re/src/lifecycle.rs +++ b/hive-c0re/src/lifecycle.rs @@ -325,26 +325,34 @@ async fn systemd_daemon_reload() -> Result<()> { Ok(()) } -/// Idempotently rewrite the `EXTRA_NSPAWN_FLAGS` line in -/// `/etc/nixos-containers/.conf`. The start script expands this -/// variable unquoted into the `systemd-nspawn` command. +/// Idempotently rewrite the lines in `/etc/nixos-containers/.conf` +/// that hive-c0re owns: `PRIVATE_NETWORK` (forced 0 so the agent's web UI port +/// is reachable on the host) and `EXTRA_NSPAWN_FLAGS` (the runtime-dir bind). +/// The start script expands `$EXTRA_NSPAWN_FLAGS` unquoted into the +/// `systemd-nspawn` command. fn set_nspawn_flags(container: &str, agent_dir: &Path) -> Result<()> { let path = format!("/etc/nixos-containers/{container}.conf"); let original = std::fs::read_to_string(&path).with_context(|| format!("read {path}"))?; - let flag = format!( + let bind_flag = format!( "EXTRA_NSPAWN_FLAGS=\"--bind={}:{CONTAINER_RUNTIME_MOUNT}\"", agent_dir.display() ); let mut lines: Vec = original .lines() - .filter(|line| !line.trim_start().starts_with("EXTRA_NSPAWN_FLAGS=")) + .filter(|line| { + let trimmed = line.trim_start(); + !trimmed.starts_with("EXTRA_NSPAWN_FLAGS=") + && !trimmed.starts_with("PRIVATE_NETWORK=") + }) .map(str::to_owned) .collect(); - lines.push(flag); + // Share host netns so per-agent web UI ports are reachable directly. + lines.push("PRIVATE_NETWORK=0".to_owned()); + lines.push(bind_flag); let mut content = lines.join("\n"); content.push('\n'); std::fs::write(&path, content).with_context(|| format!("write {path}"))?; - tracing::info!(%path, "set EXTRA_NSPAWN_FLAGS"); + tracing::info!(%path, "set PRIVATE_NETWORK=0 + EXTRA_NSPAWN_FLAGS"); Ok(()) }