From 7ad2bb9211c46103dfc8f0c7c4e6d422e27fdabc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?m=C3=BCde?= Date: Mon, 13 Jul 2026 21:58:30 +0200 Subject: [PATCH] refactor: replace deprecated no-op options with mkRemovedOptionModule --- nix/modules/hive-forge.nix | 3 +- nix/modules/hive-gateway/default.nix | 37 ++++---------- nix/modules/hive-gateway/options.nix | 29 ++++------- nix/modules/hive-matrix.nix | 73 ++++++++++++--------------- nix/modules/hive-network.nix | 74 ++++++---------------------- nix/modules/hive-tls.nix | 22 ++++----- nix/templates/harness/default.nix | 19 +++---- nix/templates/harness/mcp.nix | 17 ------- 8 files changed, 85 insertions(+), 189 deletions(-) diff --git a/nix/modules/hive-forge.nix b/nix/modules/hive-forge.nix index 90378b25..f625a8a7 100644 --- a/nix/modules/hive-forge.nix +++ b/nix/modules/hive-forge.nix @@ -23,8 +23,7 @@ let defaultRootUrl = if cfg.behindGateway then let - portSuffix = - if gatewayCfg.httpsPort == 443 then "" else ":${toString gatewayCfg.httpsPort}"; + portSuffix = if gatewayCfg.httpsPort == 443 then "" else ":${toString gatewayCfg.httpsPort}"; in "https://${cfg.domain}${portSuffix}/" else diff --git a/nix/modules/hive-gateway/default.nix b/nix/modules/hive-gateway/default.nix index 757f02fa..acdd34e7 100644 --- a/nix/modules/hive-gateway/default.nix +++ b/nix/modules/hive-gateway/default.nix @@ -28,8 +28,7 @@ let # (`tls.certDir`) nor ACME (`tls.acme.enable`) is configured, the gateway # generates + serves a hive-CA-signed leaf (see hive-tls.nix). There is no # explicit toggle and no http-only mode — matrix discovery requires https, - # so the gateway always terminates TLS. The deprecated `selfSignedTls` - # option is a no-op kept only so existing configs eval (see warnings). + # so the gateway always terminates TLS. # `cfg.useSelfSigned` (options.nix) is the derived single source of truth. useSelfSigned = cfg.useSelfSigned; in @@ -55,20 +54,6 @@ in } ]; - # Deprecation surface for the removed `selfSignedTls` toggle. Self-signed - # is now the implicit floor (used whenever neither `tls.certDir` nor - # `tls.acme` is set), so the toggle no longer does anything. Warn only - # when it's set to `false` — that's the case that previously meant - # "http-only / external-only", which no longer exists; `= true` matches - # the effective behaviour and stays silent to avoid noise. - warnings = lib.optional (!cfg.selfSignedTls) '' - services.hyperhive.gateway.selfSignedTls = false is deprecated and - ignored — self-signed TLS is now the default whenever no other TLS - source is configured, and there is no http-only mode. Remove the - setting; configure `tls.certDir` or `tls.acme` to override the - self-signed default. - ''; - # Ensure bind-mount sources exist at host boot before the gateway # container's first start. nspawn would auto-create missing dirs; # tmpfiles rules make the intent explicit and cover the fresh-boot @@ -259,17 +244,15 @@ in inherit (nginxTree) appendHttpConfig virtualHosts; }; - services.dnsmasq = lib.mkIf networkCfg.enable ( - import ./dnsmasq.nix { - inherit - lib - networkCfg - forgeCfg - matrixCfg - hyperhiveDomain - ; - } - ); + services.dnsmasq = import ./dnsmasq.nix { + inherit + lib + networkCfg + forgeCfg + matrixCfg + hyperhiveDomain + ; + }; }; }; diff --git a/nix/modules/hive-gateway/options.nix b/nix/modules/hive-gateway/options.nix index 5d5a3133..211a8c3a 100644 --- a/nix/modules/hive-gateway/options.nix +++ b/nix/modules/hive-gateway/options.nix @@ -12,6 +12,15 @@ let cfg = config.services.hyperhive.gateway; in { + imports = [ + (lib.mkRemovedOptionModule [ "services" "hyperhive" "gateway" "selfSignedTls" ] '' + Self-signed TLS is the implicit default whenever neither + tls.certDir nor tls.acme is configured, and there is no http-only + mode. Remove the setting; configure `tls.certDir` or `tls.acme` + to override the self-signed default. + '') + ]; + options.services.hyperhive.gateway = { port = lib.mkOption { type = lib.types.port; @@ -85,26 +94,6 @@ in ''; }; - selfSignedTls = lib.mkOption { - type = lib.types.bool; - default = true; - example = false; - description = '' - **DEPRECATED — ignored.** Self-signed TLS is now the implicit - default: when neither `tls.certDir` nor `tls.acme.enable` is - configured, the gateway generates and serves a hive-CA-signed - leaf (see the `hive-tls` module). There is no explicit toggle and - no http-only mode — matrix discovery hardcodes - `https:///.well-known/matrix/client`, so the gateway always - terminates TLS. This option is retained as a no-op so existing - configs eval; setting it (to either value) warns and has no - effect, and it will be removed in a future release. Use - `tls.certDir` or `tls.acme` to override the self-signed default. - - See `docs/gateway.md` ("Self-signed TLS"). - ''; - }; - useSelfSigned = lib.mkOption { type = lib.types.bool; internal = true; diff --git a/nix/modules/hive-matrix.nix b/nix/modules/hive-matrix.nix index b8a7378a..1dc5d65d 100644 --- a/nix/modules/hive-matrix.nix +++ b/nix/modules/hive-matrix.nix @@ -366,39 +366,31 @@ in # gets the host file across the shared-netns boundary), so it # regenerates an empty file and tuwunel dies at boot. # - # The earlier fix turned host-tracking off and trusted resolvconf - # to honour `networking.nameservers` — but that's a RUNTIME - # resolvconf behaviour, not verifiable at eval time, and it STILL - # came up empty in practice. So take resolvconf out of the - # loop entirely and write a STATIC `/etc/resolv.conf` from - # `bridgeIp` that nothing regenerates. Eval-proven: the generated + # Trusting resolvconf to honour `networking.nameservers` doesn't + # work either — that's a RUNTIME resolvconf behaviour, not + # verifiable at eval time, and it still comes up empty in + # practice. So take resolvconf out of the loop entirely and + # write a STATIC `/etc/resolv.conf` from `bridgeIp` that nothing + # regenerates. Eval-proven: the generated # `environment.etc."resolv.conf".text` is `nameserver `. # This container always shares the host netns # (`privateNetwork = false`), so it reaches `bridgeIp` regardless - # of agent-container isolation. Network module off → inherit the host's - # resolv.conf. See `docs/network.md`. - networking = lib.mkMerge [ - (lib.mkIf networkCfg.enable { - # resolvconf is taken out of the loop entirely; the static - # `environment.etc."resolv.conf"` below is the sole source of - # the resolver file (no `nameservers` — nothing would read it). - useHostResolvConf = lib.mkForce false; - resolvconf.enable = lib.mkForce false; - }) - (lib.mkIf (!networkCfg.enable) { - useHostResolvConf = true; - }) - ]; + # of agent-container isolation. See `docs/network.md`. + networking = { + # resolvconf is taken out of the loop entirely; the static + # `environment.etc."resolv.conf"` below is the sole source of + # the resolver file (no `nameservers` — nothing would read it). + useHostResolvConf = lib.mkForce false; + resolvconf.enable = lib.mkForce false; + }; # resolvconf is disabled above, so write the static resolver file # explicitly — NixOS won't synthesise one from `nameservers` once # resolvconf is off, and this is the file tuwunel parses at boot. - environment.etc = lib.mkIf networkCfg.enable { - "resolv.conf".text = '' - nameserver ${networkCfg.bridgeIp} - options edns0 - ''; - }; + environment.etc."resolv.conf".text = '' + nameserver ${networkCfg.bridgeIp} + options edns0 + ''; services.matrix-tuwunel = { enable = true; @@ -444,21 +436,20 @@ in ]; }; - # When the hive network module is on, the matrix container's resolver - # is the dnsmasq that runs in the gateway container (bound at - # `bridgeIp`). Order the matrix container start after the gateway - # container so the resolver is up before tuwunel's first federation - # lookups. tuwunel boots fine without this — it configures the resolver - # from `/etc/resolv.conf` at startup and only queries on-demand (the - # boot failure this module fixes was an *empty* resolv.conf, a parse - # error, not a connectivity one) — so this is robustness, not a boot - # requirement. Soft `after` ordering (not `requires`) keeps the matrix - # container's lifecycle decoupled from the gateway's. The gateway - # always runs alongside hyperhive, so the gateway container unit always - # exists here. (Declarative `containers.` → `container@.service` — the - # nspawn template NixOS generates, confirmed from the live - # `container@hive-matrix.service` host unit.) - systemd.services."container@hive-matrix".after = lib.mkIf networkCfg.enable [ + # The matrix container's resolver is the dnsmasq that runs in the + # gateway container (bound at `bridgeIp`). Order the matrix + # container start after the gateway container so the resolver is up + # before tuwunel's first federation lookups. tuwunel boots fine + # without this — it configures the resolver from `/etc/resolv.conf` + # at startup and only queries on-demand (the boot failure this + # module guards against is an *empty* resolv.conf, a parse error, + # not a connectivity one) — so this is robustness, not a boot + # requirement. Soft `after` ordering (not `requires`) keeps the + # matrix container's lifecycle decoupled from the gateway's. The + # gateway always runs alongside hyperhive, so the gateway container + # unit always exists here. (Declarative `containers.` → + # `container@.service` — the nspawn template NixOS generates.) + systemd.services."container@hive-matrix".after = [ "container@hive-gateway.service" ]; }; diff --git a/nix/modules/hive-network.nix b/nix/modules/hive-network.nix index 7a510657..5cbc6c9c 100644 --- a/nix/modules/hive-network.nix +++ b/nix/modules/hive-network.nix @@ -33,28 +33,20 @@ in # Always active when hyperhive is enabled: agent containers run in # private netns behind the bridge. Full design: docs/network.md. + imports = [ + (lib.mkRemovedOptionModule [ "services" "hyperhive" "network" "enable" ] '' + The hive network (bridge + dnsmasq resolver + private-netns + isolation) is always on whenever hyperhive is enabled. Remove the + setting. + '') + (lib.mkRemovedOptionModule [ "services" "hyperhive" "network" "isolateContainers" ] '' + Network isolation is the only mode and is always on whenever + hyperhive is enabled; the shared-netns path was removed. Remove + the setting. + '') + ]; + options.services.hyperhive.network = { - enable = lib.mkOption { - type = lib.types.bool; - default = config.services.hyperhive.enable; - defaultText = lib.literalExpression "config.services.hyperhive.enable"; - example = false; - description = '' - **DEPRECATED — ignored.** The hive network (bridge + dnsmasq - resolver + private-netns isolation) is now always on whenever - hyperhive is enabled; setting this to `false` warns and has no - effect. Retained as a no-op so existing configs eval; will be - removed in a future release. - - The network requires `services.hyperhive.domain` to be set — the - dnsmasq resolver is authoritative for `` and its - sub-domains. A bridge interface (`bridgeName`) appears on the host - with `bridgeIp` assigned, the hive-gateway container runs a dnsmasq - on that IP, and each agent container runs in a private netns with a - veth pair on the bridge. - ''; - }; - bridgeName = lib.mkOption { type = lib.types.str; default = "hive-br0"; @@ -168,26 +160,12 @@ in ''; }; - isolateContainers = lib.mkOption { - type = lib.types.bool; - default = true; - example = true; - description = '' - **DEPRECATED — ignored.** Network isolation is now the only mode and - 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. - ''; - }; }; config = lib.mkMerge [ # 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. + # hyperhive is enabled: the shared-netns mode was removed, so there + # is one mode (private netns behind the bridge). (lib.mkIf config.services.hyperhive.enable { assertions = [ { @@ -275,27 +253,5 @@ in (lib.mkIf (config.services.hyperhive.enable && cfg.exposeHostPorts != [ ]) { networking.firewall.interfaces.${cfg.bridgeName}.allowedTCPPorts = cfg.exposeHostPorts; }) - - # 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. - '' - ); - } ]; } diff --git a/nix/modules/hive-tls.nix b/nix/modules/hive-tls.nix index d8e82df7..2d3d4bea 100644 --- a/nix/modules/hive-tls.nix +++ b/nix/modules/hive-tls.nix @@ -22,19 +22,17 @@ in { # Host-side TLS trust root for the self-signed gateway mode. # - # `gateway.selfSignedTls` historically generated a *bare* self-signed - # leaf inside the gateway container at first boot. A bare leaf is its - # own trust anchor, so every regeneration is a new anchor and every - # consumer (agents, federation peers) would have to re-trust on each - # rotation — and a runtime-generated, in-container cert can't be wired - # into an agent's build-time trust store at all. + # A bare self-signed leaf would be its own trust anchor, so every + # regeneration would be a new anchor and every consumer (agents, + # federation peers) would have to re-trust on each rotation — and a + # runtime-generated, in-container cert can't be wired into an agent's + # build-time trust store at all. # - # This module moves the anchor to a long-lived **hive CA** held on the - # host. The gateway serves a **leaf** signed by that CA (via the - # existing `tls.certDir` bind-mount path); agents and federation peers - # trust the *CA* once, and leaf rotation never re-breaks them. See - # `docs/gateway.md` ("Self-signed TLS") and issue-tracker discussion of - # agent web-UI reachability. + # So the anchor is a long-lived **hive CA** held on the host. The + # gateway serves a **leaf** signed by that CA (via the `tls.certDir` + # bind-mount path); agents and federation peers trust the *CA* once, + # and leaf rotation never re-breaks them. See `docs/gateway.md` + # ("Self-signed TLS"). options.services.hyperhive.tls = { stateDir = lib.mkOption { diff --git a/nix/templates/harness/default.nix b/nix/templates/harness/default.nix index 115f3e1f..7672a5b2 100644 --- a/nix/templates/harness/default.nix +++ b/nix/templates/harness/default.nix @@ -34,19 +34,16 @@ ./packages.nix ./user.nix ./weston-vnc.nix + (lib.mkRemovedOptionModule [ "hyperhive" "web" "useUnixSocket" ] '' + Unix socket mode is always enabled for all agents. Remove the + setting from your agent.nix. + '') + (lib.mkRemovedOptionModule [ "hyperhive" "allowedBashPatterns" ] '' + The built-in Bash tool is fully disabled; agents use + mcp__bash__run instead. Remove the setting from your agent.nix. + '') ]; - options.hyperhive.web.useUnixSocket = lib.mkOption { - type = lib.types.bool; - default = false; - example = true; - description = '' - Deprecated. Unix socket mode is now always enabled for all agents. - Setting this option to `true` has no effect and the option will be - removed in a future version. Safe to drop from agent configs. - ''; - }; - options.hyperhive.icon = lib.mkOption { type = lib.types.nullOr lib.types.path; default = null; diff --git a/nix/templates/harness/mcp.nix b/nix/templates/harness/mcp.nix index cab1695d..717ec0b0 100644 --- a/nix/templates/harness/mcp.nix +++ b/nix/templates/harness/mcp.nix @@ -12,17 +12,6 @@ let userName = config.hyperhive.user.name; in { - options.hyperhive.allowedBashPatterns = lib.mkOption { - type = lib.types.listOf lib.types.str; - default = [ ]; - description = '' - Deprecated - has no effect. The built-in Bash tool is fully - disabled regardless of this list; agents use mcp__bash__run - instead. Remove this option from your agent.nix. - ''; - visible = false; - }; - options.hyperhive.allowedRecipients = lib.mkOption { type = lib.types.listOf lib.types.str; default = [ ]; @@ -148,12 +137,6 @@ in }; config = { - warnings = lib.optional (config.hyperhive.allowedBashPatterns != [ ]) '' - hyperhive.allowedBashPatterns is deprecated and has no effect. - The built-in Bash tool is fully disabled; agents use mcp__bash__run instead. - Remove allowedBashPatterns from your agent.nix. - ''; - # Auto-inject the built-in bash MCP server — always present, every # agent needs bash tools. `lib.mkDefault` so the operator's own # agent.nix can override the entry. (The matrix sibling lives in