nix: remove the non-isolated (shared-netns) mode
Network isolation is validated working end to end (forge + matrix reach the gateway under private netns), so the shared-host-netns mode is removed — there is now one mode. - hive-network.nix: the bridge/DNS block and the isolation overlay are now unconditional whenever hyperhive is enabled (gated on services.hyperhive.enable, not the per-feature toggles). The redundant isolateContainers-implies-enable guard is dropped. - network.enable and isolateContainers are kept as DEPRECATED no-op options so existing configs that set them to true still evaluate cleanly; setting either to false now warns (gated on hyperhive being enabled, so a non-hyperhive host gets no spurious warning) and has no effect. Both are slated for removal in a future release. - hive-c0re.nix: the HIVE_FORGE_URL / HIVE_MATRIX_URL conditionals drop the "&& isolateContainers" clause — agents always reach forge/matrix through the gateway vhost now. - hive-matrix.nix: refresh one stale comment. The Rust lifecycle is env-driven (HIVE_NETWORK_ISOLATION), so no Rust change is needed: the env is now always set, so the existing private-netns path always runs. Supersedes the default-on flip (the option it would have defaulted is gone).
This commit is contained in:
parent
8acf9dcd9b
commit
78482cb624
3 changed files with 74 additions and 54 deletions
|
|
@ -756,10 +756,13 @@ in
|
||||||
# needed — nginx proxies to forgejo as it does for the operator.
|
# needed — nginx proxies to forgejo as it does for the operator.
|
||||||
# - Shared netns: host loopback is reachable, use direct port.
|
# - Shared netns: host loopback is reachable, use direct port.
|
||||||
# See `docs/gateway.md::HIVE_FORGE_URL`.
|
# See `docs/gateway.md::HIVE_FORGE_URL`.
|
||||||
|
# Network isolation is now unconditional (the shared-netns mode was
|
||||||
|
# removed), so agents always reach the forge through the gateway
|
||||||
|
# vhost rather than host loopback. The `network.enable` guard remains
|
||||||
|
# only so a deliberately network-less deployment still falls back to
|
||||||
|
# loopback; in the normal case it is always on.
|
||||||
HIVE_FORGE_URL =
|
HIVE_FORGE_URL =
|
||||||
if
|
if config.services.hyperhive.network.enable then
|
||||||
config.services.hyperhive.network.enable && config.services.hyperhive.network.isolateContainers
|
|
||||||
then
|
|
||||||
"http://${config.services.hyperhive.forge.domain}"
|
"http://${config.services.hyperhive.forge.domain}"
|
||||||
else
|
else
|
||||||
"http://127.0.0.1:${toString config.services.hyperhive.forge.httpPort}";
|
"http://127.0.0.1:${toString config.services.hyperhive.forge.httpPort}";
|
||||||
|
|
@ -767,19 +770,17 @@ in
|
||||||
// lib.optionalAttrs config.services.hyperhive.matrix.enable {
|
// lib.optionalAttrs config.services.hyperhive.matrix.enable {
|
||||||
# In-cluster matrix homeserver URL for each agent's
|
# In-cluster matrix homeserver URL for each agent's
|
||||||
# hive-matrix-daemon. Same shape + rationale as HIVE_FORGE_URL:
|
# hive-matrix-daemon. Same shape + rationale as HIVE_FORGE_URL:
|
||||||
# - Isolated (private netns): reach tuwunel via the gateway vhost
|
# network isolation is now unconditional, so agents reach tuwunel
|
||||||
# (`matrix.<domain>`) on plain http:80 — host loopback is dead.
|
# via the gateway vhost (`matrix.<domain>`) on plain http:80 rather
|
||||||
# - Shared netns: direct host loopback on the tuwunel port.
|
# than host loopback. The gatewayHost null-guard falls back to
|
||||||
# gatewayHost null-guard falls back to loopback so a domain-less
|
# loopback so a domain-less config still evals; the `network.enable`
|
||||||
# config doesn't break eval (it just won't work under isolation,
|
# guard covers a deliberately network-less deployment. Forwarded to
|
||||||
# which needs a gateway anyway). Forwarded to agents by meta.rs
|
# agents by meta.rs alongside HIVE_FORGE_URL; shares the same
|
||||||
# alongside HIVE_FORGE_URL; shares the same env-forwarding ordering
|
# env-forwarding ordering caveat (value baked at config-generation
|
||||||
# caveat (value baked at config-generation time).
|
# time).
|
||||||
HIVE_MATRIX_URL =
|
HIVE_MATRIX_URL =
|
||||||
if
|
if
|
||||||
config.services.hyperhive.network.enable
|
config.services.hyperhive.network.enable && config.services.hyperhive.matrix.gatewayHost != null
|
||||||
&& config.services.hyperhive.network.isolateContainers
|
|
||||||
&& config.services.hyperhive.matrix.gatewayHost != null
|
|
||||||
then
|
then
|
||||||
"http://${config.services.hyperhive.matrix.gatewayHost}"
|
"http://${config.services.hyperhive.matrix.gatewayHost}"
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -377,7 +377,7 @@ in
|
||||||
# `environment.etc."resolv.conf".text` is `nameserver <bridgeIp>`.
|
# `environment.etc."resolv.conf".text` is `nameserver <bridgeIp>`.
|
||||||
# This container always shares the host netns
|
# This container always shares the host netns
|
||||||
# (`privateNetwork = false`), so it reaches `bridgeIp` regardless
|
# (`privateNetwork = false`), so it reaches `bridgeIp` regardless
|
||||||
# of `isolateContainers`. Network module off → inherit the host's
|
# of agent-container isolation. Network module off → inherit the host's
|
||||||
# resolv.conf. See `docs/network.md`.
|
# resolv.conf. See `docs/network.md`.
|
||||||
networking = lib.mkMerge [
|
networking = lib.mkMerge [
|
||||||
(lib.mkIf networkCfg.enable {
|
(lib.mkIf networkCfg.enable {
|
||||||
|
|
|
||||||
|
|
@ -19,18 +19,18 @@ in
|
||||||
defaultText = lib.literalExpression "config.services.hyperhive.enable";
|
defaultText = lib.literalExpression "config.services.hyperhive.enable";
|
||||||
example = false;
|
example = false;
|
||||||
description = ''
|
description = ''
|
||||||
Stand up the hive-internal bridge + dnsmasq resolver.
|
**DEPRECATED — ignored.** The hive network (bridge + dnsmasq
|
||||||
Defaults to `config.services.hyperhive.enable` so it comes
|
resolver + private-netns isolation) is now always on whenever
|
||||||
on automatically with the rest of hyperhive. Requires
|
hyperhive is enabled; setting this to `false` warns and has no
|
||||||
`services.hyperhive.domain` to be set — the dnsmasq resolver
|
effect. Retained as a no-op so existing configs eval; will be
|
||||||
is authoritative for `<hive-domain>` and its sub-domains.
|
removed in a future release.
|
||||||
When enabled: a bridge interface (`bridgeName`) appears on the
|
|
||||||
host with `bridgeIp` assigned, and the hive-gateway container
|
The network requires `services.hyperhive.domain` to be set — the
|
||||||
runs a dnsmasq listening on that IP for `<hive-domain>` +
|
dnsmasq resolver is authoritative for `<hive-domain>` and its
|
||||||
sub-domains. Agent containers still default to shared host
|
sub-domains. A bridge interface (`bridgeName`) appears on the host
|
||||||
netns — the endpoint is up but only used once
|
with `bridgeIp` assigned, the hive-gateway container runs a dnsmasq
|
||||||
`isolateContainers = true` flips containers to private netns
|
on that IP, and each agent container runs in a private netns with a
|
||||||
+ veth peers on this bridge.
|
veth pair on the bridge.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -94,11 +94,16 @@ in
|
||||||
|
|
||||||
isolateContainers = lib.mkOption {
|
isolateContainers = lib.mkOption {
|
||||||
type = lib.types.bool;
|
type = lib.types.bool;
|
||||||
default = false;
|
default = true;
|
||||||
example = true;
|
example = true;
|
||||||
description = ''
|
description = ''
|
||||||
Flip agent containers from shared host netns to private netns.
|
**DEPRECATED — ignored.** Network isolation is now the only mode and
|
||||||
When true, each agent container gets a dedicated veth
|
is always on whenever hyperhive is enabled; the shared-netns path was
|
||||||
|
removed. This option is retained as a no-op so existing configs eval;
|
||||||
|
setting it to `false` warns and has no effect. It will be removed in
|
||||||
|
a future release.
|
||||||
|
|
||||||
|
Each agent container gets a dedicated veth
|
||||||
pair attached to `bridgeName` and a deterministic IP from
|
pair attached to `bridgeName` and a deterministic IP from
|
||||||
the bridge subnet. The bridge (already up when `enable = true`)
|
the bridge subnet. The bridge (already up when `enable = true`)
|
||||||
becomes the sole routed path between the host and agent
|
becomes the sole routed path between the host and agent
|
||||||
|
|
@ -142,21 +147,27 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkMerge [
|
config = lib.mkMerge [
|
||||||
(lib.mkIf cfg.enable {
|
# The hive network + container isolation are unconditional whenever
|
||||||
|
# hyperhive is enabled: the shared-netns mode was removed, so there is
|
||||||
|
# one mode (private netns behind the bridge). `network.enable` and
|
||||||
|
# `isolateContainers` are kept as deprecated no-op options (see the
|
||||||
|
# warnings block below) so existing configs that set them still eval.
|
||||||
|
(lib.mkIf config.services.hyperhive.enable {
|
||||||
assertions = [
|
assertions = [
|
||||||
{
|
{
|
||||||
assertion = config.services.hyperhive.domain != null;
|
assertion = config.services.hyperhive.domain != null;
|
||||||
message = ''
|
message = ''
|
||||||
services.hyperhive.network.enable = true requires
|
hyperhive requires services.hyperhive.domain to be set — the
|
||||||
services.hyperhive.domain to be set — the resolver needs a
|
hive resolver is authoritative for `<hive-domain>` and its
|
||||||
domain to be authoritative for. Either pin a hostname
|
sub-domains, and agents reach the forge/matrix through the
|
||||||
(`services.hyperhive.domain = "example.com";`) or set
|
gateway by that domain. Pin a hostname
|
||||||
`services.hyperhive.network.enable = false` explicitly.
|
(`services.hyperhive.domain = "example.com";`).
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
# Virtual bridge — veth pairs attach when isolateContainers flips on.
|
# Virtual bridge — each agent container attaches a veth pair (isolation
|
||||||
|
# is unconditional now).
|
||||||
networking.bridges.${cfg.bridgeName}.interfaces = [ ];
|
networking.bridges.${cfg.bridgeName}.interfaces = [ ];
|
||||||
|
|
||||||
# Bridge IP — dnsmasq (in the gateway container) binds here.
|
# Bridge IP — dnsmasq (in the gateway container) binds here.
|
||||||
|
|
@ -174,23 +185,9 @@ in
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|
||||||
# Guard: fires unconditionally on isolateContainers so the assertion
|
# Container isolation overlay — now unconditional (the shared-netns
|
||||||
# is not silently swallowed when enable=false.
|
# mode was removed). See docs/network.md#container-isolation.
|
||||||
(lib.mkIf cfg.isolateContainers {
|
(lib.mkIf config.services.hyperhive.enable {
|
||||||
assertions = [
|
|
||||||
{
|
|
||||||
assertion = cfg.enable;
|
|
||||||
message = ''
|
|
||||||
services.hyperhive.network.isolateContainers = true requires
|
|
||||||
services.hyperhive.network.enable = true (the bridge and
|
|
||||||
resolver must be running before isolation is flipped on).
|
|
||||||
'';
|
|
||||||
}
|
|
||||||
];
|
|
||||||
})
|
|
||||||
|
|
||||||
# Container isolation overlay — see docs/network.md#container-isolation.
|
|
||||||
(lib.mkIf (cfg.enable && cfg.isolateContainers) {
|
|
||||||
|
|
||||||
# Agents route internet traffic via the bridge; NAT masquerades their RFC-1918 IPs.
|
# Agents route internet traffic via the bridge; NAT masquerades their RFC-1918 IPs.
|
||||||
boot.kernel.sysctl."net.ipv4.ip_forward" = 1;
|
boot.kernel.sysctl."net.ipv4.ip_forward" = 1;
|
||||||
|
|
@ -222,5 +219,27 @@ in
|
||||||
HIVE_NETWORK_SUBNET = "${cfg.bridgeIp}/${toString cfg.bridgePrefixLength}";
|
HIVE_NETWORK_SUBNET = "${cfg.bridgeIp}/${toString cfg.bridgePrefixLength}";
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|
||||||
|
# Deprecation surface for the removed toggles. Both options are kept so
|
||||||
|
# existing configs that set them to `true` still eval cleanly; setting
|
||||||
|
# either to `false` no longer does anything (network + isolation are
|
||||||
|
# unconditional now), so warn rather than silently ignore.
|
||||||
|
{
|
||||||
|
# Only warn when hyperhive itself is enabled — otherwise `cfg.enable`
|
||||||
|
# defaults to `false` (tracking `hyperhive.enable`) and we'd fire a
|
||||||
|
# spurious deprecation warning on a host that doesn't run hyperhive.
|
||||||
|
warnings = lib.optionals config.services.hyperhive.enable (
|
||||||
|
lib.optional (!cfg.enable) ''
|
||||||
|
services.hyperhive.network.enable = false is deprecated and ignored
|
||||||
|
— the hive network is now always on (private-netns isolation is the
|
||||||
|
only mode). Remove the setting.
|
||||||
|
''
|
||||||
|
++ lib.optional (!cfg.isolateContainers) ''
|
||||||
|
services.hyperhive.network.isolateContainers = false is deprecated
|
||||||
|
and ignored — network isolation is now the only mode and is always
|
||||||
|
on. Remove the setting.
|
||||||
|
''
|
||||||
|
);
|
||||||
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue