Watch
0
0
Fork
You've already forked hyperhive
0
hyperhive/nix/host-modules/glue-bao-readers-store-order.nix
atlas 141be16c6d hive-forge: the controller-token mint writes straight to the store, and the on-disk token goes
`forgejo-swarm-controller-account`, in the forge's container, now puts
the swarm-controller's forge token into the swarm secret store itself,
under the forge publisher's leaf. The container already receives that
leaf as nspawn system credentials for its journal forwarder; the mint
loads the same three. The token reaches bao on stdin (`value=-`) and
the forge's API through a header file, never as an argument, and never
touches disk.

The mint's guard is a marker holding the published token's name, at
/var/lib/forgejo/swarm-controller-token-name, written last: after the
put, and after every other `swarm-controller-boot-*` token of the
account is revoked through forgejo's admin API, authenticated as the
new token. So a put that failed, or a marker lost while the store kept
an older token, leaves no live token behind once a mint completes. The
mint logs in to the store and checks that the account is a site admin
before it mints, so a store that is down or an account the admin API
would refuse mints nothing on each retry. Failures retry under
store-retry; forgejo does not wait for the mint. No bao read and no
grant change: the forge publisher keeps create/update on the token.

Removed: the host's `swarm-bao-forge-publisher` service and path unit,
which read the token file through the container's root, and their
entries in the store and policy ordering glue. The forge publisher's
policy unit stays; `swarm-bao-forge-oidc` still uses the leaf.

On deploy, an existing forge host has no marker, so the mint runs once:
it mints a new token, publishes it, revokes the old one, and deletes
the old /var/lib/forgejo/swarm-controller-token. The controller's next
forge call gets a 401, re-reads the store and carries on.
2026-10-16 17:48:56 +02:00

75 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;
# ./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);
}