refactor: replace deprecated no-op options with mkRemovedOptionModule
This commit is contained in:
parent
43bbd64f82
commit
7ad2bb9211
8 changed files with 85 additions and 189 deletions
|
|
@ -23,8 +23,7 @@ let
|
||||||
defaultRootUrl =
|
defaultRootUrl =
|
||||||
if cfg.behindGateway then
|
if cfg.behindGateway then
|
||||||
let
|
let
|
||||||
portSuffix =
|
portSuffix = if gatewayCfg.httpsPort == 443 then "" else ":${toString gatewayCfg.httpsPort}";
|
||||||
if gatewayCfg.httpsPort == 443 then "" else ":${toString gatewayCfg.httpsPort}";
|
|
||||||
in
|
in
|
||||||
"https://${cfg.domain}${portSuffix}/"
|
"https://${cfg.domain}${portSuffix}/"
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -28,8 +28,7 @@ let
|
||||||
# (`tls.certDir`) nor ACME (`tls.acme.enable`) is configured, the gateway
|
# (`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
|
# 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,
|
# explicit toggle and no http-only mode — matrix discovery requires https,
|
||||||
# so the gateway always terminates TLS. The deprecated `selfSignedTls`
|
# so the gateway always terminates TLS.
|
||||||
# option is a no-op kept only so existing configs eval (see warnings).
|
|
||||||
# `cfg.useSelfSigned` (options.nix) is the derived single source of truth.
|
# `cfg.useSelfSigned` (options.nix) is the derived single source of truth.
|
||||||
useSelfSigned = cfg.useSelfSigned;
|
useSelfSigned = cfg.useSelfSigned;
|
||||||
in
|
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
|
# Ensure bind-mount sources exist at host boot before the gateway
|
||||||
# container's first start. nspawn would auto-create missing dirs;
|
# container's first start. nspawn would auto-create missing dirs;
|
||||||
# tmpfiles rules make the intent explicit and cover the fresh-boot
|
# tmpfiles rules make the intent explicit and cover the fresh-boot
|
||||||
|
|
@ -259,17 +244,15 @@ in
|
||||||
inherit (nginxTree) appendHttpConfig virtualHosts;
|
inherit (nginxTree) appendHttpConfig virtualHosts;
|
||||||
};
|
};
|
||||||
|
|
||||||
services.dnsmasq = lib.mkIf networkCfg.enable (
|
services.dnsmasq = import ./dnsmasq.nix {
|
||||||
import ./dnsmasq.nix {
|
inherit
|
||||||
inherit
|
lib
|
||||||
lib
|
networkCfg
|
||||||
networkCfg
|
forgeCfg
|
||||||
forgeCfg
|
matrixCfg
|
||||||
matrixCfg
|
hyperhiveDomain
|
||||||
hyperhiveDomain
|
;
|
||||||
;
|
};
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,15 @@ let
|
||||||
cfg = config.services.hyperhive.gateway;
|
cfg = config.services.hyperhive.gateway;
|
||||||
in
|
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 = {
|
options.services.hyperhive.gateway = {
|
||||||
port = lib.mkOption {
|
port = lib.mkOption {
|
||||||
type = lib.types.port;
|
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://<host>/.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 {
|
useSelfSigned = lib.mkOption {
|
||||||
type = lib.types.bool;
|
type = lib.types.bool;
|
||||||
internal = true;
|
internal = true;
|
||||||
|
|
|
||||||
|
|
@ -366,39 +366,31 @@ in
|
||||||
# gets the host file across the shared-netns boundary), so it
|
# gets the host file across the shared-netns boundary), so it
|
||||||
# regenerates an empty file and tuwunel dies at boot.
|
# regenerates an empty file and tuwunel dies at boot.
|
||||||
#
|
#
|
||||||
# The earlier fix turned host-tracking off and trusted resolvconf
|
# Trusting resolvconf to honour `networking.nameservers` doesn't
|
||||||
# to honour `networking.nameservers` — but that's a RUNTIME
|
# work either — that's a RUNTIME resolvconf behaviour, not
|
||||||
# resolvconf behaviour, not verifiable at eval time, and it STILL
|
# verifiable at eval time, and it still comes up empty in
|
||||||
# came up empty in practice. So take resolvconf out of the
|
# practice. So take resolvconf out of the loop entirely and
|
||||||
# loop entirely and write a STATIC `/etc/resolv.conf` from
|
# write a STATIC `/etc/resolv.conf` from `bridgeIp` that nothing
|
||||||
# `bridgeIp` that nothing regenerates. Eval-proven: the generated
|
# regenerates. Eval-proven: the generated
|
||||||
# `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 agent-container isolation. Network module off → inherit the host's
|
# of agent-container isolation. See `docs/network.md`.
|
||||||
# resolv.conf. See `docs/network.md`.
|
networking = {
|
||||||
networking = lib.mkMerge [
|
# resolvconf is taken out of the loop entirely; the static
|
||||||
(lib.mkIf networkCfg.enable {
|
# `environment.etc."resolv.conf"` below is the sole source of
|
||||||
# resolvconf is taken out of the loop entirely; the static
|
# the resolver file (no `nameservers` — nothing would read it).
|
||||||
# `environment.etc."resolv.conf"` below is the sole source of
|
useHostResolvConf = lib.mkForce false;
|
||||||
# the resolver file (no `nameservers` — nothing would read it).
|
resolvconf.enable = lib.mkForce false;
|
||||||
useHostResolvConf = lib.mkForce false;
|
};
|
||||||
resolvconf.enable = lib.mkForce false;
|
|
||||||
})
|
|
||||||
(lib.mkIf (!networkCfg.enable) {
|
|
||||||
useHostResolvConf = true;
|
|
||||||
})
|
|
||||||
];
|
|
||||||
|
|
||||||
# resolvconf is disabled above, so write the static resolver file
|
# resolvconf is disabled above, so write the static resolver file
|
||||||
# explicitly — NixOS won't synthesise one from `nameservers` once
|
# explicitly — NixOS won't synthesise one from `nameservers` once
|
||||||
# resolvconf is off, and this is the file tuwunel parses at boot.
|
# resolvconf is off, and this is the file tuwunel parses at boot.
|
||||||
environment.etc = lib.mkIf networkCfg.enable {
|
environment.etc."resolv.conf".text = ''
|
||||||
"resolv.conf".text = ''
|
nameserver ${networkCfg.bridgeIp}
|
||||||
nameserver ${networkCfg.bridgeIp}
|
options edns0
|
||||||
options edns0
|
'';
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
services.matrix-tuwunel = {
|
services.matrix-tuwunel = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
@ -444,21 +436,20 @@ in
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
# When the hive network module is on, the matrix container's resolver
|
# The matrix container's resolver is the dnsmasq that runs in the
|
||||||
# is the dnsmasq that runs in the gateway container (bound at
|
# gateway container (bound at `bridgeIp`). Order the matrix
|
||||||
# `bridgeIp`). Order the matrix container start after the gateway
|
# container start after the gateway container so the resolver is up
|
||||||
# container so the resolver is up before tuwunel's first federation
|
# before tuwunel's first federation lookups. tuwunel boots fine
|
||||||
# lookups. tuwunel boots fine without this — it configures the resolver
|
# without this — it configures the resolver from `/etc/resolv.conf`
|
||||||
# from `/etc/resolv.conf` at startup and only queries on-demand (the
|
# at startup and only queries on-demand (the boot failure this
|
||||||
# boot failure this module fixes was an *empty* resolv.conf, a parse
|
# module guards against is an *empty* resolv.conf, a parse error,
|
||||||
# error, not a connectivity one) — so this is robustness, not a boot
|
# not a connectivity one) — so this is robustness, not a boot
|
||||||
# requirement. Soft `after` ordering (not `requires`) keeps the matrix
|
# requirement. Soft `after` ordering (not `requires`) keeps the
|
||||||
# container's lifecycle decoupled from the gateway's. The gateway
|
# matrix container's lifecycle decoupled from the gateway's. The
|
||||||
# always runs alongside hyperhive, so the gateway container unit always
|
# gateway always runs alongside hyperhive, so the gateway container
|
||||||
# exists here. (Declarative `containers.<n>` → `container@<n>.service` — the
|
# unit always exists here. (Declarative `containers.<n>` →
|
||||||
# nspawn template NixOS generates, confirmed from the live
|
# `container@<n>.service` — the nspawn template NixOS generates.)
|
||||||
# `container@hive-matrix.service` host unit.)
|
systemd.services."container@hive-matrix".after = [
|
||||||
systemd.services."container@hive-matrix".after = lib.mkIf networkCfg.enable [
|
|
||||||
"container@hive-gateway.service"
|
"container@hive-gateway.service"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -33,28 +33,20 @@ in
|
||||||
# Always active when hyperhive is enabled: agent containers run in
|
# Always active when hyperhive is enabled: agent containers run in
|
||||||
# private netns behind the bridge. Full design: docs/network.md.
|
# 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 = {
|
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 `<hive-domain>` 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 {
|
bridgeName = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
default = "hive-br0";
|
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 [
|
config = lib.mkMerge [
|
||||||
# The hive network + container isolation are unconditional whenever
|
# The hive network + container isolation are unconditional whenever
|
||||||
# hyperhive is enabled: the shared-netns mode was removed, so there is
|
# hyperhive is enabled: the shared-netns mode was removed, so there
|
||||||
# one mode (private netns behind the bridge). `network.enable` and
|
# is one mode (private netns behind the bridge).
|
||||||
# `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 {
|
(lib.mkIf config.services.hyperhive.enable {
|
||||||
assertions = [
|
assertions = [
|
||||||
{
|
{
|
||||||
|
|
@ -275,27 +253,5 @@ in
|
||||||
(lib.mkIf (config.services.hyperhive.enable && cfg.exposeHostPorts != [ ]) {
|
(lib.mkIf (config.services.hyperhive.enable && cfg.exposeHostPorts != [ ]) {
|
||||||
networking.firewall.interfaces.${cfg.bridgeName}.allowedTCPPorts = 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.
|
|
||||||
''
|
|
||||||
);
|
|
||||||
}
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,19 +22,17 @@ in
|
||||||
{
|
{
|
||||||
# Host-side TLS trust root for the self-signed gateway mode.
|
# Host-side TLS trust root for the self-signed gateway mode.
|
||||||
#
|
#
|
||||||
# `gateway.selfSignedTls` historically generated a *bare* self-signed
|
# A bare self-signed leaf would be its own trust anchor, so every
|
||||||
# leaf inside the gateway container at first boot. A bare leaf is its
|
# regeneration would be a new anchor and every consumer (agents,
|
||||||
# own trust anchor, so every regeneration is a new anchor and every
|
# federation peers) would have to re-trust on each rotation — and a
|
||||||
# consumer (agents, federation peers) would have to re-trust on each
|
# runtime-generated, in-container cert can't be wired into an agent's
|
||||||
# rotation — and a runtime-generated, in-container cert can't be wired
|
# build-time trust store at all.
|
||||||
# into an agent's build-time trust store at all.
|
|
||||||
#
|
#
|
||||||
# This module moves the anchor to a long-lived **hive CA** held on the
|
# So the anchor is a long-lived **hive CA** held on the host. The
|
||||||
# host. The gateway serves a **leaf** signed by that CA (via the
|
# gateway serves a **leaf** signed by that CA (via the `tls.certDir`
|
||||||
# existing `tls.certDir` bind-mount path); agents and federation peers
|
# bind-mount path); agents and federation peers trust the *CA* once,
|
||||||
# trust the *CA* once, and leaf rotation never re-breaks them. See
|
# and leaf rotation never re-breaks them. See `docs/gateway.md`
|
||||||
# `docs/gateway.md` ("Self-signed TLS") and issue-tracker discussion of
|
# ("Self-signed TLS").
|
||||||
# agent web-UI reachability.
|
|
||||||
|
|
||||||
options.services.hyperhive.tls = {
|
options.services.hyperhive.tls = {
|
||||||
stateDir = lib.mkOption {
|
stateDir = lib.mkOption {
|
||||||
|
|
|
||||||
|
|
@ -34,19 +34,16 @@
|
||||||
./packages.nix
|
./packages.nix
|
||||||
./user.nix
|
./user.nix
|
||||||
./weston-vnc.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 {
|
options.hyperhive.icon = lib.mkOption {
|
||||||
type = lib.types.nullOr lib.types.path;
|
type = lib.types.nullOr lib.types.path;
|
||||||
default = null;
|
default = null;
|
||||||
|
|
|
||||||
|
|
@ -12,17 +12,6 @@ let
|
||||||
userName = config.hyperhive.user.name;
|
userName = config.hyperhive.user.name;
|
||||||
in
|
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 {
|
options.hyperhive.allowedRecipients = lib.mkOption {
|
||||||
type = lib.types.listOf lib.types.str;
|
type = lib.types.listOf lib.types.str;
|
||||||
default = [ ];
|
default = [ ];
|
||||||
|
|
@ -148,12 +137,6 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
config = {
|
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
|
# Auto-inject the built-in bash MCP server — always present, every
|
||||||
# agent needs bash tools. `lib.mkDefault` so the operator's own
|
# agent needs bash tools. `lib.mkDefault` so the operator's own
|
||||||
# agent.nix can override the entry. (The matrix sibling lives in
|
# agent.nix can override the entry. (The matrix sibling lives in
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue