A swarm has one store, so running it is a fact about this machine and belongs beside the other deploy.* toggles rather than in the namespace every host agrees on. Attrset with an enable, not a bare bool, so a second deployment decision has somewhere to go. Asserted from swarm.enableRequiredServices alongside the other once-per-swarm services, and asserted as a mkDefault -- which is what keeps *where* the store runs a separate question from *that* it runs. Set it directly to put the store on a host of its own; a hive that does not run it is a client either way, reaching it by name. Two descriptions in the file still narrated the old swarm.* layout as something that used to be true, and the queue's claimed it belongs on the shared-services host. Both now say what holds.
100 lines
4.7 KiB
Nix
100 lines
4.7 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.
|
|
#
|
|
# Everything derives under `deploy.*` now, because "does THIS host run
|
|
# it" is a per-host decision and `swarm.*` has to be identical on every
|
|
# host. Same switch, same rule, one attribute path.
|
|
config.services.hyperhive.deploy.matrix.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.enable = lib.mkDefault swarmCfg.enableRequiredServices;
|
|
|
|
# The queue. Same rule: once per swarm, optional.
|
|
config.services.hyperhive.deploy.nats.enable = lib.mkDefault swarmCfg.enableRequiredServices;
|
|
|
|
# The swarm collector that feeds the metrics pair, and the only tier
|
|
# holding the upstream credential. ⚠️ NOT the per-hive collector below,
|
|
# which every hive runs.
|
|
config.services.hyperhive.deploy.swarm-otel.enable = 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.enable =
|
|
lib.mkDefault swarmCfg.enableRequiredServices;
|
|
config.services.hyperhive.deploy.grafana.enable = 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.enable =
|
|
lib.mkDefault swarmCfg.enableRequiredServices;
|
|
|
|
# The secret store. Once per swarm and optional, so it belongs to the
|
|
# same switch: a hive that does not run it is a *client*, reading its
|
|
# own secrets from whoever does. `mkDefault` is what keeps the store
|
|
# placeable on a host of its own — it can be set directly here and
|
|
# turned off wherever this switch happens to be on.
|
|
config.services.hyperhive.deploy.bao.enable = lib.mkDefault swarmCfg.enableRequiredServices;
|
|
}
|