deploy: give every option an enable, and name the controller one
Two corrections from review, applied forward on this branch rather than
by rewriting it.
`deploy.<service>` was a bare bool, which makes
`deploy.forgejo = { enable; ci; }` unrepresentable -- the nested
CI-runner sub-option this namespace was designed around. Every entry is
now an attrset with an `enable`, so a second per-host deployment
decision becomes an ordinary addition rather than a migration.
`deploy.controller` is now `deploy.swarm-controller`, consistent with
`deploy.swarm-ui`, which was introduced in the same commit.
89 references rewritten across 24 files -- nix, Rust, docs, and the
repo's own CLAUDE.md.
The prefix-anchored sweep missed exactly one, and it was live code:
hive-tls.nix spells it `hyperhiveCfg.deploy.controller` -- the only
`hyperhiveCfg` prefix among 45 references. A suffix grep
(`\.deploy\.<name>`) finds it; a path-anchored one cannot, because the
head of a reference is whatever alias the reading file happens to bind.
This commit is contained in:
parent
ba5ab313b3
commit
d3b40da1c8
24 changed files with 137 additions and 121 deletions
|
|
@ -164,13 +164,14 @@ let
|
|||
# Written once because "which exporters" is a property of this tier, not
|
||||
# of which hive a sample came from.
|
||||
exporterNames =
|
||||
upstreamExporters ++ lib.optional deployCfg.victoriametrics "otlphttp/victoriametrics";
|
||||
upstreamExporters ++ lib.optional deployCfg.victoriametrics.enable "otlphttp/victoriametrics";
|
||||
|
||||
# The same fan-out for logs, and the local store is only ONE of its
|
||||
# destinations. A deployment that turns the swarm's log store off and keeps
|
||||
# an upstream endpoint still collects — the store is where logs may be kept,
|
||||
# not the reason to read the journal at all.
|
||||
logExporterNames = upstreamExporters ++ lib.optional deployCfg.victorialogs "otlphttp/victorialogs";
|
||||
logExporterNames =
|
||||
upstreamExporters ++ lib.optional deployCfg.victorialogs.enable "otlphttp/victorialogs";
|
||||
|
||||
# Collect when there is anywhere to send it, and only then. A pipeline with
|
||||
# an empty exporter list is not a quiet no-op — the collector rejects it —
|
||||
|
|
@ -179,7 +180,7 @@ let
|
|||
collectLogs = logExporterNames != [ ];
|
||||
in
|
||||
{
|
||||
# `enable` moved to `services.hyperhive.deploy.otel` — see ./deploy.nix.
|
||||
# `enable` moved to `services.hyperhive.deploy.otel.enable` — 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.
|
||||
|
|
@ -434,8 +435,8 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf (config.services.hyperhive.enable && deployCfg.otel) {
|
||||
# The gateway name, inside `deployCfg.otel` — that guard is the load-bearing
|
||||
config = lib.mkIf (config.services.hyperhive.enable && deployCfg.otel.enable) {
|
||||
# The gateway name, inside `deployCfg.otel.enable` — 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.
|
||||
|
|
@ -505,7 +506,7 @@ in
|
|||
# declaration would break every hive that runs a collector and
|
||||
# publishes nothing.
|
||||
services.hyperhive.swarm.authelia.oidc.clients =
|
||||
lib.mkIf (deployCfg.authelia && cfg.publishedScrapeTargets != { })
|
||||
lib.mkIf (deployCfg.authelia.enable && cfg.publishedScrapeTargets != { })
|
||||
[
|
||||
{
|
||||
id = cfg.clientId;
|
||||
|
|
@ -543,7 +544,7 @@ in
|
|||
# after it. On a fresh swarm that is a permanent stall presenting as
|
||||
# "metrics are broken", several layers from its cause.
|
||||
systemd.services.swarm-otel-oidc-secret =
|
||||
lib.mkIf (deployCfg.authelia && cfg.publishedScrapeTargets != { })
|
||||
lib.mkIf (deployCfg.authelia.enable && cfg.publishedScrapeTargets != { })
|
||||
{
|
||||
description = "deliver the swarm collector's OIDC client secret from authelia";
|
||||
after = [ "container@${autheliaCfg.machine}.service" ];
|
||||
|
|
@ -598,12 +599,12 @@ in
|
|||
# The tier exists to hold the upstream credential and to write the
|
||||
# swarm's store. With neither, it is a process that receives
|
||||
# samples and drops them — which looks healthy and loses data.
|
||||
assertion = otelCfg.endpoint != "" || deployCfg.victoriametrics;
|
||||
assertion = otelCfg.endpoint != "" || deployCfg.victoriametrics.enable;
|
||||
message = ''
|
||||
services.hyperhive.deploy.otel is true but this collector
|
||||
services.hyperhive.deploy.otel.enable 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.
|
||||
services.hyperhive.deploy.victoriametrics.enable is false.
|
||||
|
||||
Set the endpoint to export upstream, or enable the swarm's
|
||||
metrics store.
|
||||
|
|
@ -632,7 +633,7 @@ in
|
|||
# collector would listen on nothing while looking configured.
|
||||
assertion = hyperhiveCfg.swarm.hives != { };
|
||||
message = ''
|
||||
services.hyperhive.deploy.otel is true but
|
||||
services.hyperhive.deploy.otel.enable 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.
|
||||
|
|
@ -744,7 +745,7 @@ in
|
|||
# issuer URL evaluates cleanly and refuses every hive at runtime.
|
||||
assertion = autheliaCfg.url != null;
|
||||
message = ''
|
||||
services.hyperhive.deploy.otel is true but
|
||||
services.hyperhive.deploy.otel.enable 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.
|
||||
|
|
@ -770,7 +771,7 @@ in
|
|||
cfg.producerPort
|
||||
otelCfg.collector.port
|
||||
]
|
||||
++ lib.optional deployCfg.victoriametrics vmCfg.port;
|
||||
++ lib.optional deployCfg.victoriametrics.enable vmCfg.port;
|
||||
all = derived ++ others;
|
||||
in
|
||||
lib.length (lib.unique all) == lib.length all;
|
||||
|
|
@ -1005,7 +1006,7 @@ in
|
|||
};
|
||||
|
||||
exporters =
|
||||
lib.optionalAttrs deployCfg.victoriametrics {
|
||||
lib.optionalAttrs deployCfg.victoriametrics.enable {
|
||||
# `metrics_endpoint`, NOT `endpoint`: the latter is a
|
||||
# base that otlphttp appends `/v1/metrics` to, while
|
||||
# VictoriaMetrics serves OTLP at
|
||||
|
|
@ -1028,7 +1029,7 @@ in
|
|||
}
|
||||
// lib.optionalAttrs (otelCfg.protocol == "http/json") { encoding = "json"; };
|
||||
}
|
||||
// lib.optionalAttrs deployCfg.victorialogs {
|
||||
// lib.optionalAttrs deployCfg.victorialogs.enable {
|
||||
# `logs_endpoint`, NOT `endpoint`, for exactly the reason the
|
||||
# metrics exporter above spells out — and the trap is worse
|
||||
# here, because the two stores' OTLP routes differ. `endpoint`
|
||||
|
|
|
|||
Loading…
Reference in a new issue