move hiveName to deploy.hive-controller; only a hive host needs a name
This commit is contained in:
parent
67f0d6a9d3
commit
0c6e8fc5a2
37 changed files with 402 additions and 215 deletions
|
|
@ -9,6 +9,7 @@
|
|||
}:
|
||||
let
|
||||
hiveCfg = config.services.hyperhive;
|
||||
hiveName = hiveCfg.deploy.hive-controller.hiveName;
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
|
|
@ -46,8 +47,8 @@ in
|
|||
# would recreate the second path (and, since that default reads
|
||||
# `swarm.domain` too, a value that can differ from the directory's).
|
||||
default =
|
||||
if hiveCfg.hiveName != null && hiveCfg.swarm.hives ? ${hiveCfg.hiveName} then
|
||||
hiveCfg.swarm.hives.${hiveCfg.hiveName}.domain
|
||||
if hiveName != null && hiveCfg.swarm.hives ? ${hiveName} then
|
||||
hiveCfg.swarm.hives.${hiveName}.domain
|
||||
else
|
||||
null;
|
||||
defaultText = lib.literalExpression "services.hyperhive.swarm.hives.\${hiveName}.domain, or null when there is no entry for this hive";
|
||||
|
|
@ -90,7 +91,7 @@ in
|
|||
hive's address belongs in the swarm directory, which every hive in
|
||||
the swarm shares a copy of:
|
||||
|
||||
services.hyperhive.swarm.hives."${toString hiveCfg.hiveName}".domain = "${toString hiveCfg.domain}";
|
||||
services.hyperhive.swarm.hives."${toString hiveName}".domain = "${toString hiveCfg.domain}";
|
||||
|
||||
(Or drop the value entirely if it is the conventional
|
||||
`<hiveName>.<swarm.domain>` — that is the directory entry's own
|
||||
|
|
@ -115,7 +116,7 @@ in
|
|||
occupies its own sub-domain of it, which is why every entry in
|
||||
`services.hyperhive.swarm.hives` defaults its `domain` to
|
||||
`<name>.<swarm.domain>` — set this plus
|
||||
`services.hyperhive.hiveName`, list the hives by name, and no
|
||||
`services.hyperhive.deploy.hive-controller.hiveName`, list the hives by name, and no
|
||||
hive in the swarm states an address at all.
|
||||
|
||||
**Required** on every host that runs a hyperhive service (a
|
||||
|
|
@ -129,56 +130,69 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
# Human display name for this hive. Distinct from the DNS domain
|
||||
# above (machine-readable) — see docs/process/conventions.md::Hive identity
|
||||
# for the domain-vs-name-vs-swarm distinction + the env-var
|
||||
# propagation chain. The swarm's display name is
|
||||
# `services.hyperhive.swarm.name`, one level out: this hive is named
|
||||
# here, the swarm it belongs to is named there.
|
||||
options.services.hyperhive.hiveName = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
example = "pr1ma";
|
||||
description = ''
|
||||
Human-readable name of this single-host hive instance.
|
||||
**Required** when this host runs a hive, the swarm's secret store
|
||||
or its homeserver
|
||||
(`services.hyperhive.deploy.hive-controller.enable`,
|
||||
`deploy.bao.enable`, `deploy.matrix.enable`). Distinct from
|
||||
`services.hyperhive.domain` (the machine-addressable DNS name)
|
||||
and not merely cosmetic: a hive occupies
|
||||
`<hiveName>.<swarm.domain>`, so this is the label the hive is
|
||||
*addressed* by as well as the one it is called. Exposed to
|
||||
agents as `HYPERHIVE_HIVE_NAME`; surfaced in the dashboard
|
||||
chrome and per-agent system prompt.
|
||||
'';
|
||||
};
|
||||
|
||||
# Each of these deployments turns `hiveName` into an identifier with no
|
||||
# fallback: hive-c0re's OIDC client and matrix localpart, the CN of the
|
||||
# store's `client.pem` (./glue-bao-tls.nix), and the `hives/<name>` path
|
||||
# the queue credential reader fetches. A null there renders
|
||||
# as an empty string that evaluates and deploys.
|
||||
# The hive's name is `deploy.hive-controller.hiveName`, declared in
|
||||
# ./deploy.nix beside the switch that makes a host run a hive. The
|
||||
# identity surfaces (label, domain, display names, env-var chain) are in
|
||||
# docs/process/conventions.md::Hive identity.
|
||||
#
|
||||
# A hive turns the name into an identifier with no fallback: hive-c0re's
|
||||
# OIDC client and matrix localpart, the CN of the hive's `client.pem`
|
||||
# (./glue-bao-tls.nix), and the `hives/<name>` path of its secrets. A null
|
||||
# there renders as an empty string that evaluates and deploys.
|
||||
config.assertions = [
|
||||
{
|
||||
assertion =
|
||||
!(
|
||||
hiveCfg.deploy.hive-controller.enable || hiveCfg.deploy.bao.enable || hiveCfg.deploy.matrix.enable
|
||||
)
|
||||
|| hiveCfg.hiveName != null;
|
||||
assertion = !hiveCfg.deploy.hive-controller.enable || hiveName != null;
|
||||
message = ''
|
||||
hyperhive requires services.hyperhive.hiveName to be set on a host
|
||||
that runs a hive, the swarm's secret store or its homeserver — it is
|
||||
this hive's label within the swarm, and the leftmost part of the
|
||||
domain it is addressed by (`<hiveName>.<swarm.domain>`), not only a
|
||||
display name. Set it (`services.hyperhive.hiveName = "pr1ma";`).
|
||||
hyperhive requires services.hyperhive.deploy.hive-controller.hiveName
|
||||
to be set on a host that runs a hive — it is this hive's label
|
||||
within the swarm, and the leftmost part of the domain it is
|
||||
addressed by (`<hiveName>.<swarm.domain>`), not only a display name.
|
||||
Set it (`services.hyperhive.deploy.hive-controller.hiveName = "pr1ma";`).
|
||||
'';
|
||||
}
|
||||
{
|
||||
# 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 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
|
||||
# above is what fires for that case — two assertions naming the same
|
||||
# missing value is noise.
|
||||
assertion =
|
||||
!hiveCfg.deploy.hive-controller.enable || hiveName == null || hiveCfg.swarm.hives ? ${hiveName};
|
||||
message = ''
|
||||
services.hyperhive.swarm.hives has no entry for this hive
|
||||
(services.hyperhive.deploy.hive-controller.hiveName = "${toString 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 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 hiveCfg.swarm.hives)}
|
||||
'';
|
||||
}
|
||||
];
|
||||
|
||||
config.services.hyperhive.deploy.hive-controller.dashboardDomain =
|
||||
if hiveName != null && hiveCfg.swarm.dashboardDomains ? ${hiveName} then
|
||||
hiveCfg.swarm.dashboardDomains.${hiveName}
|
||||
else
|
||||
null;
|
||||
|
||||
# The one hive-level option that describes something ABOVE the hive,
|
||||
# which is why it sits under `swarm` with the swarm-global services
|
||||
# rather than beside `hiveName`.
|
||||
# rather than beside the hive's name.
|
||||
options.services.hyperhive.swarm.name = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
|
|
|
|||
Loading…
Reference in a new issue