# "What does THIS host deploy?" # # Separated from `services.hyperhive.swarm.*` because those are two # different kinds of fact and only one of them varies per machine: # # swarm.* — swarm-wide truth. The swarm's name, domain, hives, peers, # and where each service lives. **Identical on every # host**, byte for byte; a hive needs all of it to be a # *client* of the swarm. # deploy.* — this machine's deployment decisions. Necessarily different # on every host, because that is what a deployment is. # # The `enable` toggles live here rather than under `swarm.*` so the # namespace that is identical everywhere does not carry the one thing # that must differ per host. # # Flat and named for the thing deployed — `deploy.forgejo`, not # `deploy.swarmServices.forgejo`: grouping by "swarm service" re-encodes # the service-side taxonomy into a layer that does not care about it. # # ⚠️ Each entry is an attrset with an `enable`, not a bare bool, so a # service that grows a second *deployment* decision has somewhere to put # it — `deploy.nats = { enable; autoGenerateCallout; }` is then an ordinary # addition rather than a migration, where a bare bool leaves it # unrepresentable. # # ⚠️ The renames below are deliberately in this one file rather than # spread across the service modules, so all of them have a single home # and a single file to delete when the deprecation window closes — the # shape ./swarm-peers-removed.nix already uses. { lib, config, ... }: let deployCfg = config.services.hyperhive.deploy; # A removed CI-runner option. Its replacement has the same name under # `deploy.ci-runner`. ciRunnerRemoved = from: opt: lib.mkRemovedOptionModule ( [ "services" "hyperhive" ] ++ from ++ [ opt ] ) '' The CI runner is the swarm service in swarm-ci-runner.nix. It runs on any host, needs neither the forge nor a hive there, and registers with the token swarm-controller publishes to the secret store. Set services.hyperhive.deploy.ci-runner.${opt} instead. The runner registers as a new runner on the forge, so delete the old one in the forge's admin panel (Site administration, Actions, Runners). A forge host that runs the swarm-controller keeps resolving `uses: actions/checkout` from itself unless services.hyperhive.deploy.forgejo.actionsFromSelf is false there. See docs/scheduler/ci.md. ''; in { imports = [ # Same type, same meaning, new path — so a rename carries it exactly # and existing configs keep evaluating with one warning naming both # paths. Precedent: ./hive-forge/service.nix, ./hive-matrix.nix. (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "grafana" "enable" ] [ "services" "hyperhive" "deploy" "grafana" "enable" ] ) (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "grafana" "socketDir" ] [ "services" "hyperhive" "deploy" "grafana" "socketDir" ] ) (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "grafana" "datasourceUrl" ] [ "services" "hyperhive" "deploy" "grafana" "datasourceUrl" ] ) (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "grafana" "logsDatasourceUrl" ] [ "services" "hyperhive" "deploy" "grafana" "logsDatasourceUrl" ] ) (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "grafana" "plugins" ] [ "services" "hyperhive" "deploy" "grafana" "plugins" ] ) (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "victoriametrics" "enable" ] [ "services" "hyperhive" "deploy" "victoriametrics" "enable" ] ) (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "victorialogs" "enable" ] [ "services" "hyperhive" "deploy" "victorialogs" "enable" ] ) (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "controller" "enable" ] [ "services" "hyperhive" "deploy" "swarm-controller" "enable" ] ) (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "controller" "forgeTokenFile" ] [ "services" "hyperhive" "deploy" "swarm-controller" "forgeTokenFile" ] ) (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "controller" "authBridgeUrl" ] [ "services" "hyperhive" "deploy" "swarm-controller" "authBridgeUrl" ] ) (lib.mkRemovedOptionModule [ "services" "hyperhive" "swarm" "controller" "queue" "clientSecretFile" ] '' The controller reads its queue client secret from the swarm's secret store, under its own certificate (deploy.swarm-controller.baoClientCertFile), and swarm-secret-publish on the host that runs authelia puts it there. Remove this definition; the file it named is read by nothing now and can be deleted. '' ) (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "ui" "enable" ] [ "services" "hyperhive" "deploy" "swarm-ui" "enable" ] ) (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "authelia" "enable" ] [ "services" "hyperhive" "deploy" "authelia" "enable" ] ) (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "authelia" "usersFile" ] [ "services" "hyperhive" "deploy" "authelia" "usersFile" ] ) # `hostClientSecretDir` and `hostUsersFile` deliberately have NO entry # here. A rename module contributes a # *definition* to its target, and both are `readOnly`, which refuses a # second one — so a shim for either makes every evaluation fail with # "set multiple times", naming the option's own default as the rival # definition. Nothing could have set them anyway: both are derived and # read-only, so the shim's only possible customer is a reader of the old # path, and that reader now gets "option does not exist" instead, which # says the same thing sooner. (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "nats" "enable" ] [ "services" "hyperhive" "deploy" "nats" "enable" ] ) # Two of statusPublish's three coordinates. `tokenEndpoint` stays under # `swarm.*`: it is the swarm IdP's one address, identical on every hive, # where these two are "the queue as seen from here" and "the secret on # this disk". The all-or-nothing assertion in ./swarm.nix spans the split # deliberately and names all three paths in its message. (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "statusPublish" "natsUrl" ] [ "services" "hyperhive" "deploy" "hive-controller" "statusPublish" "natsUrl" ] ) (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "statusPublish" "clientSecretFile" ] [ "services" "hyperhive" "deploy" "hive-controller" "statusPublish" "clientSecretFile" ] ) # Both old spellings of "run a hive here" forward to the one switch. (lib.mkRenamedOptionModule [ "services" "hyperhive" "enable" ] [ "services" "hyperhive" "deploy" "hive-controller" "enable" ] ) (lib.mkRenamedOptionModule [ "services" "hyperhive" "c0re" "enable" ] [ "services" "hyperhive" "deploy" "hive-controller" "enable" ] ) (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "otel" "enable" ] [ "services" "hyperhive" "deploy" "swarm-otel" "enable" ] ) # ⚠️ Not to be confused with `services.hyperhive.otel.clientSecretFile`, # a different option on the hive tier that is not part of this table. A # bare `clientSecretFile` matches five distinct options across the tree. (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "otel" "clientSecretFile" ] [ "services" "hyperhive" "deploy" "swarm-otel" "clientSecretFile" ] ) # Removed rather than renamed: the runner is a different container with a # registration of its own, so an old definition is a deployment to re-read # rather than a path to forward. (ciRunnerRemoved [ "swarm" "forge" "ci" ] "enable") (ciRunnerRemoved [ "swarm" "forge" "ci" ] "name") (ciRunnerRemoved [ "swarm" "forge" "ci" ] "concurrency") (ciRunnerRemoved [ "swarm" "forge" "ci" ] "labels") (ciRunnerRemoved [ "swarm" "forge" "ci" ] "package") (ciRunnerRemoved [ "deploy" "forgejo" "ci" ] "enable") (ciRunnerRemoved [ "deploy" "forgejo" "ci" ] "name") (ciRunnerRemoved [ "deploy" "forgejo" "ci" ] "concurrency") (ciRunnerRemoved [ "deploy" "forgejo" "ci" ] "labels") (ciRunnerRemoved [ "deploy" "forgejo" "ci" ] "package") (ciRunnerRemoved [ "deploy" "forgejo" "ci" ] "jobTimeout") # The queue's callout identity. What stays under `swarm.nats` is what the # queue IS to every hive — the ports it answers on and the client id it is # registered under; these five are what the host running it decides. The # responder package is one of them, renamed further down with the other # `*.package` entries. # # ⚠️ The two PUBLIC keys follow their seeds. A public key looks # swarm-wide, and the user key genuinely is published to every client that # connects — but peers RECEIVE it over the wire, they never configure it, # and splitting a keypair across two namespaces is worse than either # placement. `enable`'s shim is the one above. (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "nats" "autoGenerateCallout" ] [ "services" "hyperhive" "deploy" "nats" "autoGenerateCallout" ] ) (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "nats" "calloutUserPublicKey" ] [ "services" "hyperhive" "deploy" "nats" "calloutUserPublicKey" ] ) (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "nats" "calloutIssuerPublicKey" ] [ "services" "hyperhive" "deploy" "nats" "calloutIssuerPublicKey" ] ) (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "nats" "calloutUserSeedFile" ] [ "services" "hyperhive" "deploy" "nats" "calloutUserSeedFile" ] ) (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "nats" "calloutIssuerSeedFile" ] [ "services" "hyperhive" "deploy" "nats" "calloutIssuerSeedFile" ] ) # The rest of the forge split. What stays under `swarm.forge` is what the # forge IS from any hive's point of view — the names and ports it answers # on, the URLs it advertises, the client id it is registered under; these # four are what the host running it decides. Its package is renamed # further down with the other `*.package` entries. `sso` splits # because its two halves are different facts: the client id must match the # entry in authelia's register, the secret is a path on this machine. # # `mirrors` renames in one entry rather than one per field: it is a single # option of a list-of-submodule type, so the rename carries its whole # value. (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "forge" "openFirewall" ] [ "services" "hyperhive" "deploy" "forgejo" "openFirewall" ] ) (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "forge" "mirrors" ] [ "services" "hyperhive" "deploy" "forgejo" "mirrors" ] ) (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "forge" "sso" "clientSecretFile" ] [ "services" "hyperhive" "deploy" "forgejo" "sso" "clientSecretFile" ] ) (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "forge" "hostSwarmControllerTokenFile" ] [ "services" "hyperhive" "deploy" "forgejo" "hostSwarmControllerTokenFile" ] ) # The homeserver, split the same way. `swarm.matrix` keeps what it IS to # every hive — the name it answers to, the ports and URLs it is reached # on, the client id it is registered under. These six are what the host # running it decides; its two packages are renamed further down with # the other `*.package` entries. ⚠️ `enable` is NOT here: its shim lives in # ./hive-matrix.nix, so that file is the one # to check before assuming this table is the whole matrix story. (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "matrix" "openFirewall" ] [ "services" "hyperhive" "deploy" "matrix" "openFirewall" ] ) (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "matrix" "trustedServers" ] [ "services" "hyperhive" "deploy" "matrix" "trustedServers" ] ) (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "matrix" "maxRequestSize" ] [ "services" "hyperhive" "deploy" "matrix" "maxRequestSize" ] ) # Both spellings of the registration token, removed rather than renamed: # the homeserver does not accept a shared registration secret at all, # so there is no path to point a definition at. Accounts are created by # the swarm's appservice. (lib.mkRemovedOptionModule [ "services" "hyperhive" "swarm" "matrix" "registrationTokenFile" ] '' The matrix registration token is gone: swarm-controller creates accounts as the swarm's appservice instead, so there is no shared secret for tuwunel to check. Remove this definition — nothing needs replacing. The old token file at /var/lib/hyperhive/matrix-register-token is read by nothing now and can be deleted. See docs/integrations/matrix.md. '') (lib.mkRemovedOptionModule [ "services" "hyperhive" "deploy" "matrix" "registrationTokenFile" ] '' The matrix registration token is gone: swarm-controller creates accounts as the swarm's appservice instead, so there is no shared secret for tuwunel to check. Remove this definition — nothing needs replacing. The old token file at /var/lib/hyperhive/matrix-register-token is read by nothing now and can be deleted. See docs/integrations/matrix.md. '') (lib.mkRemovedOptionModule [ "services" "hyperhive" "swarm" "matrix" "gui" "enable" ] '' The matrix web client has no on/off switch: every host that runs the homeserver serves it at services.hyperhive.swarm.matrix.gatewayHost, and the swarm UI links to it. Remove this definition. '') (lib.mkRemovedOptionModule [ "services" "hyperhive" "deploy" "matrix" "gui" "enable" ] '' The matrix web client has no on/off switch: every host that runs the homeserver serves it at services.hyperhive.swarm.matrix.gatewayHost, and the swarm UI links to it. Remove this definition. '') (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "matrix" "sso" "clientSecretFile" ] [ "services" "hyperhive" "deploy" "matrix" "sso" "clientSecretFile" ] ) # Retention is read only where the container is defined, so it is a # decision of the host running the store rather than something the swarm # agrees on. The two stores keep their domain and port in `swarm.*`, # because a client hive needs those to reach them; `package` followed # `enable` and `retentionPeriod` across in a later slice. (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "victoriametrics" "retentionPeriod" ] [ "services" "hyperhive" "deploy" "victoriametrics" "retentionPeriod" ] ) (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "victorialogs" "retentionPeriod" ] [ "services" "hyperhive" "deploy" "victorialogs" "retentionPeriod" ] ) # The switch over all of the above. `allSwarmServices` says whether THIS # host runs every service the swarm requires; those services are # required of the SWARM, so the name is about the swarm rather than this # host's wiring. (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "enableRequiredServices" ] [ "services" "hyperhive" "deploy" "allSwarmServices" ] ) # The mode above that one lives under `deploy`, not at the TOP of # `services.hyperhive`: that namespace is everything about hyperhive, not # the settings of a single hive. `singleHostSwarm` names what the mode # asserts — the whole swarm runs on this host — instead of its mechanism. (lib.mkRenamedOptionModule [ "services" "hyperhive" "enableAllLocalDefaults" ] [ "services" "hyperhive" "deploy" "singleHostSwarm" ] ) # The hive TLS state dir lives under `deploy.hive-controller` (the # hive-c0re daemon's namespace), not at the TOP of `services.hyperhive`, # which is everything about hyperhive rather than the settings of one hive. (lib.mkRenamedOptionModule [ "services" "hyperhive" "tls" "stateDir" ] [ "services" "hyperhive" "deploy" "hive-controller" "tls" "stateDir" ] ) # The hive CA's lifetime and its leaves', both spellings, removed rather # than renamed: no hive CA is generated, and the store's per-hive role # sets the gateway leaf's lifetime. (lib.mkRemovedOptionModule [ "services" "hyperhive" "tls" "caValidityDays" ] '' No hive CA is generated any more: the gateway leaf is issued by the secret store's pki mount, whose per-hive role sets its lifetime (services.hyperhive.deploy.bao.servicesPkiLeafTtlHours). Remove this definition. See docs/swarm/ca.md. '') (lib.mkRemovedOptionModule [ "services" "hyperhive" "tls" "leafValidityDays" ] '' No hive CA is generated any more: the gateway leaf is issued by the secret store's pki mount, whose per-hive role sets its lifetime (services.hyperhive.deploy.bao.servicesPkiLeafTtlHours). Remove this definition. See docs/swarm/ca.md. '') (lib.mkRemovedOptionModule [ "services" "hyperhive" "deploy" "hive-controller" "tls" "caValidityDays" ] '' No hive CA is generated any more: the gateway leaf is issued by the secret store's pki mount, whose per-hive role sets its lifetime (services.hyperhive.deploy.bao.servicesPkiLeafTtlHours). Remove this definition. See docs/swarm/ca.md. '' ) (lib.mkRemovedOptionModule [ "services" "hyperhive" "deploy" "hive-controller" "tls" "leafValidityDays" ] '' No hive CA is generated any more: the gateway leaf is issued by the secret store's pki mount, whose per-hive role sets its lifetime (services.hyperhive.deploy.bao.servicesPkiLeafTtlHours). Remove this definition. See docs/swarm/ca.md. '' ) # The WireGuard mesh, whole. Unlike every rename above this one covers a # namespace rather than a toggle: nothing under it is a fact another hive # reads. A peer needs this host's `wireguardEndpoint` — the roster entry # in ./swarm.nix, which stays — and nothing about the interface this host # brings up. `listenPort` follows for the same reason and is easy to read # the other way: it is what this host *binds*, while the port a peer # *dials* is the one inside `wireguardEndpoint`. (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "wireguard" "enable" ] [ "services" "hyperhive" "deploy" "wireguard" "enable" ] ) (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "wireguard" "privateKeyFile" ] [ "services" "hyperhive" "deploy" "wireguard" "privateKeyFile" ] ) (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "wireguard" "address" ] [ "services" "hyperhive" "deploy" "wireguard" "address" ] ) (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "wireguard" "listenPort" ] [ "services" "hyperhive" "deploy" "wireguard" "listenPort" ] ) (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "wireguard" "persistentKeepalive" ] [ "services" "hyperhive" "deploy" "wireguard" "persistentKeepalive" ] ) # Which build a service runs is a decision of the host that runs it, so # every `*.package` follows its `enable` across. Left in separate # namespaces they split one client's two halves, as `gui.enable` and # `gui.package` would. (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "matrix" "package" ] [ "services" "hyperhive" "deploy" "matrix" "package" ] ) (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "matrix" "gui" "package" ] [ "services" "hyperhive" "deploy" "matrix" "gui" "package" ] ) (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "grafana" "package" ] [ "services" "hyperhive" "deploy" "grafana" "package" ] ) (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "victorialogs" "package" ] [ "services" "hyperhive" "deploy" "victorialogs" "package" ] ) (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "victoriametrics" "package" ] [ "services" "hyperhive" "deploy" "victoriametrics" "package" ] ) # With this one `services.hyperhive.swarm.ui` holds nothing at all — its # two options are both renamed, so the namespace exists only as this # entry and the `enable` one above it. (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "ui" "package" ] [ "services" "hyperhive" "deploy" "swarm-ui" "package" ] ) (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "nats" "authPackage" ] [ "services" "hyperhive" "deploy" "nats" "authPackage" ] ) (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "authelia" "package" ] [ "services" "hyperhive" "deploy" "authelia" "package" ] ) (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "authelia" "bridgePackage" ] [ "services" "hyperhive" "deploy" "authelia" "bridgePackage" ] ) # ⚠️ `swarm-controller`, not `hive-controller` — see the note in # ./swarm-controller.nix. Both namespaces exist, so the wrong target here # lands on a live option in hive-c0re's tree instead of failing. (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "controller" "package" ] [ "services" "hyperhive" "deploy" "swarm-controller" "package" ] ) (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "controller" "swarmctlPackage" ] [ "services" "hyperhive" "deploy" "swarm-controller" "swarmctlPackage" ] ) # ⚠️ `deploy.forgejo`, not `deploy.forge` — the deploy-side name differs # from the swarm-side one here, as it does for the controller and the UI. (lib.mkRenamedOptionModule [ "services" "hyperhive" "swarm" "forge" "package" ] [ "services" "hyperhive" "deploy" "forgejo" "package" ] ) ]; # ⚠️ Only `deploy.forgejo.enable` is declared here. The rest of # `deploy.forgejo` is in ./hive-forge/default.nix: the knobs live with the # module that reads them; this file stays the registry of toggles. options.services.hyperhive.deploy = { forgejo.enable = lib.mkOption { type = lib.types.bool; default = false; example = true; description = '' Run the swarm's forge in a `hive-forge` container on this host. A swarm has one forge, so one host turns this on. It is the canonical store for the meta flake and every agent's config repo, so the swarm needs it, but *this* host running it is a decision like any other shared service's. With it off, this hive is a *client*: it reaches the swarm's forge at {option}`services.hyperhive.swarm.forge.domain`, which the operator's DNS must resolve to the forge's host. No container is created, and an existing one's state stays on disk under `/var/lib/nixos-containers/hive-forge/`. {option}`services.hyperhive.deploy.allSwarmServices` turns it on, and `singleHostSwarm` through that. ''; }; grafana.enable = lib.mkOption { type = lib.types.bool; default = false; description = '' Run the swarm's metrics UI on this host. Off by default and not derived from {option}`services.hyperhive.deploy.hive-controller.enable`: a swarm has one Grafana, so running it is a decision about this host rather than about whether it runs a hive. ''; }; victoriametrics.enable = lib.mkOption { type = lib.types.bool; default = false; description = '' Run the swarm's metrics store on this host. Paired with {option}`services.hyperhive.deploy.grafana.enable`: 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 that switch. Set either directly to run exactly one. ''; }; victorialogs.enable = lib.mkOption { type = lib.types.bool; default = false; description = '' Run the swarm's log store on this host. A hive that is not the service host is a *client* of this store, not a second one. ''; }; bao.enable = lib.mkOption { type = lib.types.bool; default = false; example = true; description = '' Run the swarm's secret store in a `swarm-bao` container on this host. A swarm has one store and it has to exist somewhere. *Where* it runs is a separate question from *that* it runs: set this directly to put the store on a host of its own, and clients still reach it by name at {option}`services.hyperhive.swarm.bao.domain` rather than at a local address. With it off, this hive is a *client*: it still reads its own secrets from whoever runs the store, authenticating with its own client certificate. Every hive needs the client half; only one runs the server half, which is why the two live in different namespaces. ''; }; authelia.enable = lib.mkOption { type = lib.types.bool; default = false; example = true; description = '' Run the swarm's authelia in a `swarm-authelia` container on this host. A swarm has one SSO provider, and this says it lives here. With it off, this hive is a *client*: {option}`services.hyperhive.swarm.authelia.url` still points at whoever runs it, and no container is created. That asymmetry is why the two live in different namespaces — every hive needs the client half, only one runs the server half. ''; }; swarm-otel.enable = lib.mkOption { type = lib.types.bool; default = false; description = '' Run the **swarm's** telemetry collector on this host. A swarm has one of these, and it belongs wherever the shared services live rather than on every hive. Named `swarm-otel` rather than `otel` because there are two collectors and the tier is the whole distinction: {option}`services.hyperhive.otel.enable` is the **hive-tier** one, which every hive runs. A bare `deploy.otel` would not say which it meant. A hive that does not run the swarm collector still runs its own, and reaches this one by name at {option}`services.hyperhive.swarm.otel.domain`. ''; }; matrix.enable = lib.mkOption { type = lib.types.bool; default = false; description = '' Run the swarm's matrix homeserver — matrix-tuwunel, in a `hive-matrix` container — on this host. Set it directly to put the homeserver somewhere other than the host holding the rest of the swarm's services. Client-side settings stay in {option}`services.hyperhive.swarm.matrix.*`, which every hive agrees on; this is only the decision to run it here. ''; }; nats.enable = lib.mkOption { type = lib.types.bool; default = false; description = '' Run the swarm's message queue in a `swarm-nats` container on this host. A swarm has one queue, so at most one host turns this on — but *which* host is its own decision, not necessarily the one running the swarm's other shared services. Off by default, and off means *absent*: no container is created and nothing else in the evaluated config changes. ''; }; ci-runner.enable = lib.mkOption { type = lib.types.bool; default = false; example = true; description = '' Run the swarm's Forgejo Actions runner in a `swarm-ci-runner` container on this host. It reaches the forge at {option}`services.hyperhive.swarm.forge.domain` and registers with the token swarm-controller publishes to the secret store, so it needs neither the forge nor a hive on this host. Not derived from {option}`services.hyperhive.deploy.allSwarmServices`: a runner executes pull-request code, so running one is a decision of its own. ''; }; hive-controller.enable = lib.mkOption { type = lib.types.bool; default = false; example = true; description = '' Run a hive on this host: the `hive-c0re` coordinator that owns every agent container here, its `hive-priv` helper, and the bridge, resolver and gateway the agents hang off. Every hive turns this on. A host that only runs the swarm's shared services ({option}`services.hyperhive.deploy.allSwarmServices`) leaves it off. ''; }; swarm-controller.enable = lib.mkOption { type = lib.types.bool; default = false; description = '' Run the swarm-controller daemon on this host. Off by default and deliberately not derived from {option}`services.hyperhive.deploy.hive-controller.enable`: a swarm has one controller, so running it is a decision about this host rather than about whether it runs a hive. ''; }; swarm-ui.enable = lib.mkOption { type = lib.types.bool; default = deployCfg.swarm-controller.enable; defaultText = lib.literalExpression "services.hyperhive.deploy.swarm-controller.enable"; example = true; description = '' Serve the swarm UI from this host. Derived from {option}`services.hyperhive.deploy.swarm-controller.enable`: the UI is a view onto the controller's state and reaches it over that daemon's unix socket, so the host that runs the controller is the host that can serve the UI. A hive that merely *uses* a swarm has nothing to serve here. ''; }; }; }