diff --git a/docs/swarm/ui.md b/docs/swarm/ui.md index 09926687..06cd4ad4 100644 --- a/docs/swarm/ui.md +++ b/docs/swarm/ui.md @@ -337,7 +337,8 @@ Where each credential lives and who reads it: services.hyperhive.deploy.swarm-controller.enable = true; # the UI comes with it ``` -The UI has no switch of its own, and doesn't follow `allSwarmServices`: +The UI has no switch of its own (setting `deploy.swarm-ui.enable` or +`swarm.ui.enable` has no effect, and warns at evaluation), and doesn't follow `allSwarmServices`: the UI is a view onto the controller's state and reaches it over that daemon's socket, so the host that runs the controller is the host that can serve the UI. A hive that merely _uses_ a swarm has nothing to serve. diff --git a/nix/host-modules/deploy.nix b/nix/host-modules/deploy.nix index bfa5a83c..0b9b460b 100644 --- a/nix/host-modules/deploy.nix +++ b/nix/host-modules/deploy.nix @@ -28,13 +28,23 @@ # spread across the service modules, so all of them have a single home # and a single file to delete when the deprecation window closes — the # shape ./swarm-peers-removed.nix already uses. -{ lib, ... }: +{ config, lib, ... }: let - # Shared by the two removed spellings of the swarm UI's own switch below. - swarmUiSwitchRemoved = '' - swarm-ui now runs wherever swarm-controller runs. Remove this - definition; services.hyperhive.deploy.swarm-controller.enable decides it. - ''; + # The swarm UI's own switch, in both spellings. Accepted and ignored: a + # definition only produces a warning, so a host that still sets one keeps + # evaluating. `null` is "not set". + swarmUiSwitchIgnored = lib.mkOption { + type = lib.types.nullOr lib.types.bool; + default = null; + visible = false; + description = '' + No effect. swarm-ui runs wherever swarm-controller runs. + ''; + }; + swarmUiSwitchWarning = + path: value: + lib.optional (value != null) + "services.hyperhive.${path} no longer has any effect: swarm-ui now runs wherever swarm-controller runs. Remove this setting; services.hyperhive.deploy.swarm-controller.enable decides it."; # Shared by the two removed spellings of the status-publishing secret below. statusSecretRemoved = '' @@ -98,20 +108,6 @@ in be deleted. '' ) - (lib.mkRemovedOptionModule [ - "services" - "hyperhive" - "swarm" - "ui" - "enable" - ] swarmUiSwitchRemoved) - (lib.mkRemovedOptionModule [ - "services" - "hyperhive" - "deploy" - "swarm-ui" - "enable" - ] swarmUiSwitchRemoved) (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "authelia" "enable" ] [ "services" "hyperhive" "deploy" "authelia" "enable" ] @@ -451,7 +447,7 @@ in [ "services" "hyperhive" "deploy" "victoriametrics" "package" ] ) # With this one `services.hyperhive.swarm.ui` holds nothing at all: its - # `enable` is removed above and its `package` is renamed here. + # `enable` is an ignored switch (declared below) and its `package` is renamed here. (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "ui" "package" ] [ "services" "hyperhive" "deploy" "swarm-ui" "package" ] @@ -490,7 +486,14 @@ in # ⚠️ Only `deploy.forgejo.enable` is declared here. The rest of # `deploy.forgejo` is in ./hive-forge/default.nix: the knobs live with the # module that reads them; this file stays the registry of toggles. + options.services.hyperhive.swarm.ui.enable = swarmUiSwitchIgnored; + + config.warnings = + swarmUiSwitchWarning "deploy.swarm-ui.enable" config.services.hyperhive.deploy.swarm-ui.enable + ++ swarmUiSwitchWarning "swarm.ui.enable" config.services.hyperhive.swarm.ui.enable; + options.services.hyperhive.deploy = { + swarm-ui.enable = swarmUiSwitchIgnored; forgejo.enable = lib.mkOption { type = lib.types.bool; default = false; diff --git a/nix/module-eval/swarm-services-switch.nix b/nix/module-eval/swarm-services-switch.nix index d7be255b..96182176 100644 --- a/nix/module-eval/swarm-services-switch.nix +++ b/nix/module-eval/swarm-services-switch.nix @@ -75,8 +75,8 @@ let # saying "it is not there" would hold just as well if it were never there. # Package stubbed per this file's header: the vhost roots at it. # - # Also sets both removed UI switches to `false`: the vhost must render - # regardless, and each must fail evaluation through its assertion. Neither + # Also sets both ignored UI switches to `false`: the vhost must render + # regardless, and each must evaluate and warn. Neither # is read anywhere else, so they change nothing the other arms see. swarmUiHere = hive { deploy.swarm-controller.enable = true; @@ -245,24 +245,23 @@ let ok = swarmUiHere.services.nginx.virtualHosts ? "t.local"; } { - # Control: `swarmServicesHere` sets neither removed switch. - name = "a definition of a removed swarm UI switch fails evaluation, naming the option and the controller"; + # Control: `swarmServicesHere` sets neither ignored switch. + name = "a definition of an ignored swarm UI switch evaluates and warns, naming the option and the controller"; ok = let - refused = + warned = m: path: lib.any ( - a: - !a.assertion - && lib.hasInfix "services.hyperhive.${path}" a.message - && lib.hasInfix "swarm-ui now runs wherever swarm-controller runs" a.message - ) m.assertions; + w: + lib.hasInfix "services.hyperhive.${path} no longer has any effect" w + && lib.hasInfix "swarm-ui now runs wherever swarm-controller runs" w + ) m.warnings; paths = [ "deploy.swarm-ui.enable" "swarm.ui.enable" ]; in - lib.all (refused swarmUiHere) paths && !(lib.any (refused swarmServicesHere) paths); + lib.all (warned swarmUiHere) paths && !(lib.any (warned swarmServicesHere) paths); } { # The swarm-services toggle enables them explicitly, from its own