feat(#2363): full-DHCP for all agents — drop static agent_network_ip

All agent containers now receive their bridge IP dynamically via DHCP
from the dnsmasq pool instead of a hash-derived static address:

- nix/templates/harness-base.nix: networking.useDHCP = true
- nix/modules/hive-gateway.nix: expand DHCP pool to full usable range
  (.2 to .254 on /24) — was last-14-IPs-only
- hive-sh4re/src/priv_proto.rs: remove agent_ip from NetworkIsolation
- hive-c0re/src/lifecycle/mod.rs: drop agent_network_ip + DHCP_POOL_SIZE
- hive-c0re/src/lifecycle/host_config.rs: remove agent_network_ip call
- hive-priv/src/main.rs: LOCAL_ADDRESS= empty (DHCP assigns IP);
  HOST_ADDRESS still set so nixos-container installs default route
  before the DHCP lease arrives
- nix/dhcp-pool-size: deleted (no longer needed)

The nix/dhcp-pool-size single-source-of-truth file and all associated
Rust/Nix dual-constant plumbing are gone — there is no static map.
bridge_gateway_ip() is retained (still needed for HOST_ADDRESS).

Closes #2363
This commit is contained in:
atlas 2026-07-13 11:18:42 +02:00 committed by mara
commit 4cdbbafc44
8 changed files with 37 additions and 244 deletions

View file

@ -10,7 +10,7 @@ use hive_sh4re::priv_proto::{BindMount, CredentialMount};
use crate::coordinator::{AgentPaths, HiveEnv};
use super::{
AGENT_PREFIX, CONTAINER_RUNTIME_MOUNT, CONTAINER_SHARED_MOUNT, agent_network_ip, agent_uid_gid,
AGENT_PREFIX, CONTAINER_RUNTIME_MOUNT, CONTAINER_SHARED_MOUNT, agent_uid_gid,
bridge_gateway_ip, container_claude_mount, container_name, validate,
};
@ -294,21 +294,6 @@ async fn set_nspawn_flags(
let bridge = std::env::var("HIVE_NETWORK_BRIDGE").unwrap_or_default();
let subnet = std::env::var("HIVE_NETWORK_SUBNET").unwrap_or_default();
if isolate && !bridge.is_empty() && !subnet.is_empty() {
let Some(agent_ip) = agent_network_ip(agent_name, &subnet) else {
tracing::warn!(
%agent_name, %subnet,
"HIVE_NETWORK_SUBNET is set but could not derive a valid IP for agent \
(bad CIDR? prefix too narrow?); skipping PRIVATE_NETWORK write to \
avoid misconfigured isolation"
);
return crate::priv_client::write_nspawn_flags(
container,
&binds,
None,
&load_creds,
)
.await;
};
let Some(gateway_ip) = bridge_gateway_ip(&subnet) else {
tracing::warn!(
%agent_name, %subnet,
@ -325,14 +310,10 @@ async fn set_nspawn_flags(
.await;
};
tracing::info!(
%agent_name, %agent_ip, %gateway_ip, %bridge,
"network isolation: PRIVATE_NETWORK=1"
%agent_name, %gateway_ip, %bridge,
"network isolation: PRIVATE_NETWORK=1 (DHCP)"
);
Some(hive_sh4re::priv_proto::NetworkIsolation {
agent_ip,
bridge,
gateway_ip,
})
Some(hive_sh4re::priv_proto::NetworkIsolation { bridge, gateway_ip })
} else {
None
}