Watch
0
0
Fork
You've already forked hyperhive
0

move hiveName to deploy.hive-controller; only a hive host needs a name

This commit is contained in:
atlas 2026-10-26 16:06:11 +01:00 • committed by mara
commit 0c6e8fc5a2
37 changed files with 402 additions and 215 deletions

View file

@ -1,6 +1,6 @@
# The swarm's directory: one entry per hive, **including this one**,
# identical on every host in the swarm. `services.hyperhive.hiveName`
# says which entry is us.
# identical on every host in the swarm. A host that runs a hive says which
# entry is its own with `services.hyperhive.deploy.hive-controller.hiveName`.
#
# Why a directory rather than a per-host peer list: every field here is
# intrinsic to the hive it describes — none of them says anything about
@ -217,14 +217,14 @@ in
Every hive in this swarm, keyed by `hiveName` — **including this
host's own hive**. The same attrset is meant to be identical on
every host in the swarm, so it can be written once and shared;
`services.hyperhive.hiveName` is what makes a given host read it
`services.hyperhive.deploy.hive-controller.hiveName` is what makes a hive host read it
as "me and four others" rather than "five peers".
Each entry needs no fields at all in the conventional case: a
hive's `domain` defaults to `<name>.<swarm.domain>`, so the whole
directory is usually a list of names.
It must contain an entry for `hiveName`, which is asserted — this
On a host that runs a hive it must contain an entry for `hiveName`, which is asserted — this
host's own address is read out of it (it is where
`services.hyperhive.domain` derives from), and a hive that lists
everyone but itself would otherwise derive its own peer set as
@ -247,16 +247,6 @@ in
'';
};
options.services.hyperhive.swarm.dashboardDomain = lib.mkOption {
type = lib.types.nullOr lib.types.str;
readOnly = true;
internal = true;
description = ''
Read-only: this hive's entry in `dashboardDomains`, or null where
`hiveName` has no entry in `hives` (asserted below).
'';
};
options.services.hyperhive.swarm.serviceDomains = lib.mkOption {
type = lib.types.listOf lib.types.str;
readOnly = true;
@ -284,49 +274,11 @@ in
if swarmCfg.domain == null then "${name}.hives.invalid" else "${name}.hives.${swarmCfg.domain}"
) swarmCfg.hives;
services.hyperhive.swarm.dashboardDomain =
if cfg.hiveName != null && swarmCfg.dashboardDomains ? ${cfg.hiveName} then
swarmCfg.dashboardDomains.${cfg.hiveName}
else
null;
services.hyperhive.swarm.serviceDomains = lib.sort (a: b: a < b) (
lib.unique (lib.filter (d: d != null && d != "") serviceDomains')
);
assertions = [
{
# An EMPTY `hives` fires this too, deliberately: since
# `swarm.domain` is required, every hive is in a swarm — a
# swarm of one is still a swarm — so a directory with no entry
# for this host is missing one either way. It also has to fire
# here, because this host's own domain is now read out of the
# directory: without the entry `services.hyperhive.domain` is
# null and the generic required-domain assertion in
# ./hive-network.nix would fire instead, naming an option the
# operator should not be setting.
#
# Guarded on `hiveName != null` so the required-hiveName
# assertion in ./hyperhive.nix is what fires for that case —
# two assertions naming the same missing value is noise.
assertion = cfg.hiveName == null || swarmCfg.hives ? ${cfg.hiveName};
message = ''
services.hyperhive.swarm.hives has no entry for this hive
(services.hyperhive.hiveName = "${toString cfg.hiveName}").
`hives` describes every hive in the swarm including this one,
so that every host can share one identical attrset, and this
hive's own domain is derived from its entry. Add:
services.hyperhive.swarm.hives."${toString cfg.hiveName}" = { };
No fields are needed: `domain` defaults to
`<name>.<swarm.domain>`. Set it in the entry if this hive is
addressed by something else.
Declared hives: ${lib.concatStringsSep ", " (lib.attrNames swarmCfg.hives)}
'';
}
(nameGuards.mustBeIdent {
option = "services.hyperhive.swarm.hives";
names = hiveNames;