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

@ -29,11 +29,11 @@
}:
let
cfg = config.services.hyperhive.swarm.otel;
deployCfg = config.services.hyperhive.deploy;
swarmCfg = config.services.hyperhive.swarm;
otelCfg = config.services.hyperhive.otel;
vmCfg = config.services.hyperhive.swarm.victoriametrics;
vlCfg = config.services.hyperhive.swarm.victorialogs;
deployCfg = config.services.hyperhive.deploy;
hyperhiveCfg = config.services.hyperhive;
gatewayCfg = hyperhiveCfg.gateway;
swarmDomain = hyperhiveCfg.swarm.domain;
@ -179,23 +179,11 @@ let
collectLogs = logExporterNames != [ ];
in
{
# `enable` moved to `services.hyperhive.deploy.otel` — see ./deploy.nix.
# ⚠️ That is the SWARM collector. The per-hive one keeps its own
# `services.hyperhive.otel.enable` (./otel.nix) and is a different
# option entirely — every hive runs that one.
options.services.hyperhive.swarm.otel = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Run the swarm's telemetry collector on this host.
Asserted from `swarm.enableRequiredServices` in
./swarm-required-services.nix, with the metrics pair this
collector feeds: a swarm has one of these, and it belongs
wherever the shared services live rather than on every hive.
A hive that does not run it still runs its own hive-tier collector
(`services.hyperhive.otel.enable`) and reaches this one by name, at
{option}`services.hyperhive.swarm.otel.domain`.
'';
};
machine = lib.mkOption {
type = lib.types.str;
@ -446,8 +434,8 @@ in
};
};
config = lib.mkIf (config.services.hyperhive.enable && cfg.enable) {
# The gateway name, inside `cfg.enable` — that guard is the load-bearing
config = lib.mkIf (config.services.hyperhive.enable && deployCfg.otel) {
# The gateway name, inside `deployCfg.otel` — that guard is the load-bearing
# part. Every hive in a swarm may know this collector exists, but only
# the host that RUNS it may claim the name; a client hive declaring the
# vhost would answer for a service it does not have.
@ -612,7 +600,7 @@ in
# samples and drops them — which looks healthy and loses data.
assertion = otelCfg.endpoint != "" || deployCfg.victoriametrics;
message = ''
services.hyperhive.swarm.otel.enable is true but this collector
services.hyperhive.deploy.otel is true but this collector
has nowhere to send what it receives:
services.hyperhive.otel.endpoint is empty and
services.hyperhive.deploy.victoriametrics is false.
@ -644,7 +632,7 @@ in
# collector would listen on nothing while looking configured.
assertion = hyperhiveCfg.swarm.hives != { };
message = ''
services.hyperhive.swarm.otel.enable is true but
services.hyperhive.deploy.otel is true but
services.hyperhive.swarm.hives is empty: ingest is authenticated
per hive, so an empty roster means this collector accepts nothing
from anyone.
@ -756,7 +744,7 @@ in
# issuer URL evaluates cleanly and refuses every hive at runtime.
assertion = autheliaCfg.url != null;
message = ''
services.hyperhive.swarm.otel.enable is true but
services.hyperhive.deploy.otel is true but
services.hyperhive.swarm.authelia.url is null: every hive
authenticates to this collector as itself, and the token comes
from the swarm's identity provider.