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

@ -568,7 +568,7 @@ let
l = vh."h1.hives.t.local".locations;
gated = loc: lib.hasInfix "auth_request /__hive_authelia;" loc.extraConfig;
in
allLocal.services.hyperhive.swarm.dashboardDomain == "h1.hives.t.local"
allLocal.services.hyperhive.deploy.hive-controller.dashboardDomain == "h1.hives.t.local"
&& vh."h1.hives.t.local".forceSSL
&& lib.all (p: gated l.${p}) [
"/"
@ -1251,23 +1251,133 @@ let
&& bare.networking.bridges ? hive-br0;
}
{
# Refused wherever something turns the name into an identifier, and only
# there. The store host is the control that the refusal is not the hive's
# alone; the host running neither is the control that it is gated at all.
name = "a missing hiveName is refused on a hive and on a store host, not elsewhere";
# Refused where a hive runs and nowhere else. A name is an identifier
# only for a hive; the hive host is the control that the lookup finds the
# refusal when there is one.
name = "a missing hiveName is refused on a hive and not on a store, homeserver or services host";
ok =
let
refusedHiveName =
refused =
extra:
lib.any (a: !a.assertion && lib.hasInfix "services.hyperhive.hiveName to be set" a.message)
(hiveWithController ({ hiveName = null; } // extra)).assertions;
lib.any (
a:
!a.assertion
&& lib.hasInfix "services.hyperhive.deploy.hive-controller.hiveName" a.message
&& lib.hasInfix "to be set" a.message
) (hive (lib.recursiveUpdate { deploy.hive-controller.hiveName = null; } extra)).assertions;
in
refusedHiveName { }
&& refusedHiveName {
deploy.hive-controller.enable = false;
deploy.bao.enable = true;
}
&& !(refusedHiveName { deploy.hive-controller.enable = false; });
refused { deploy.hive-controller.enable = true; }
&& !(refused { deploy.bao.enable = true; })
&& !(refused { deploy.matrix.enable = true; })
&& !(refused { deploy.allSwarmServices = true; });
}
{
# The directory entry is asserted for a hive and only for a hive. The
# hive host with a name the directory lacks is the control.
name = "a hive whose name has no swarm.hives entry is refused, and a host without a hive is not asked";
ok =
let
noEntry =
extra:
lib.any (a: !a.assertion && lib.hasInfix "swarm.hives has no entry for this hive" a.message)
(hive (lib.recursiveUpdate { deploy.hive-controller.hiveName = "other"; } extra)).assertions;
in
noEntry { deploy.hive-controller.enable = true; }
&& !(noEntry { deploy.bao.enable = true; })
&& !(noEntry { deploy.allSwarmServices = true; });
}
{
# Nothing of the hive's identity is minted for a host that runs no hive:
# no reader leaf named after a hive, and no reader identity at all, so
# the glue that locates the PKI falls back to the store's own directory.
# The hive host with the same store is the control.
name = "a store host without a hive mints no hive reader leaf and still wires the controller and publisher";
ok =
let
storeNoHive = hive {
deploy.hive-controller.hiveName = null;
deploy.bao.enable = true;
deploy.swarm-controller.enable = true;
deploy.swarm-secret-publisher.enable = true;
};
storeWithHive = hiveWithController {
deploy.bao.enable = true;
deploy.swarm-controller.enable = true;
deploy.swarm-secret-publisher.enable = true;
};
pki = m: m.systemd.services.swarm-bao-pki.script;
d = m: m.services.hyperhive.deploy;
in
(d storeNoHive).bao.clientCertFile == null
&& (d storeNoHive).bao.clientKeyFile == null
&& !(lib.hasInfix "/var/lib/swarm-bao-pki/client.pem ]" (pki storeNoHive))
&& (d storeNoHive).swarm-controller.baoClientCertFile == "/var/lib/swarm-bao-pki/controller.pem"
&&
(d storeNoHive).swarm-secret-publisher.baoClientCertFile
== "/var/lib/swarm-bao-pki/secret-publisher.pem"
&& (d storeWithHive).bao.clientCertFile == "/var/lib/swarm-bao-pki/client.pem"
&& lib.hasInfix "/var/lib/swarm-bao-pki/client.pem ]" (pki storeWithHive)
&& (d storeWithHive).swarm-controller.baoClientCertFile == "/var/lib/swarm-bao-pki/controller.pem";
}
{
# An operator's own reader leaf names the PKI directory, exactly as it did
# when the glue always derived it from that path.
name = "a controller and publisher with an operator-placed reader leaf and no store follow its directory";
ok =
let
m = hive {
deploy.swarm-controller.enable = true;
deploy.swarm-secret-publisher.enable = true;
deploy.bao.clientCertFile = "/etc/pki/elsewhere/client.pem";
deploy.bao.clientKeyFile = "/etc/pki/elsewhere/client-key.pem";
};
d = m.services.hyperhive.deploy;
in
!d.bao.enable
&& d.swarm-controller.baoClientCertFile == "/etc/pki/elsewhere/controller.pem"
&& d.swarm-secret-publisher.baoClientCertFile == "/etc/pki/elsewhere/secret-publisher.pem";
}
{
# The old spelling forwards with the module system's one warning and
# produces the same hive. The new-path host is the control that the
# warning is not always present.
name = "services.hyperhive.hiveName still sets the hive's name, with a rename warning";
ok =
let
old = hiveWithController {
hiveName = "legacy";
swarm.hives.legacy = { };
};
warned =
m:
lib.any (
w: lib.hasInfix "services.hyperhive.hiveName" w && lib.hasInfix "has been renamed" w
) m.warnings;
in
old.services.hyperhive.deploy.hive-controller.hiveName == "legacy"
&& old.systemd.services.hive-c0re.environment.HYPERHIVE_HIVE_NAME == "legacy"
&& warned old
&& !(warned bare);
}
{
# A hive's rendered identity, pinned so moving the option changes none of
# it: the coordinator's name and client, the dashboard name, the CN of the
# reader leaf the store host signs, and what the hive collector presents.
name = "a hive's name reaches hive-c0re, the reader leaf, the dashboard and the hive collector unchanged";
ok =
let
e = allLocal.systemd.services.hive-c0re.environment;
script = allLocal.systemd.services.swarm-bao-pki.script;
lines = lib.splitString "\n" script;
at = lib.lists.findFirstIndex (lib.hasSuffix "swarm-bao-pki client \\") null lines;
nextLine = builtins.head (builtins.match " *(.*)" (builtins.elemAt lines (at + 1)));
in
e.HYPERHIVE_HIVE_NAME == "h1"
&& e.HIVE_C0RE_OIDC_CLIENT_ID == "hive-h1"
&& e.HYPERHIVE_DASHBOARD_DOMAIN == "h1.hives.t.local"
&& allLocal.services.hyperhive.deploy.hive-controller.dashboardDomain == "h1.hives.t.local"
&& at != null
&& nextLine == ''h1 "" clientAuth'';
}
{
# The control is a host that defines no such option; the removal message