deploy: move the swarm collector toggle

The one move where the suffix grep is the wrong instrument. There are two
otel options a word apart — `swarm.otel.enable` (one per swarm) and
`otel.enable` (one per hive, every hive runs it) — so `\.otel\.enable`
matches twenty-five references of which most must not change. The module
already carries a comment warning about exactly this, on a line that
names `swarm.otel` in full rather than through a binding.

Triaged by hand and confirmed the other way round: after the move, a grep
for the per-hive option still finds it in the files that should keep it.

Also worth recording what the alias sweep cannot do. `swarm.nix` reads
this as `swarmCfg.otel.enable`, where `swarmCfg = cfg.swarm` and `cfg =
config.services.hyperhive` — an alias bound to an alias, two hops from
the option path. No syntactic sweep resolves that chain, which is why the
module system's own evaluation is the only complete check here and the
static sweeps are a way to narrow the work, not to finish it.
This commit is contained in:
atlas 2026-08-30 03:35:23 +02:00 committed by mara
commit ba5ab313b3
10 changed files with 54 additions and 52 deletions

View file

@ -49,28 +49,13 @@ in
# Same precedence reasoning as ./local-defaults.nix: fills in for an
# operator who hasn't spoken, yields to one who has.
config.services.hyperhive.swarm = {
# The last one still spelled `swarm.*.enable`. Everything else that
# used to derive here — the queue, the SSO provider, the collector,
# the metrics pair, the log store — now derives below under
# `deploy.*`, because "does THIS host run it" is a per-host decision
# and `swarm.*` has to be identical on every host. Same switch, same
# rule, different attribute path.
matrix.enable = lib.mkDefault swarmCfg.enableRequiredServices;
# The queue. Added later than the two above and missed at the time —
# this file predates the `swarm-nats` container by nine days and had
# not been revisited since, so its absence was sequence rather than
# intent. It meets the rule in the option's own description exactly:
# once per swarm, and optional.
#
# The tell that it was an omission: `local-defaults.nix` already
# derives `nats.autoGenerateCallout` from the all-local mode, so that
# mode was minting the queue's callout nkeys and then never starting
# the queue they authenticate against.
# The metrics pair and the log store used to derive here too. They now
# live under `deploy.*` (below, and ./deploy.nix) because "does THIS
# host run it" is a per-host decision and `swarm.*` has to be identical
# on every host. Same switch, same rule, different attribute path.
# The collector that feeds the pair above, and the only tier holding
# the upstream credential. Same rule as the rest: once per swarm,
# optional, and a hive that is not the service host is a *client* of
# it (by name, `swarm.otel.domain`) rather than a second one.
otel.enable = lib.mkDefault swarmCfg.enableRequiredServices;
};
# The collector that feeds the pair above (note: no `swarm.` prefix,
@ -91,6 +76,11 @@ in
# The queue. Same rule: once per swarm, optional.
config.services.hyperhive.deploy.nats = lib.mkDefault swarmCfg.enableRequiredServices;
# The swarm collector that feeds the metrics pair, and the only tier
# holding the upstream credential. ⚠️ NOT the per-hive collector below,
# which every hive runs.
config.services.hyperhive.deploy.otel = lib.mkDefault swarmCfg.enableRequiredServices;
# The metrics pair, deriving together on purpose: a store with no UI is
# unreadable and a UI with no store is empty, so there is no sensible
# deployment that takes one and not the other from this switch. An