hyperhive/nix/host-modules/swarm-required-services.nix
atlas 64e8c62f18 deploy: move the queue toggle
Same shape as the others. Three of the eight references were prose
rather than code: two assertion messages naming the option to an
operator, and a `defaultText` in the authelia module, whose
`oidc.hiveIdentities` derives from whether the queue runs here.

Also corrects a comment in swarm.nix that this commit's own hunk sits
directly beneath. It said `enableRequiredServices` turns on matrix and
authelia "but NOT nats (nats has no mode that enables it)", which stopped
being true when the queue was added to that switch — before this change,
not by it. The reasoning it introduces is still right and still worth
keeping; only the premise had expired.
2026-08-30 04:23:22 +02:00

105 lines
5 KiB
Nix

# "The swarm-wide services run HERE."
#
# A swarm has one forge, one matrix, one SSO. This says this host is
# where they live, and asserts the per-service `enable`s that follow —
# the same mode-not-default shape as ./local-defaults.nix, one tier down.
#
# Only the *optional* services derive: matrix and authelia. The forge has
# no `enable` to assert, because it is not optional — it is the canonical
# store for the meta flake and every agent's config repo, so it deploys
# with hyperhive itself.
{
lib,
config,
...
}:
let
swarmCfg = config.services.hyperhive.swarm;
in
{
options.services.hyperhive.swarm.enableRequiredServices = lib.mkOption {
type = lib.types.bool;
default = false;
example = true;
description = ''
Host the swarm's shared services on this hive. The services that
exist once per swarm rather than once per hive and are *optional*
the matrix homeserver, the SSO provider, the queue, the metrics
and log stores have their toggle asserted from this, so a
swarm's service host is declared in one place.
Those toggles live in two namespaces and the split is deliberate:
{option}`services.hyperhive.deploy.*` for "does THIS host run it",
`swarm.*.enable` for the ones not yet moved. See ./deploy.nix.
The forge is swarm-wide too but has nothing to assert: it is the
canonical store for the meta flake and every agent's config repo,
so it deploys with hyperhive itself and is not optional.
`services.hyperhive.enableAllLocalDefaults` turns this on as part
of the all-on-one-box mode. Set it directly to run the swarm's
services on a host that is not otherwise all-local a dedicated
services box with hives elsewhere is exactly that shape.
With it off, this hive is a *client* of those services: it still
configures how to reach them, it just doesn't run them.
'';
};
# Same precedence reasoning as ./local-defaults.nix: fills in for an
# operator who hasn't spoken, yields to one who has.
config.services.hyperhive.swarm = {
matrix.enable = lib.mkDefault swarmCfg.enableRequiredServices;
# The queue. Added later than the two above and missed at the time —
# this file predates the `swarm-nats` container by nine days and had
# not been revisited since, so its absence was sequence rather than
# intent. It meets the rule in the option's own description exactly:
# once per swarm, and optional.
#
# The tell that it was an omission: `local-defaults.nix` already
# derives `nats.autoGenerateCallout` from the all-local mode, so that
# mode was minting the queue's callout nkeys and then never starting
# the queue they authenticate against.
# The metrics pair and the log store used to derive here too. They now
# live under `deploy.*` (below, and ./deploy.nix) because "does THIS
# host run it" is a per-host decision and `swarm.*` has to be identical
# on every host. Same switch, same rule, different attribute path.
# The collector that feeds the pair above, and the only tier holding
# the upstream credential. Same rule as the rest: once per swarm,
# optional, and a hive that is not the service host is a *client* of
# it (by name, `swarm.otel.domain`) rather than a second one.
otel.enable = lib.mkDefault swarmCfg.enableRequiredServices;
};
# The collector that feeds the pair above (note: no `swarm.` prefix,
# this is ./otel.nix's existing per-hive option).
config.services.hyperhive.otel.enable = lib.mkDefault swarmCfg.enableRequiredServices;
# The rest of the shared services, deriving from the same switch as the
# `swarm.*` ones above. They read differently only because "does THIS
# host run it" lives in `deploy.*` (./deploy.nix) — `swarm.*` has to be
# identical on every host, and these are exactly the values that must
# differ.
#
# authelia: a swarm has one SSO provider, and this says it lives here.
# With it off the hive is a *client* — `swarm.authelia.url` still points
# at whoever runs it.
config.services.hyperhive.deploy.authelia = lib.mkDefault swarmCfg.enableRequiredServices;
# The queue. Same rule: once per swarm, optional.
config.services.hyperhive.deploy.nats = lib.mkDefault swarmCfg.enableRequiredServices;
# The metrics pair, deriving together on purpose: a store with no UI is
# unreadable and a UI with no store is empty, so there is no sensible
# deployment that takes one and not the other from this switch. An
# operator who wants exactly one still sets it directly, which
# `mkDefault` allows.
config.services.hyperhive.deploy.victoriametrics = lib.mkDefault swarmCfg.enableRequiredServices;
config.services.hyperhive.deploy.grafana = lib.mkDefault swarmCfg.enableRequiredServices;
# The log store, from the same switch for the same reason as the rest: a
# hive that is not the service host is a *client* of it, not a second one.
config.services.hyperhive.deploy.victorialogs = lib.mkDefault swarmCfg.enableRequiredServices;
}