module-eval: pin which switch enables each swarm-wide service
`deploy.allSwarmServices` derives nine service enables and appeared nowhere in the check, so the tier a service sits on was prose only. The tenth, the swarm controller, already had this exact pair of cases — it rides `singleHostSwarm` instead, and swarm-ui follows the controller. Four cases: the switch turns its nine on, a hive that does not host them runs none, an operator placing one elsewhere still wins over the `mkDefault`, and hosting the shared services does not make a hive the swarm's control plane. The roster is counted before it is read: `lib.all` over an empty set holds vacuously, so a roster that lost a member would otherwise turn the case green by measuring nothing. Closes #4186
This commit is contained in:
parent
9a94fa08e3
commit
dd9e0bf0b0
1 changed files with 77 additions and 0 deletions
|
|
@ -453,8 +453,85 @@ let
|
||||||
in
|
in
|
||||||
builtins.foldl' (acc: v: builtins.seq v acc) true vals;
|
builtins.foldl' (acc: v: builtins.seq v acc) true vals;
|
||||||
|
|
||||||
|
# The swarm's shared services hosted HERE without the all-local mode — a
|
||||||
|
# services box with hives elsewhere, the shape ./host-modules/
|
||||||
|
# swarm-required-services.nix documents the switch for.
|
||||||
|
swarmServicesHere = hive { deploy.allSwarmServices = true; };
|
||||||
|
|
||||||
|
# Same, with one of those services placed on another host. Every derivation
|
||||||
|
# in that module is `mkDefault` so this stays expressible.
|
||||||
|
swarmServicesBaoElsewhere = hive {
|
||||||
|
deploy.allSwarmServices = true;
|
||||||
|
deploy.bao.enable = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
# The enables that switch owns. ⚠️ `otel` is the per-hive collector's own
|
||||||
|
# option and is NOT under `deploy` — spelled at the wrong path it would be
|
||||||
|
# undeclared rather than false, and a roster that quietly loses a member is
|
||||||
|
# what the count guard in the cases below exists to catch. Its membership
|
||||||
|
# here is deliberate and was the fix for a gap, not an oversight: the hive
|
||||||
|
# tier lands wherever the swarm services do.
|
||||||
|
swarmServiceEnables =
|
||||||
|
machine:
|
||||||
|
let
|
||||||
|
h = machine.services.hyperhive;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
matrix = h.deploy.matrix.enable;
|
||||||
|
otel = h.otel.enable;
|
||||||
|
authelia = h.deploy.authelia.enable;
|
||||||
|
nats = h.deploy.nats.enable;
|
||||||
|
swarm-otel = h.deploy.swarm-otel.enable;
|
||||||
|
victoriametrics = h.deploy.victoriametrics.enable;
|
||||||
|
grafana = h.deploy.grafana.enable;
|
||||||
|
victorialogs = h.deploy.victorialogs.enable;
|
||||||
|
bao = h.deploy.bao.enable;
|
||||||
|
};
|
||||||
|
|
||||||
# Each case: a name stating the property, and `ok`.
|
# Each case: a name stating the property, and `ok`.
|
||||||
cases = [
|
cases = [
|
||||||
|
{
|
||||||
|
# `lib.all` over an empty set holds vacuously, so the roster is counted
|
||||||
|
# before it is read: a helper that lost a member would otherwise turn
|
||||||
|
# this case green by measuring nothing.
|
||||||
|
name = "hosting the swarm's shared services turns on every service that switch owns";
|
||||||
|
ok =
|
||||||
|
let
|
||||||
|
es = swarmServiceEnables swarmServicesHere;
|
||||||
|
in
|
||||||
|
lib.length (lib.attrNames es) == 9 && lib.all lib.id (lib.attrValues es);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "a hive that does not host the swarm's shared services runs none of them";
|
||||||
|
ok =
|
||||||
|
let
|
||||||
|
es = swarmServiceEnables bare;
|
||||||
|
in
|
||||||
|
lib.length (lib.attrNames es) == 9 && !lib.any lib.id (lib.attrValues es);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
# The switch fills in for an operator who has not spoken and yields to
|
||||||
|
# one who has — that is what keeps a shared service placeable on a host
|
||||||
|
# of its own. A plain assignment or `mkForce` would satisfy both cases
|
||||||
|
# above and break this one. `nats` is the control: without it the case
|
||||||
|
# also passes on a fixture where nothing came on at all.
|
||||||
|
name = "placing one shared service elsewhere survives the switch that would enable it";
|
||||||
|
ok =
|
||||||
|
let
|
||||||
|
es = swarmServiceEnables swarmServicesBaoElsewhere;
|
||||||
|
in
|
||||||
|
!es.bao && es.nats;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
# The controller sits on the OTHER tier: `singleHostSwarm` places it
|
||||||
|
# (./host-modules/local-defaults.nix) and swarm-ui follows the
|
||||||
|
# controller. Pinned so that moving a service between tiers is a
|
||||||
|
# decision someone makes rather than a merge nobody reads.
|
||||||
|
name = "hosting the swarm's shared services does not make a hive the swarm's control plane";
|
||||||
|
ok =
|
||||||
|
!swarmServicesHere.services.hyperhive.deploy.swarm-controller.enable
|
||||||
|
&& !swarmServicesHere.services.hyperhive.deploy.swarm-ui.enable;
|
||||||
|
}
|
||||||
{
|
{
|
||||||
name = "a hive that has not opted into all-local runs no swarm controller";
|
name = "a hive that has not opted into all-local runs no swarm controller";
|
||||||
ok = !bare.services.hyperhive.deploy.swarm-controller.enable;
|
ok = !bare.services.hyperhive.deploy.swarm-controller.enable;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue