diff --git a/nix/module-eval/hive-otel.nix b/nix/module-eval/hive-otel.nix index 42941877..93554ef0 100644 --- a/nix/module-eval/hive-otel.nix +++ b/nix/module-eval/hive-otel.nix @@ -232,6 +232,29 @@ let && lib.hasInfix "ActiveEnterTimestamp" s && lib.hasInfix ''if [ "$written_us" -le "$started_us" ]; then'' s; } + { + # On a first boot the file does not exist until the fetch succeeds, so + # the collector fails `LoadCredential` into its start limit, i.e. the + # `failed` state. Only `reset-failed` clears that limit, so the fetch + # has to reset before it starts; `try-restart` acts on no failed unit. + # A never-active collector has an empty `ActiveEnterTimestamp`, read as + # 0, so the file always counts as newer. The collector only `wants` the + # fetch, so an unreachable store does not hold it back. + name = "the hive collector's fetch revives a collector that hit its start limit without the file"; + ok = + let + s = builtins.unsafeDiscardStringContext (hiveOtelFetch hiveOtelLeaf).script; + c = hiveOtelLeaf.systemd.services.opentelemetry-collector; + failedArm = lib.last (lib.splitString ''is-failed --quiet "$unit"; then'' s); + in + lib.hasInfix ''is-failed --quiet "$unit"; then'' s + && lib.hasInfix ''reset-failed "$unit"'' failedArm + && lib.hasInfix ''start --no-block "$unit"'' ( + lib.last (lib.splitString ''reset-failed "$unit"'' failedArm) + ) + && lib.hasInfix "started_us=0" s + && !(builtins.elem "swarm-bao-hive-otel-oidc.service" (c.requires or [ ])); + } { # The store is the one route, on the IdP's own host too: no default into # authelia's tree and no unit waiting for a file to appear there.