nix: run the forge on one host per swarm (deploy.forgejo.enable)

Every hive with hyperhive enabled ran its own hive-forge container, and
its gateway answered forge.<swarm> with its own bridge IP, so on a
multi-host swarm each hive talked to its own forge.

deploy.forgejo.enable defaults to false and allSwarmServices sets it with
mkDefault, like authelia and bao; singleHostSwarm gets it through that.
The forge's OIDC client moves to a glue module gated on authelia, so a
split authelia/forge swarm still registers it. CI now requires the forge
on the same host, and the controller's forgeTokenFile defaults to null
where the forge is not.

Closes #4705
Refs #3782
This commit is contained in:
atlas 2026-09-24 19:44:04 +02:00 • committed by mara
commit 978164dc53
15 changed files with 346 additions and 84 deletions

View file

@ -46,7 +46,11 @@ let
# only hive without one is a hive told to have none.
noAgentQueue = hive { deploy.hive-controller.queue.agentNatsUrl = null; };
withCi = hive { deploy.forgejo.ci.enable = true; };
# On the forge's host: the runner is refused anywhere else.
withCi = hive {
deploy.forgejo.enable = true;
deploy.forgejo.ci.enable = true;
};
# A priority collision is a property of the *option*, not
# of the merged value's interior — nix throws the moment the value is
@ -90,16 +94,16 @@ let
(hive { deploy.forgejo.behindGateway = false; }).services.hyperhive.swarm.forge.publicUrl == null;
}
{
# The controller's token path defaulted to forge's delivery path only on
# a host with the central toggle on, and to `null` otherwise. Forge
# deploys unconditionally, so the path is now unconditional too.
name = "the swarm controller's forgeTokenFile defaults to forge's delivery path regardless of the central toggle";
# The controller's token path follows where the forge runs
# (./forge-placement.nix), never the central toggle: a forge host with
# the toggle off still renders the path.
name = "the swarm controller's forgeTokenFile default does not consult the central toggle";
ok =
let
forgePath = "/var/lib/hyperhive-forge/swarm-controller.token";
in
bare.services.hyperhive.deploy.swarm-controller.forgeTokenFile == forgePath
&& centralToggleOff.services.hyperhive.deploy.swarm-controller.forgeTokenFile == forgePath;
(hive {
enable = false;
deploy.forgejo.enable = true;
}).services.hyperhive.deploy.swarm-controller.forgeTokenFile
== "/var/lib/hyperhive-forge/swarm-controller.token";
}
{
name = "a hive that does not host the swarm's shared services runs none of them";