nix: split module-eval into per-subsystem checks
The single module-eval derivation forced ~62 full nixosSystem fixtures live at once to compute its cases list: 10.6GB peak RSS / 5m25s to evaluate, by far the dominant cost in nix flake check. Splits it into 21 independent checks.module-eval-* derivations (1-7 fixtures each) sharing builders/helpers via module-eval/lib.nix, so no single derivation needs more than a handful of fixtures live at once. A few cases spanning two clusters carry a small duplicated fixture rather than threading shared state through lib.nix.
This commit is contained in:
parent
69b70a9c6f
commit
dc418a5223
24 changed files with 3760 additions and 2997 deletions
121
nix/module-eval/nats-authelia.nix
Normal file
121
nix/module-eval/nats-authelia.nix
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
# `checks.module-eval-nats-authelia` — see ./lib.nix for the shared
|
||||
# rationale (why this suite exists, naming convention, "evaluates
|
||||
# not executes").
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
self,
|
||||
nixosSystem,
|
||||
}:
|
||||
let
|
||||
inherit
|
||||
(import ./lib.nix {
|
||||
inherit
|
||||
pkgs
|
||||
lib
|
||||
self
|
||||
nixosSystem
|
||||
;
|
||||
})
|
||||
hive
|
||||
runGroup
|
||||
;
|
||||
|
||||
# The queue's callout identity, fourth split slice. `autoGenerateCallout` is
|
||||
# left FALSE on purpose: that is what makes the seed paths the thing deciding
|
||||
# `responderConfigured`, so the assertion below is about the seeds rather
|
||||
# than about the auto-mint branch. Every one of the seven old paths is
|
||||
# defined — `enable` included, which is why it is spelled the old way here
|
||||
# while the fixture below uses the new one — so dropping any single nats
|
||||
# shim fails the eval, not just the arms read.
|
||||
natsOldPath = hive {
|
||||
swarm.nats.enable = true;
|
||||
swarm.nats.autoGenerateCallout = false;
|
||||
swarm.nats.calloutUserPublicKey = "UTESTUSERPUBKEYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
|
||||
swarm.nats.calloutIssuerPublicKey = "ATESTISSUERPUBKEYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
|
||||
swarm.nats.calloutUserSeedFile = "/run/secrets/nats-user.seed";
|
||||
swarm.nats.calloutIssuerSeedFile = "/run/secrets/nats-issuer.seed";
|
||||
swarm.nats.authPackage = pkgs.emptyDirectory;
|
||||
};
|
||||
|
||||
# Seventh split slice, plus slice 10's two authelia packages. Of slice 7's
|
||||
# movers only `usersFile` has a rename entry — the other two are `readOnly`,
|
||||
# and a rename module contributes a definition, which a read-only option
|
||||
# refuses; see ./host-modules/deploy.nix. `package` and `bridgePackage` are
|
||||
# ordinary options, so they do carry one. The two arms
|
||||
# below have different jobs. `usersFile` tests the rename; the nats one tests
|
||||
# that a reader repointed to the new namespace still renders the derived
|
||||
# path, which is the failure this slice could actually have shipped — seven
|
||||
# of those reads went through an alias a path-shaped grep cannot see.
|
||||
autheliaOldPath = hive {
|
||||
deploy.authelia.enable = true;
|
||||
deploy.nats.enable = true;
|
||||
swarm.authelia.usersFile = "/var/lib/test-authelia/users.yml";
|
||||
swarm.authelia.package = pkgs.emptyDirectory;
|
||||
swarm.authelia.bridgePackage = pkgs.emptyDirectory;
|
||||
swarm.nats.autoGenerateCallout = false;
|
||||
swarm.nats.calloutUserPublicKey = "UTESTUSERPUBKEYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
|
||||
swarm.nats.calloutIssuerPublicKey = "ATESTISSUERPUBKEYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
|
||||
swarm.nats.calloutUserSeedFile = "/run/secrets/nats-user.seed";
|
||||
swarm.nats.calloutIssuerSeedFile = "/run/secrets/nats-issuer.seed";
|
||||
};
|
||||
cases = [
|
||||
{
|
||||
# Reads the RENDERED settings, not the option: `calloutBlocks {…} // {
|
||||
# … }` is a shallow merge, and a future edit that dropped or shadowed
|
||||
# this key would still evaluate cleanly — the only reader that would
|
||||
# notice is a publisher whose row exceeds upstream's much smaller
|
||||
# default, and by then it is a dropped row, not an eval failure.
|
||||
# Piggybacks on the pre-rename nats fixture above, which already
|
||||
# renders this container's full config.
|
||||
name = "the queue's payload ceiling is set, not inherited from the server's default";
|
||||
ok = natsOldPath.containers.swarm-nats.config.services.nats.settings.max_payload == 8388608;
|
||||
}
|
||||
{
|
||||
# Reads the RENDERED unit text, not the module's source, because the
|
||||
# failure this defends against renders perfectly: systemd substitutes
|
||||
# `$NAME` in `ExecStart` regardless of quoting, so a single dollar
|
||||
# here hands the responder `.term.{hive}.>` — a grant that parses, is
|
||||
# accepted, and matches nothing an agent ever publishes to. Asserting
|
||||
# the doubled dollar is the only way to tell the two apart before
|
||||
# deploy. The flag's presence is asserted separately so that dropping
|
||||
# the grant entirely fails as its own arm rather than as an escaping
|
||||
# complaint.
|
||||
name = "the responder grants agents their hive's terminal subject, and the dollar survives systemd";
|
||||
ok =
|
||||
let
|
||||
exec =
|
||||
natsOldPath.containers.swarm-nats.config.systemd.services.swarm-nats-auth.serviceConfig.ExecStart;
|
||||
in
|
||||
lib.hasInfix "--agent-publish-subject " exec && lib.hasInfix "$$SWARM.term.{hive}.>" exec;
|
||||
}
|
||||
{
|
||||
# Second grant, same escaping trap, asserted separately: the two
|
||||
# subject families are independent features (terminal rows and the
|
||||
# turn-state header) and dropping either should fail as its own arm
|
||||
# rather than being masked by the other still being present.
|
||||
#
|
||||
# Flag and argument are matched as one infix rather than as two
|
||||
# independent `hasInfix` calls: the responder takes the flag
|
||||
# repeatedly, so the thing worth pinning is that THIS subject is the
|
||||
# argument of one of them, which two separate presence checks would
|
||||
# both pass on while the subject sat under some other flag entirely.
|
||||
name = "the responder grants agents their hive's agent-state subject too";
|
||||
ok =
|
||||
let
|
||||
exec =
|
||||
natsOldPath.containers.swarm-nats.config.systemd.services.swarm-nats-auth.serviceConfig.ExecStart;
|
||||
in
|
||||
lib.hasInfix "--agent-publish-subject '$$SWARM.agent-state.{hive}.>'" exec;
|
||||
}
|
||||
{
|
||||
# Not a rename test. `hostClientSecretDir` is `readOnly`, so the fixture
|
||||
# cannot define it; what can break is a reader left pointing at the
|
||||
# namespace it moved out of. Five modules read this through an
|
||||
# `autheliaCfg` alias, where a path-shaped grep does not see it.
|
||||
name = "a consumer of authelia's host client-secret dir renders it from the deploy namespace";
|
||||
ok = lib.hasInfix "/var/lib/nixos-containers/swarm-authelia/var/lib/authelia-swarm/oidc-clients/" autheliaOldPath.systemd.services.swarm-nats-auth-secrets.script;
|
||||
}
|
||||
];
|
||||
in
|
||||
runGroup "nats-authelia" cases
|
||||
Loading…
Reference in a new issue