diff --git a/flake.nix b/flake.nix index 2d0b2f46..9e6d2ad4 100644 --- a/flake.nix +++ b/flake.nix @@ -142,10 +142,10 @@ agentBaseToplevel = lib.mkDefault self.packages.x86_64-linux.agent-base-toplevel; managerToplevel = lib.mkDefault self.packages.x86_64-linux.ruth-toplevel; }; - services.hyperhive.swarm.controller.package = + services.hyperhive.deploy.swarm-controller.package = lib.mkDefault self.packages.${pkgs.stdenv.hostPlatform.system}.swarm-controller; - services.hyperhive.swarm.controller.swarmctlPackage = + services.hyperhive.deploy.swarm-controller.swarmctlPackage = lib.mkDefault self.packages.${pkgs.stdenv.hostPlatform.system}.swarmctl; services.hyperhive.deploy.swarm-ui.package = diff --git a/nix/host-modules/deploy.nix b/nix/host-modules/deploy.nix index b1c36f90..45b1eade 100644 --- a/nix/host-modules/deploy.nix +++ b/nix/host-modules/deploy.nix @@ -381,6 +381,17 @@ in [ "services" "hyperhive" "swarm" "authelia" "bridgePackage" ] [ "services" "hyperhive" "deploy" "authelia" "bridgePackage" ] ) + # ⚠️ `swarm-controller`, not `hive-controller` — see the note in + # ./swarm-controller.nix. Both namespaces exist, so the wrong target here + # lands on a live option in hive-c0re's tree instead of failing. + (lib.mkRenamedOptionModule + [ "services" "hyperhive" "swarm" "controller" "package" ] + [ "services" "hyperhive" "deploy" "swarm-controller" "package" ] + ) + (lib.mkRenamedOptionModule + [ "services" "hyperhive" "swarm" "controller" "swarmctlPackage" ] + [ "services" "hyperhive" "deploy" "swarm-controller" "swarmctlPackage" ] + ) ]; # ⚠️ `deploy.forgejo` is declared in ./hive-ci.nix, not here, and it is the diff --git a/nix/host-modules/swarm-controller.nix b/nix/host-modules/swarm-controller.nix index c9a939e5..29d445ec 100644 --- a/nix/host-modules/swarm-controller.nix +++ b/nix/host-modules/swarm-controller.nix @@ -196,7 +196,7 @@ let # config back to it — and to get it wrong the day one of them changes. swarmctlConfigured = pkgs.symlinkJoin { name = "swarmctl-configured"; - paths = [ cfg.swarmctlPackage ]; + paths = [ deployCfg.swarm-controller.swarmctlPackage ]; nativeBuildInputs = [ pkgs.makeWrapper ]; postBuild = '' wrapProgram $out/bin/swarmctl ${ @@ -243,30 +243,8 @@ in # asserts it, and that was never an exception to "not derived from # services.hyperhive.enable": that mode says "this box is the whole # deployment", which answers the topology question outright, where - # `enable` alone never can. What stays here is what the daemon IS. - - package = lib.mkOption { - type = lib.types.package; - defaultText = lib.literalExpression "hyperhive.packages.\${system}.swarm-controller"; - description = '' - swarm-controller package. Wired by default from this flake's own - package set (see `flake.nix`); override to run a different build. - ''; - }; - - swarmctlPackage = lib.mkOption { - type = lib.types.package; - defaultText = lib.literalExpression "hyperhive.packages.\${system}.swarmctl"; - description = '' - `swarmctl` package — the swarm operator's CLI, installed on this - host alongside the daemon and wrapped with the paths it needs. - - A separate option from `package` rather than a second binary in - the same derivation: the CLI runs as root and acts directly, - the daemon runs unprivileged and serves a socket, and pinning one - without the other is a thing an operator may legitimately want. - ''; - }; + # `enable` alone never can. Both packages moved to that same + # `deploy.swarm-controller` block. What stays here is what the daemon IS. staleAfterSeconds = lib.mkOption { type = lib.types.ints.positive; @@ -371,16 +349,39 @@ in }; # What stays above is what the controller IS to the swarm: the quick-links - # it publishes, the client id it is registered under, how stale a snapshot - # may read, and its packages. What the host running it decides is here — - # where its socket lives, and the three credentials it reads off local - # disk. `enable` already lives in ./deploy.nix, which also carries the - # renames. + # it publishes, the client id it is registered under, and how stale a + # snapshot may read. What the host running it decides is here — which two + # builds it runs, where its socket lives, and the three credentials it reads + # off local disk. `enable` already lives in ./deploy.nix, which also carries + # the renames. # # ⚠️ `deploy.swarm-controller`, NOT `deploy.hive-controller`. Both exist: # the latter is hive-c0re's namespace, where `tls.*` lives. A definition on # the wrong one lands on a live, unrelated option rather than failing. options.services.hyperhive.deploy.swarm-controller = { + package = lib.mkOption { + type = lib.types.package; + defaultText = lib.literalExpression "hyperhive.packages.\${system}.swarm-controller"; + description = '' + swarm-controller package. Wired by default from this flake's own + package set (see `flake.nix`); override to run a different build. + ''; + }; + + swarmctlPackage = lib.mkOption { + type = lib.types.package; + defaultText = lib.literalExpression "hyperhive.packages.\${system}.swarmctl"; + description = '' + `swarmctl` package — the swarm operator's CLI, installed on this + host alongside the daemon and wrapped with the paths it needs. + + A separate option from `package` rather than a second binary in + the same derivation: the CLI runs as root and acts directly, + the daemon runs unprivileged and serves a socket, and pinning one + without the other is a thing an operator may legitimately want. + ''; + }; + socketPath = lib.mkOption { type = lib.types.str; default = "/run/swarm-controller/controller.sock"; @@ -591,7 +592,7 @@ in after = [ "network.target" ]; serviceConfig = { - ExecStart = "${cfg.package}/bin/swarm-controller"; + ExecStart = "${deployCfg.swarm-controller.package}/bin/swarm-controller"; # The two differ on purpose. The queue credential is # unconditional — the assertions above make its path a value that diff --git a/nix/host-modules/swarm-ui.nix b/nix/host-modules/swarm-ui.nix index c7c7aac1..f50b3eff 100644 --- a/nix/host-modules/swarm-ui.nix +++ b/nix/host-modules/swarm-ui.nix @@ -90,7 +90,7 @@ in controller's own API. Wired by default from this flake's own package set (see - `flake.nix`), the same way `swarm.controller.package` is. There + `flake.nix`), the same way `deploy.swarm-controller.package` is. There is deliberately **no overlay** in this project, so a `pkgs.swarm-ui` default here would name an attribute that does not exist on any real deployment. diff --git a/nix/module-eval.nix b/nix/module-eval.nix index 71598d6a..8e2e3ad7 100644 --- a/nix/module-eval.nix +++ b/nix/module-eval.nix @@ -153,8 +153,12 @@ let deploy.matrix.maxRequestSize = 99000000; }; + # `enable` is spelled the OLD way like everything else here, so all seven + # of the controller's shims are exercised rather than six. controllerOldPath = hive { - deploy.swarm-controller.enable = true; + swarm.controller.enable = true; + swarm.controller.package = pkgs.emptyDirectory; + swarm.controller.swarmctlPackage = pkgs.emptyDirectory; swarm.controller.socketPath = "/run/test-ctrl/ctrl.sock"; swarm.controller.forgeTokenFile = "/run/secrets/ctrl-forge.token"; swarm.controller.authBridgeUrl = "http://127.0.0.1:19097";