Watch
0
0
Fork
You've already forked hyperhive
0

hive otel: keep file_storage defined when the collector authenticates upstream

The hive collector's `settings` was `{ extensions.file_storage = …; … }
// lib.optionalAttrs senderAuth { extensions.oauth2client/swarm = …; }`.
`//` is shallow, so whenever senderAuth held (every valid hive config)
the right-hand `extensions` replaced the left one and `file_storage`
vanished, while `service.extensions` still listed it. `otelcol validate`
then failed the config.yaml build:

  Error: service::extensions: references extension "file_storage" which is not configured

Broken by 02831fb5e (PR #5178), which added `extensions.file_storage`
to the left-hand attrset; the `//` block for the auth extension predates
it (cb787997bd). Both extensions now live in one `extensions` attrset.

module-eval-hive-otel gains a case that every name in
`service.extensions` is defined under `extensions`; it evaluates false
on the parent commit and true here.

Fixes #5240
This commit is contained in:
atlas 2026-10-14 02:23:15 +02:00 • committed by mara
commit 38ee68c31d
2 changed files with 46 additions and 31 deletions

View file

@ -401,19 +401,42 @@ in
# prove this config STARTS, never mind that a sample arrives.
validateConfigFile = true;
settings = {
# The journald receiver's cursor store, same shape as the agent
# tier's own (`nix/agent-modules/otel.nix`): a restart resumes
# from the last-read position instead of re-reading from the
# journal's tail (silently dropping whatever landed while the
# collector was down) or its head (re-sending everything).
# `create_directory` matters at BUILD time: `validateConfigFile`
# runs `otelcol validate` in the nix sandbox, where systemd's
# `StateDirectory=` has never run and the path does not exist
# yet — without it the validator refuses with "directory must
# exist".
extensions.file_storage = {
directory = "/var/lib/opentelemetry-collector";
create_directory = true;
# Every extension is defined in this one attrset: a second
# `extensions` joined onto `settings` with `//` replaces this one
# instead of adding to it.
extensions = {
# The journald receiver's cursor store, same shape as the agent
# tier's own (`nix/agent-modules/otel.nix`): a restart resumes
# from the last-read position instead of re-reading from the
# journal's tail (silently dropping whatever landed while the
# collector was down) or its head (re-sending everything).
# `create_directory` matters at BUILD time: `validateConfigFile`
# runs `otelcol validate` in the nix sandbox, where systemd's
# `StateDirectory=` has never run and the path does not exist
# yet — without it the validator refuses with "directory must
# exist".
file_storage = {
directory = "/var/lib/opentelemetry-collector";
create_directory = true;
};
}
// lib.optionalAttrs senderAuth {
${authName} = {
client_id = hiveClient;
# A real key, measured against this collector version rather
# than assumed — with a deliberate typo rejected in the same
# run, so "accepted" is distinguishable from "ignores
# everything". Keeps the secret out of nix entirely: the
# collector opens the file itself.
client_secret_file = "\${env:CREDENTIALS_DIRECTORY}/${credName}";
token_url = "${toString autheliaCfg.url}/api/oidc/token";
# ⚠️ THE AUDIENCE HAS TO BE REQUESTED, not merely granted.
# Registering it on the client only makes it permissible; a
# token minted without asking carries `aud: []` and every
# receiver refuses it — with a config that reads perfectly at
# both ends. Measured against authelia 4.39.20.
endpoint_params.audience = hiveClient;
};
};
receivers = {
@ -676,24 +699,6 @@ in
};
}
];
}
// lib.optionalAttrs senderAuth {
extensions.${authName} = {
client_id = hiveClient;
# A real key, measured against this collector version rather
# than assumed — with a deliberate typo rejected in the same
# run, so "accepted" is distinguishable from "ignores
# everything". Keeps the secret out of nix entirely: the
# collector opens the file itself.
client_secret_file = "\${env:CREDENTIALS_DIRECTORY}/${credName}";
token_url = "${toString autheliaCfg.url}/api/oidc/token";
# ⚠️ THE AUDIENCE HAS TO BE REQUESTED, not merely granted.
# Registering it on the client only makes it permissible; a
# token minted without asking carries `aud: []` and every
# receiver refuses it — with a config that reads perfectly at
# both ends. Measured against authelia 4.39.20.
endpoint_params.audience = hiveClient;
};
};
};

View file

@ -111,6 +111,16 @@ let
!(builtins.elem "deltatocumulative" hiveOtelPipelines.logs.processors)
&& builtins.elem "deltatocumulative" hiveOtelPipelines.metrics.processors;
}
{
# `otelcol validate` refuses a `service.extensions` entry with no
# definition, and that runs when the unit is built, not in this suite.
# `hiveOtel` authenticates upstream, so both extensions are listed;
# the length clause keeps the check from passing on an empty list.
name = "the hive collector defines every extension its service lists";
ok =
lib.length hiveOtelSettings.service.extensions == 2
&& lib.all (e: hiveOtelSettings.extensions ? ${e}) hiveOtelSettings.service.extensions;
}
{
# The counters that say telemetry is being LOST — refused, failed,
# queue depth — are served on loopback and reach no store unless