diff --git a/nix/host-modules/hyperhive.nix b/nix/host-modules/hyperhive.nix index 6de59aee..d370aeab 100644 --- a/nix/host-modules/hyperhive.nix +++ b/nix/host-modules/hyperhive.nix @@ -132,6 +132,32 @@ in ''; }; + # The one switch for "everything runs on this box". Every autoconf + # toggle in the tree defaults from it, so an all-local deployment is a + # single line rather than one line per service that grew a toggle. + options.services.hyperhive.enableAllLocalDefaults = lib.mkOption { + type = lib.types.bool; + default = false; + example = true; + description = '' + Run the whole swarm on this host: the swarm-wide services + (`services.hyperhive.swarm.enableRequiredServices`) and the swarm + CA (`services.hyperhive.swarm.ca.autoConfigure`) all default from + this, and anything autoconfigurable added later should too. + + **Off by default, and that is the load-bearing part.** A swarm's + services and its hives can live on different hosts, and a host has + no way to tell which ones it is meant to be — so this is an + operator saying "this is that box", never something inferred. + Turn it on for a dev box or a single-hive swarm and get a working + deployment with no further configuration; leave it off and every + swarm-level artifact is operator-provided. + + Each derived toggle can still be set explicitly to override this + one, so "all local except X" needs no new option. + ''; + }; + # Whether this hive runs "ruthless" — with no root/manager agent at # all. Some hives don't want a root agent — see issue tracker # "scope concept: special agents". diff --git a/nix/host-modules/swarm-ca.nix b/nix/host-modules/swarm-ca.nix index 75607c24..5e7ed467 100644 --- a/nix/host-modules/swarm-ca.nix +++ b/nix/host-modules/swarm-ca.nix @@ -52,12 +52,19 @@ in options.services.hyperhive.swarm.ca = { autoConfigure = lib.mkOption { type = lib.types.bool; - default = false; + default = hyperhiveCfg.enableAllLocalDefaults; + defaultText = lib.literalExpression "services.hyperhive.enableAllLocalDefaults"; example = true; description = '' Run the whole swarm CA on this one host: generate the swarm root when it is missing, and issue this hive's CA under it. + Defaults from `services.hyperhive.enableAllLocalDefaults`, the + all-on-one-box switch — which is off, so this is off, and the + paragraph below still describes what a hive does by default. + Set it directly to run the CA on a host that is not otherwise + all-local. + **Off by default, deliberately.** A swarm's services and its hives can live on different hosts, and this host has no way to tell whether it is the one holding the root — so the swarm CA diff --git a/nix/host-modules/swarm.nix b/nix/host-modules/swarm.nix index 4430432a..f7be1a33 100644 --- a/nix/host-modules/swarm.nix +++ b/nix/host-modules/swarm.nix @@ -126,6 +126,31 @@ ''; }; + # "The swarm-wide services run HERE." A swarm has one forge, one + # matrix, one SSO — this says this host is where they live, and each + # of those services defaults its own enable from it rather than the + # operator enabling them one at a time. + options.services.hyperhive.swarm.enableRequiredServices = lib.mkOption { + type = lib.types.bool; + default = config.services.hyperhive.enableAllLocalDefaults; + defaultText = lib.literalExpression "services.hyperhive.enableAllLocalDefaults"; + example = true; + description = '' + Host the swarm's shared services on this hive. The services that + exist once per swarm rather than once per hive — the forge, the + matrix homeserver, the SSO provider — default their `enable` from + this, so a swarm's service host is declared in one place. + + Defaults from `services.hyperhive.enableAllLocalDefaults` (off), + which is the all-on-one-box switch. 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. + ''; + }; + options.services.hyperhive.swarm.snapshotStore = { address = lib.mkOption { type = lib.types.nullOr lib.types.str;