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.
121 lines
5.8 KiB
Nix
121 lines
5.8 KiB
Nix
# `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
|