# "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 — have their `enable` asserted from this, so a swarm's service host is declared in one place. 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; authelia.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. nats.enable = lib.mkDefault swarmCfg.enableRequiredServices; # The metrics pair. Once per swarm and optional, so they meet the rule # in the option's description the same way the three above do — a hive # that is not the service host is a *client* of this Grafana, not a # second one. # # They derive 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. victoriametrics.enable = lib.mkDefault swarmCfg.enableRequiredServices; grafana.enable = lib.mkDefault swarmCfg.enableRequiredServices; # The log store, deriving from the same switch for the same reason — # and deliberately in the same commit as the collector pipeline that # writes to it, never before it. A store nothing writes to is worse # than no store: it starts, answers queries, and returns nothing, so # the first person to look concludes there were no logs. victorialogs.enable = lib.mkDefault swarmCfg.enableRequiredServices; # 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; }