Watch
0
0
Fork
You've already forked hyperhive
0
hyperhive/nix/host-modules/glue-bao-readers-store-order.nix
atlas 7d09776742 swarm UI: an alerts page, read by the controller with a Viewer Grafana token from bao
swarm-bao-grafana-controller-token, on the host that runs Grafana, logs in
to Grafana's API over its socket as the built-in admin (the password
swarm-bao-grafana-admin minted, #5138) and keeps a `swarm-controller`
service account that is an enabled Viewer. It mints a token for that
account and writes it to bao at
swarm/controller/swarm-controller/grafana/token under Grafana's leaf. A
ten-minute timer runs it again. The unit keeps a stored token Grafana
accepts. If Grafana refuses the stored token with 401, or bao holds
none, the unit deletes every token of the account and mints a new one.
Grafana's grant gains create/read/update on that leaf, and the
controller's gains read.

swarm-controller serves GET /api/alerts from Grafana's
/api/prometheus/grafana/api/v1/alerts. It reads the token from bao,
keeps it in memory, and re-reads bao once on a 401. The HTTP client has
5s connect and 15s request timeouts. Any failure is a 503 that names its
cause. swarm-ui gets an /alerts page listing them, built the same way as
the hives page.

This is option (c) on #5129, the operator's choice.
2026-10-15 15:16:21 +02:00

76 lines
2.8 KiB
Nix

# Glue: where the store and one of its readers share a host, the reader waits
# for the store's container and requires `swarm-bao-pki`, which mints the leaf
# the reader logs in with.
#
# ONE PAIRING PER FILE — the store's container and PKI unit ← the readers that
# log in to it, and nothing else. The waits on the store's policy units are
# ./glue-bao-readers-policy-order.nix's.
#
# ⚠️ Gated on BOTH the store and that reader being here. Off the store's host
# neither unit exists, and `Requires=` on an absent unit fails the job, so
# there the reader's own start timeout bounds the attempt instead. On the
# store's host without the reader, setting `systemd.services.<reader>.after`
# would define a unit with no ExecStart, so each gate below restates the one
# the reader's own module puts on it. A reader whose gate changes must change
# here too.
{
lib,
config,
...
}:
let
hyperhiveCfg = config.services.hyperhive;
deployCfg = hyperhiveCfg.deploy;
baoDeploy = deployCfg.bao;
baoCfg = hyperhiveCfg.swarm.bao;
otel = hyperhiveCfg.otel;
havePair = cert: key: cert != null && key != null;
# Reader unit → the gate its own module defines it under.
readersHere = {
# ./hive-forge/default.nix
swarm-bao-forge-oidc = deployCfg.forgejo.enable;
swarm-bao-forge-publisher = deployCfg.forgejo.enable;
# ./hive-matrix.nix
swarm-bao-matrix-oidc = deployCfg.matrix.enable;
# ./otel.nix: `fetches`, the collector loading the file this unit writes
# under the hive's own leaf.
swarm-bao-hive-otel-oidc =
otel.enable
&& hyperhiveCfg.hiveName != null
&& havePair baoDeploy.clientCertFile baoDeploy.clientKeyFile
&&
otel.clientSecretFile
== "/var/lib/hive-otel-oidc/${hyperhiveCfg.swarm.authelia.hiveClientPrefix}${toString hyperhiveCfg.hiveName}.secret";
# ./swarm-grafana.nix
swarm-bao-grafana-oidc = deployCfg.grafana.enable;
swarm-bao-grafana-admin = deployCfg.grafana.enable;
swarm-bao-grafana-metrics-bearer = deployCfg.grafana.enable;
swarm-bao-grafana-controller-token = deployCfg.grafana.enable;
# ./swarm-nats.nix
swarm-bao-nats-callout-xkey = deployCfg.nats.enable;
# ./swarm-ci-runner.nix
swarm-bao-ci-runner = deployCfg.ci-runner.enable;
# ./swarm-otel.nix
swarm-bao-otel-oidc =
deployCfg.swarm-otel.enable
&& havePair baoDeploy.otelOidcClientCertFile baoDeploy.otelOidcClientKeyFile;
};
orderAfterStore =
reader: here:
lib.mkIf (baoDeploy.enable && here) {
systemd.services.${reader} = {
after = [
"swarm-bao-pki.service"
"container@${baoCfg.machine}.service"
];
wants = [ "container@${baoCfg.machine}.service" ];
requires = [ "swarm-bao-pki.service" ];
};
};
in
{
config = lib.mkMerge (lib.mapAttrsToList orderAfterStore readersHere);
}