From e56fc97be8cedc6378eb950001cd3b51a564e6a4 Mon Sep 17 00:00:00 2001 From: atlas Date: Sun, 30 Aug 2026 03:52:55 +0200 Subject: [PATCH] hive-priv, hive-c0re: link docs/network.md instead of restating it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The network-isolation doc comments carried prose docs/network.md already owns, and three of them named `harness-base.nix` — a file that does not exist. The `hyperhive-isolated-dns` oneshot lives in nix/agent-modules/network.nix, which the doc gets right. That is #3749's argument reproducing itself: the same fact written in two places goes stale in the copy nobody reads. Linking removes the class, not just the instance — a link cannot name a nonexistent file without the doc noticing first. Trap and measurement comments stay put, per the issue's scope: the load-bearing HOST_ADDRESS default-route note, the unquoted $EXTRA_NSPAWN_FLAGS expansion, and the "isolation is the only mode" invariants are facts about this code, not about the subsystem. --- hive-c0re/src/lifecycle/host_config.rs | 12 ++++++------ hive-priv-sock/src/lib.rs | 10 ++++------ hive-priv/src/main.rs | 23 ++++++++++------------- 3 files changed, 20 insertions(+), 25 deletions(-) diff --git a/hive-c0re/src/lifecycle/host_config.rs b/hive-c0re/src/lifecycle/host_config.rs index 4768d493..2c9e2487 100644 --- a/hive-c0re/src/lifecycle/host_config.rs +++ b/hive-c0re/src/lifecycle/host_config.rs @@ -131,12 +131,12 @@ fn bind_child_agent_dirs(child: &str, binds: &mut Vec) { } /// Idempotently rewrite the lines in `/etc/nixos-containers/.conf` -/// that hive-c0re owns: `PRIVATE_NETWORK` (always 1 — every container runs in -/// its own network namespace with a veth on the host bridge, and the agent's -/// web UI is reached over that bridge rather than a host-shared netns), -/// `HOST_ADDRESS` (the bridge gateway IP, so the container installs a default -/// route before DHCP completes) and `EXTRA_NSPAWN_FLAGS` (the runtime-dir -/// bind). The start script expands `$EXTRA_NSPAWN_FLAGS` unquoted into the +/// that hive-c0re owns: `PRIVATE_NETWORK` (always 1), `HOST_ADDRESS` (the +/// bridge gateway IP) and `EXTRA_NSPAWN_FLAGS` (the runtime-dir bind). What +/// those network vars mean and why isolation is unconditional: +/// `docs/network.md` § *What the Rust side does*. +/// +/// ⚠️ The start script expands `$EXTRA_NSPAWN_FLAGS` unquoted into the /// `systemd-nspawn` command. #[allow( clippy::too_many_lines, diff --git a/hive-priv-sock/src/lib.rs b/hive-priv-sock/src/lib.rs index 74364e30..0aaa9793 100644 --- a/hive-priv-sock/src/lib.rs +++ b/hive-priv-sock/src/lib.rs @@ -294,9 +294,8 @@ pub struct CredentialMount { /// Network isolation parameters for `WriteNspawnFlags`. hive-priv writes /// `PRIVATE_NETWORK=1` + veth bridge wiring from these; every container /// is isolated, so they are required rather than a mode selector. -/// Containers receive their IP -/// dynamically via DHCP from the bridge dnsmasq pool (`networking.useDHCP` -/// in `harness-base.nix`); no static address is pre-assigned here. +/// No static address is pre-assigned here — see `docs/network.md` +/// § *Container isolation* for how a container gets its address. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct NetworkIsolation { /// Host bridge interface name (e.g. `hive0`). @@ -306,9 +305,8 @@ pub struct NetworkIsolation { /// container-side setup installs a default route (`default via `) /// before DHCP completes: without it the container has no route off /// the bridge subnet until the DHCP lease arrives. The same IP runs the - /// hive dnsmasq resolver, so it's also written into the container's - /// `/etc/resolv.conf` (see the isolated-DNS oneshot in `harness-base.nix`, - /// gated on the marker hive-priv drops). + /// hive dnsmasq resolver — see `docs/network.md` § *How the isolated + /// container gets its resolver*. pub gateway_ip: String, } diff --git a/hive-priv/src/main.rs b/hive-priv/src/main.rs index 57be923e..45800558 100644 --- a/hive-priv/src/main.rs +++ b/hive-priv/src/main.rs @@ -2759,10 +2759,9 @@ fn write_nspawn_flags( // setup is skipped, so this only affects the container's route — // exactly what we want. let _ = writeln!(out, "HOST_ADDRESS={}", iso.gateway_ip); - // LOCAL_ADDRESS is intentionally empty: agent containers receive their - // IP dynamically via DHCP from the bridge dnsmasq pool. HOST_ADDRESS - // (the gateway IP) is still written so nixos-container's container-side - // init installs a default route before the DHCP lease arrives. + // LOCAL_ADDRESS is intentionally empty: containers take their IP by + // DHCP from the bridge dnsmasq pool. (Why HOST_ADDRESS is still + // written: the comment directly above.) out.push_str("LOCAL_ADDRESS=\n"); out.push_str("HOST_ADDRESS6=\n"); out.push_str("LOCAL_ADDRESS6=\n"); @@ -2790,15 +2789,13 @@ fn write_nspawn_flags( let _ = writeln!(out, "EXTRA_NSPAWN_FLAGS=\"{flags_joined}\""); std::fs::write(&path, out).with_context(|| format!("write {path}"))?; - // DNS marker for the in-container resolver oneshot. nixos-container - // copies the *host's* /etc/resolv.conf into the container at every - // start (its host resolver — e.g. 127.0.0.53 — is unreachable from a - // private netns, and isn't authoritative for the hive's own zones - // anyway). The `hyperhive-isolated-dns` oneshot in harness-base.nix - // rewrites resolv.conf to point at the bridge resolver, but only when - // this marker exists; it carries the gateway IP so the container - // doesn't have to re-derive it. Always written — every container is - // isolated, so there is no mode in which the marker should be absent. + // DNS marker for the in-container resolver oneshot: the oneshot only + // rewrites the container's resolv.conf when this marker exists, and the + // marker carries the gateway IP so the container need not re-derive it. + // Always written — every container is isolated, so there is no mode in + // which the marker should be absent. Why the rewrite is needed at all, + // and which unit does it: `docs/network.md` § *How the isolated + // container gets its resolver*. write_bridge_dns_marker(container, isolation)?; Ok(()) }