Watch
0
0
Fork
You've already forked hyperhive
0

swarm-controller: default matrixHomeserverUrl from swarm.matrix.gatewayHost

matrixHomeserverUrl re-derived gatewayHost's own default
(chat.${swarmDomain}) instead of reading gatewayHost itself, so a
deployment that pins gatewayHost away from that default (the exact
case hive-matrix.nix's own option doc describes) left the controller
calling a name nothing serves. Read matrix.gatewayHost directly,
mirroring hive-matrix.nix's ctlHomeserverUrl. Add module-eval cases
that pin gatewayHost and that null it out, alongside the existing
unpinned default case.

Closes #4757
This commit is contained in:
atlas 2026-09-27 14:42:58 +02:00 • committed by mara
commit 3fc7a785fa
2 changed files with 43 additions and 4 deletions

View file

@ -92,6 +92,7 @@ let
forgeCfg = config.services.hyperhive.swarm.forge;
swarmDomain = config.services.hyperhive.swarm.domain;
matrixCfg = config.services.hyperhive.swarm.matrix;
# The controller's forge client speaks TLS to `https://${forgeCfg.domain}`,
# which the gateway serves with a leaf signed by the hive CA — a CA
@ -558,10 +559,12 @@ in
matrixHomeserverUrl = lib.mkOption {
type = lib.types.nullOr lib.types.str;
# The same `chat.<swarm domain>` ./hive-matrix.nix serves its vhost on
# (`gatewayHost`): a swarm runs one homeserver.
default = if swarmDomain == null then null else "https://chat.${swarmDomain}";
defaultText = lib.literalExpression ''"https://chat.''${services.hyperhive.swarm.domain}"'';
# `gatewayHost`'s own vhost, not a re-derivation of its default: a
# deployment that pins `gatewayHost` (e.g. to keep a name from before
# it moved under the swarm domain) still has one homeserver, and this
# option has to name the same one.
default = if matrixCfg.gatewayHost == null then null else "https://${matrixCfg.gatewayHost}";
defaultText = lib.literalExpression ''"https://''${services.hyperhive.swarm.matrix.gatewayHost}"'';
example = "https://matrix.example.org";
description = ''
Client-server API base of the swarm's homeserver. The controller

View file

@ -45,6 +45,24 @@ let
# files this host will never have.
controllerNoStore = hive { deploy.swarm-controller.enable = true; };
# A deployment that pinned `gatewayHost` away from its own swarm-domain
# default (`hive-matrix.nix`'s own doc: "a deployment that was running
# before this moved keeps its current name by pinning ... here"). Only
# this fixture can tell "the controller reads gatewayHost" apart from
# "the controller re-derives gatewayHost's default itself" — both render
# the same URL on every other fixture in this file.
controllerPinnedGateway = hive {
deploy.swarm-controller.enable = true;
swarm.matrix.gatewayHost = "matrix.hive.t.local";
};
# No matrix vhost for this swarm at all: tuwunel stays direct on
# `httpPort`, so there is no homeserver URL to hand the controller.
controllerNoGatewayHost = hive {
deploy.swarm-controller.enable = true;
swarm.matrix.gatewayHost = null;
};
# The two authorities told apart. A deployment that self-signs both ends
# points `clientCaFile` and `serverCaFile` at one file, so on the fixture
# above the CA a hive is issued from and the CA the store is verified by are
@ -77,6 +95,24 @@ let
controllerNoStore.systemd.services.swarm-controller.environment.SWARM_CONTROLLER_MATRIX_HOMESERVER_URL
or null == "https://chat.t.local";
}
{
# The case above alone can't tell "reads gatewayHost" from "re-derives
# gatewayHost's own default": both land on chat.t.local when nothing is
# pinned. This fixture pins gatewayHost away from that default, so only
# the former passes.
name = "the controller's homeserver follows a pinned gatewayHost, not its own chat.<domain> default";
ok =
controllerPinnedGateway.systemd.services.swarm-controller.environment.SWARM_CONTROLLER_MATRIX_HOMESERVER_URL
or null == "https://matrix.hive.t.local";
}
{
name = "a swarm with no matrix gateway vhost gives the controller no homeserver variable";
ok =
!(
controllerNoGatewayHost.systemd.services.swarm-controller.environment
? SWARM_CONTROLLER_MATRIX_HOMESERVER_URL
);
}
{
# Nothing asserted the PKI script before this, so a third leaf could be
# added to it and every case still passed — measured, not assumed: the