swarm-archive serves restic repositories with rclone, append-only, one login and one repository per agent. swarm-controller writes each placed agent's login and restic password to the store, replaces them on a move and removes them when the agent is destroyed. Every hive backs its agents up hourly under its own store identity. The archive host prunes by retention.
95 lines
3.7 KiB
Nix
95 lines
3.7 KiB
Nix
# Glue: where the store and one of its readers share a host, the reader waits
|
|
# for the store's container and `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.
|
|
#
|
|
# No `Wants=` on the container: it is started by `machines.target` and the
|
|
# switch's start phase, and a reader's `Wants=` would pull it up mid-switch,
|
|
# before `activate` has replaced its configuration, on the OLD closure. A
|
|
# reader that starts before the store costs one failed attempt, retried by
|
|
# ./lib/store-retry.nix.
|
|
#
|
|
# `Wants=` on `swarm-bao-pki`, not `Requires=`: a pki start that fails or is
|
|
# refused fails each requirer's job with `dependency`, which leaves the reader
|
|
# inactive rather than failed, so its `Restart=on-failure` never fires. Here
|
|
# the reader runs anyway; with its leaf still missing, its login exits 1 into
|
|
# ./lib/store-retry.nix's retries.
|
|
#
|
|
# ⚠️ Gated on BOTH the store and that reader being here. Off the store's host
|
|
# neither unit exists, and 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;
|
|
|
|
hiveOtelSecret = import ./lib/hive-otel-secret.nix {
|
|
inherit (hyperhiveCfg.swarm.authelia) hiveClientPrefix;
|
|
inherit (hyperhiveCfg.deploy.hive-controller) hiveName;
|
|
};
|
|
|
|
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.collector.enable
|
|
&& hyperhiveCfg.deploy.hive-controller.hiveName != null
|
|
&& havePair baoDeploy.clientCertFile baoDeploy.clientKeyFile
|
|
&& otel.clientSecretFile == hiveOtelSecret.path;
|
|
# ./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-secret-key = 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-attic.nix
|
|
swarm-bao-attic-secret = deployCfg.attic.enable;
|
|
swarm-bao-attic-tokens = deployCfg.attic.enable;
|
|
# ./swarm-archive.nix
|
|
swarm-archive-users = deployCfg.archive.enable;
|
|
swarm-archive-prune = deployCfg.archive.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 = [ "swarm-bao-pki.service" ];
|
|
};
|
|
};
|
|
in
|
|
{
|
|
config = lib.mkMerge (lib.mapAttrsToList orderAfterStore readersHere);
|
|
}
|