Watch
0
0
Fork
You've already forked hyperhive
0

nix: finish the current-behaviour comment sweep in touched files

Rewrite the remaining narration in files the previous commit touched:
"moved"/"sat"/"was REMOVED"/"old default" comments in swarm-bao,
swarm-otel, glue-bao-tls, nats-authelia, swarm-controller, swarm-ui,
swarm-otel-service, swarm-authelia-service, the deploy.nix rename table,
hive-ci, hive-forge/service, hive-tls, hyperhive, swarm-nats, swarm.nix
and a few module-eval fixtures, so each says where a thing is or why it
is so now.

Revert the comment edits inside shell script strings in hive-tls,
swarm-nats and the forge token mint to their previous text, so those
generated units are unchanged. The only unit still changing is
swarm-bao-pki (two comment lines in its script). Refs #3902
This commit is contained in:
atlas 2026-10-05 03:13:02 +02:00
commit e990e9a0be
21 changed files with 102 additions and 103 deletions

View file

@ -93,11 +93,11 @@
[ "hyperhive" "frontend" "extraFiles" ]
[ "services" "hyperhive" "agent" "frontend" "extraFiles" ]
)
# `frontend.mergedDist` moved with the rest and deliberately has NO entry:
# `frontend.mergedDist` deliberately has NO entry:
# it is `readOnly` and ./frontend.nix already defines it, and a rename
# module contributes a *definition* to its target — so a shim for it makes
# every evaluation fail with "set multiple times". Nothing could have set
# it anyway; a reader of the old path now gets "option does not exist",
# it anyway; a reader of the old path gets "option does not exist",
# which says the same thing sooner. Same reasoning as the `hostUsersFile`
# exclusion in ../host-modules/deploy.nix.
(lib.mkRenamedOptionModule

View file

@ -25,7 +25,7 @@
# exactly that shape, and a bare bool leaves it unrepresentable.
#
# ⚠️ The renames below are deliberately in this one file rather than
# spread across the service modules, so the whole move has a single home
# spread across the service modules, so all of them have a single home
# and a single file to delete when the deprecation window closes — the
# shape ./swarm-peers-removed.nix already uses.
{ lib, config, ... }:
@ -99,8 +99,8 @@ in
[ "services" "hyperhive" "swarm" "authelia" "usersFile" ]
[ "services" "hyperhive" "deploy" "authelia" "usersFile" ]
)
# `hostClientSecretDir` and `hostUsersFile` moved in the same commit and
# deliberately have NO entry here. A rename module contributes a
# `hostClientSecretDir` and `hostUsersFile` deliberately have NO entry
# here. A rename module contributes a
# *definition* to its target, and both are `readOnly`, which refuses a
# second one — so a shim for either makes every evaluation fail with
# "set multiple times", naming the option's own default as the rival
@ -139,7 +139,7 @@ in
[ "services" "hyperhive" "deploy" "swarm-otel" "enable" ]
)
# ⚠️ Not to be confused with `services.hyperhive.otel.clientSecretFile`,
# a different option on the hive tier that is not part of this move. A
# a different option on the hive tier that is not part of this table. A
# bare `clientSecretFile` matches five distinct options across the tree.
(lib.mkRenamedOptionModule
[ "services" "hyperhive" "swarm" "otel" "clientSecretFile" ]
@ -177,14 +177,14 @@ in
# The queue's callout identity. What stays under `swarm.nats` is what the
# queue IS to every hive — the ports it answers on and the client id it is
# registered under; these five are what the host running it decides. The
# responder package is one of them now, further down with the other
# `*.package` moves.
# responder package is one of them, renamed further down with the other
# `*.package` entries.
#
# ⚠️ The two PUBLIC keys move with their seeds. A public key looks
# ⚠️ The two PUBLIC keys follow their seeds. A public key looks
# swarm-wide, and the user key genuinely is published to every client that
# connects — but peers RECEIVE it over the wire, they never configure it,
# and splitting a keypair across two namespaces is worse than either
# placement. `enable` moved earlier; its shim is the one above.
# placement. `enable`'s shim is the one above.
(lib.mkRenamedOptionModule
[ "services" "hyperhive" "swarm" "nats" "autoGenerateCallout" ]
[ "services" "hyperhive" "deploy" "nats" "autoGenerateCallout" ]
@ -209,8 +209,8 @@ in
# The rest of the forge split. What stays under `swarm.forge` is what the
# forge IS from any hive's point of view — the names and ports it answers
# on, the URLs it advertises, the client id it is registered under; these
# four are what the host running it decides. Its package moved as well,
# further down with the other `*.package` moves. `sso` splits
# four are what the host running it decides. Its package is renamed
# further down with the other `*.package` entries. `sso` splits
# because its two halves are different facts: the client id must match the
# entry in authelia's register, the secret is a path on this machine.
#
@ -238,8 +238,8 @@ in
# The homeserver, split the same way. `swarm.matrix` keeps what it IS to
# every hive — the name it answers to, the ports and URLs it is reached
# on, the client id it is registered under. These six are what the host
# running it decides; its two packages moved as well, further down with
# the other `*.package` moves. ⚠️ `enable` is NOT here: its shim lives in
# running it decides; its two packages are renamed further down with
# the other `*.package` entries. ⚠️ `enable` is NOT here: its shim lives in
# ./hive-matrix.nix, so that file is the one
# to check before assuming this table is the whole matrix story.
(lib.mkRenamedOptionModule
@ -360,11 +360,11 @@ in
''
)
# The WireGuard mesh, whole. Unlike every rename above this one moves a
# The WireGuard mesh, whole. Unlike every rename above this one covers a
# namespace rather than a toggle: nothing under it is a fact another hive
# reads. A peer needs this host's `wireguardEndpoint` — the roster entry
# in ./swarm.nix, which stays — and nothing about the interface this host
# brings up. `listenPort` moves for the same reason and is easy to read
# brings up. `listenPort` follows for the same reason and is easy to read
# the other way: it is what this host *binds*, while the port a peer
# *dials* is the one inside `wireguardEndpoint`.
(lib.mkRenamedOptionModule
@ -389,10 +389,9 @@ in
)
# Which build a service runs is a decision of the host that runs it, so
# every `*.package` follows its `enable` across. The split these replace
# was the sharpest case: `gui.enable` had already moved while
# `gui.package` stayed, so one client's two halves sat in two namespaces
# and ./hive-matrix.nix said so in a comment above the option.
# every `*.package` follows its `enable` across. Left in separate
# namespaces they split one client's two halves, as `gui.enable` and
# `gui.package` would.
(lib.mkRenamedOptionModule
[ "services" "hyperhive" "swarm" "matrix" "package" ]
[ "services" "hyperhive" "deploy" "matrix" "package" ]
@ -413,9 +412,9 @@ in
[ "services" "hyperhive" "swarm" "victoriametrics" "package" ]
[ "services" "hyperhive" "deploy" "victoriametrics" "package" ]
)
# With this one `services.hyperhive.swarm.ui` holds nothing at all — it had
# exactly two options and both have moved, so the namespace now exists only
# as this entry and the `enable` one above it.
# With this one `services.hyperhive.swarm.ui` holds nothing at all — its
# two options are both renamed, so the namespace exists only as this
# entry and the `enable` one above it.
(lib.mkRenamedOptionModule
[ "services" "hyperhive" "swarm" "ui" "package" ]
[ "services" "hyperhive" "deploy" "swarm-ui" "package" ]

View file

@ -228,7 +228,7 @@ in
# is what OPENS the mint, so it cannot come out of it. A certificate
# authority that issues the credential admitting you to it is the
# cycle this file's header exists to keep out — which is exactly why
# the swarm-services root moved into the store and this one did not.
# the swarm-services root lives in the store and this one does not.
#
# Its own CN, not the reader's: the hive's own leaf reads every secret
# its policy names, while this principal may do one thing — `update`

View file

@ -197,8 +197,8 @@ in
];
# Tell hive-c0re that CI is enabled so its startup sweep registers the
# runner. Registration moved OFF the container's boot-critical path into
# hive-c0re (`forge/ci_runner.rs`): it validates the persisted `.runner`
# runner. Registration is OFF the container's boot-critical path:
# hive-c0re (`forge/ci_runner.rs`) validates the persisted `.runner`
# against the forge and, when absent/stale, mints a registration token and
# hands it to hive-priv to write `/run/hive-ci/runner-token` + restart the
# runner. The forge admin token stays in hive-c0re; only the registration

View file

@ -925,25 +925,29 @@ in
# re-mint instead of being silently masked by a stamp that
# outlived what it claims exists.
if [ ! -s "$token_path" ]; then
# `write:admin` is required by `swarm-controller::forge::Client::
# ensure_agent_user` (the `CreateForgeUser` jobq node):
# Forgejo's `admin_create_user` HTTP endpoint refuses a
# token without it ("token does not have at least one of
# required scope(s): [write:admin]"). A host whose token was
# minted without this scope keeps it — the
# `[ ! -s "$token_path" ]` guard above only mints when the
# file is absent, by design (see its own comment) — so such a
# deployment needs its token file deleted to force a re-mint
# with the full scope.
# `write:admin` added for `swarm-controller::forge::Client::
# ensure_agent_user` (the `CreateForgeUser` jobq node) —
# Forgejo's `admin_create_user` HTTP endpoint refused every
# call with "token does not have at least one of required
# scope(s): [write:admin]" without it, an already-deployed
# swarm hitting this the moment that node shipped. A host
# whose token was minted before this scope was added won't
# pick it up automatically — the `[ ! -s "$token_path" ]`
# guard above only mints when the file is absent, by design
# (see its own comment) — so an existing deployment needs
# its token file deleted to force a re-mint with the new
# scope.
#
# Token name carries a timestamp suffix rather than a fixed
# name: deleting the token *file* (the remediation above)
# doesn't delete the token Forgejo already has under that
# name, so re-running this unit would fail with "Command
# error: access token name has been used already". Same
# approach `hive-c0re::forge::users::mint_token` uses for its
# own agent tokens — a monotonic suffix means a re-mint can
# never collide with whatever this account already has.
# Token name carries a timestamp suffix rather than the
# fixed `swarm-controller-boot` this used to be — a real
# incident, not a hypothetical: deleting the token *file*
# (the remediation above) doesn't delete the token Forgejo
# already has under that name, so re-running this unit hit
# "Command error: access token name has been used already"
# and failed outright. Same fix `hive-c0re::forge::users::
# mint_token` already uses for its own agent tokens, for
# the identical reason — a monotonic suffix means a re-mint
# can never collide with whatever this account already has.
out=$(forgejo admin user generate-access-token \
--username ${lib.escapeShellArg swarmControllerForgeUser} \
--token-name "swarm-controller-boot-$(date +%s)" \

View file

@ -98,10 +98,8 @@ in
swarm's domain, not this hive's, because a swarm runs **one**
forge that every hive in it talks to.
⚠️ A deployment that was running before this moved keeps its
current name by pinning it here:
`forge.''${services.hyperhive.domain}`, which is exactly what
the old default rendered. Certificates follow either way: the
⚠️ To use the per-hive name `forge.''${services.hyperhive.domain}`
instead, pin it here. Certificates follow either way: the
swarm-services sub-CA is name-constrained to the configured
names (see `./swarm-ca.nix`), not to a fixed tree.

View file

@ -44,7 +44,7 @@ let
publicPortSuffix = if publicPort == 443 then "" else ":${toString publicPort}";
# `<hive>/matrix/*` → 301 → `gatewayHost`'s vhost/$1 (`chat.<swarm-domain>`
# by default; legacy deep-link shim during the fluffychat sub-domain move).
# by default; legacy deep-link shim for the fluffychat sub-domain).
# See `docs/networking/gateway.md`.
matrixRedirectLocations =
lib.optionalAttrs (matrixDeployCfg.enable && matrixCfg.gatewayHost != null)

View file

@ -130,9 +130,9 @@ let
# leaf to hold, and its absence there is the correct state rather
# than a stale one — its own vhosts are covered by the hive leaf
# above. Anywhere else it is expected: the leaf comes from the
# secret store's `pki` mount, reachable from every host rather than
# from a sub-CA on one host in the swarm, so "this host cannot issue
# it" is not one of the answers.
# secret store's `pki` mount now, not from a sub-CA that exists on
# one host in the swarm, so "this host cannot issue it" is no longer
# one of the answers.
want_svc=${if localServiceDomains == [ ] then "0" else "1"}
# Expiry is not the only way a leaf goes wrong. One signed when the
@ -976,15 +976,14 @@ in
# they mint a token from authelia over TLS. Declared HERE, beside the
# bundle, rather than in each consumer's module: the path is this
# module's fact, and two consumers re-deriving `${stateDir}/…` would be
# two places to fix the day it moves.
# two places to fix when it changes.
#
# ⚠️ This is what was missing. `swarm-queue-client` built a bare
# `reqwest::Client`, so it trusted only the platform roots and died at
# `invalid peer certificate: UnknownIssuer` against a swarm whose
# authelia is signed by the swarm CA — while this very bundle sat on
# disk, already assembled, already handed to hive-c0re under a different
# variable name. The anchor was never missing; nothing pointed the queue
# client at it.
# ⚠️ `swarm-queue-client` builds a bare `reqwest::Client`, so it trusts
# only the platform roots and dies at `invalid peer certificate:
# UnknownIssuer` against a swarm whose authelia is signed by the swarm
# CA. The bundle is already assembled on disk and handed to hive-c0re
# under a different variable name; this declaration is what points the
# queue client at it.
#
# Where the gateway is not self-signed this module contributes nothing, and
# the clients then fall back to the platform roots — which is correct for

View file

@ -11,8 +11,8 @@ let
hiveCfg = config.services.hyperhive;
in
{
# The swarm's display name moved under `swarm` when the swarm-global
# settings were consolidated; the hive's own name and domain stayed put,
# The swarm's display name lives under `swarm`, with the other
# swarm-global settings; the hive's own name and domain are top-level,
# because they describe this hive rather than the swarm it joins.
imports = [
(lib.mkRenamedOptionModule
@ -39,11 +39,10 @@ in
# "the other hives can't reach me", on a machine other than the
# misconfigured one.
#
# ⚠️ The `<hiveName>.<swarm.domain>` formula did NOT move here from
# there and back: it lives once, on `hives.<name>.domain`, which
# this reads. Restoring a direct fallback here would recreate the
# second path (and, since that default reads `swarm.domain` too, a
# value that can differ from the directory's).
# ⚠️ The `<hiveName>.<swarm.domain>` formula lives once, on
# `hives.<name>.domain`, which this reads. A direct fallback here
# 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

View file

@ -18,7 +18,7 @@ let
unitName = "authelia-${instance}";
in
{
# `enable` and both packages moved to `services.hyperhive.deploy.authelia`
# `enable` and both packages are under `services.hyperhive.deploy.authelia`
# — see ./deploy.nix. Whether this host runs the swarm's SSO provider, and
# which build it runs, are deployment decisions, in ./swarm-authelia.nix.
# Here is what authelia IS, including `url` and the OIDC client registry

View file

@ -2914,9 +2914,8 @@ in
# difference between a mount nobody may issue from and one the gateway's
# certificate comes out of.
#
# The policy text moved here from the controller's unit, where it sat
# while it attached to nothing — a policy and the role that carries it
# belong in one place, and now there is a principal to put them with.
# The policy text lives beside the role that carries it: a policy and
# its role belong in one place, with the principal they grant.
systemd.services.swarm-bao-services-issuer-policy = lib.mkIf haveGranter {
description = "write the swarm services issuer's bao policy and cert-auth role";
after = [

View file

@ -375,13 +375,14 @@ in
'';
};
# `enable` moved to `services.hyperhive.deploy.swarm-controller.enable` — see
# ./deploy.nix. `services.hyperhive.deploy.singleHostSwarm` still
# asserts it, and that was never an exception to "not derived from
# `enable` is `services.hyperhive.deploy.swarm-controller.enable` — see
# ./deploy.nix. `services.hyperhive.deploy.singleHostSwarm` asserts
# it, and that is not an exception to "not derived from
# deploy.hive-controller.enable": that mode says "this box is the whole
# deployment", which answers the topology question outright, where
# `enable` alone never can. Both packages moved to that same
# `deploy.swarm-controller` block. What stays here is what the daemon IS.
# `enable` alone never can. Both packages are in that same
# `deploy.swarm-controller` block. What is declared here is what the
# daemon IS.
staleAfterSeconds = lib.mkOption {
type = lib.types.ints.positive;
@ -612,8 +613,8 @@ in
matrixHomeserverUrl = lib.mkOption {
type = lib.types.nullOr lib.types.str;
# `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
# deployment that pins `gatewayHost` (e.g. to the per-hive name) 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}"'';

View file

@ -277,7 +277,7 @@ in
# store path, and the directory it shares a socket with nginx through.
# `enable` already lives in ./deploy.nix, which also carries the renames.
#
# ⚠️ Both datasource URLs are wiring and still move. A URL's scope is the
# ⚠️ Both datasource URLs are wiring, so they live here. A URL's scope is the
# scope of what it ADDRESSES, not the fact that it is a URL: both stores
# bind loopback, so these can only ever mean "on this host".
options.services.hyperhive.deploy.grafana = {

View file

@ -118,14 +118,13 @@ let
# Two accounts, and the callout user lives in neither of the accounts
# it authorizes into.
accounts = {
# ⚠️ The nkey is not decoration and its absence was a real hole: a
# ⚠️ The nkey is not decoration, and without it there is a hole: a
# `users` entry carrying only a `user` name has no credential, and
# `CONNECT {"user":"auth"}` is then accepted with no password at
# all. Since the name is a literal in this public module, that made
# the callout-exempt identity walk-in-able from every container on
# the shared netns — the same class of hole this module exists to
# close, moved rather than fixed. Caught in review on the first
# version of this file. An nkey and NOTHING else, both halves
# close. An nkey and NOTHING else, both halves
# measured against a running server rather than reasoned about:
#
# { user = "auth"; } → `CONNECT {"user":"auth"}`

View file

@ -41,7 +41,7 @@ in
'')
];
# `enable` moved to `services.hyperhive.deploy.swarm-otel.enable` — see ./deploy.nix.
# `enable` is `services.hyperhive.deploy.swarm-otel.enable` — see ./deploy.nix.
# ⚠️ That is the SWARM collector. The per-hive one keeps its own
# `services.hyperhive.otel.enable` (./otel.nix) and is a different
# option entirely — every hive runs that one.

View file

@ -555,8 +555,8 @@ in
# that runs it without a leaf, because a Grafana with no SSO has no way
# in at all, while a collector with none still receives telemetry. So
# this fires only where the host already reads the store and is missing
# this one pair — which before the four-way split rendered the unit off
# `clientCertFile`, and now silently does not.
# this one pair: the unit is rendered off the collector's own leaf, so
# without it the unit would silently not render.
assertion = !hiveReaderIdentity || haveClientIdentity;
message = ''
This host reads the swarm secret store (services.hyperhive.deploy.bao.clientCertFile
@ -586,10 +586,10 @@ in
from that CA out of band and named here — see docs/swarm/secrets.md.
'';
}
# ⚠️ An assertion that this collector has "somewhere to send" was REMOVED
# rather than relaxed: it read the store's *per-host* enable, so it
# rejected at eval the very deployment the stores are reached by domain
# for — a collector on its own host never built.
# ⚠️ There is deliberately no assertion that this collector has
# "somewhere to send": it would read the store's *per-host* enable, and
# so reject at eval the very deployment the stores are reached by domain
# for — a collector on its own host would never build.
{
# Whether there is a journal on disk to collect from.
# A `bindMounts` entry never creates its `hostPath`, and unlike

View file

@ -61,10 +61,10 @@ let
apex = if swarmCfg.domain == null then "swarm.invalid" else swarmCfg.domain;
in
{
# `enable` moved to `services.hyperhive.deploy.swarm-ui.enable` — see
# ./deploy.nix, where it still derives from the controller's own deploy
# toggle for the same reason. `domain` is gone too: the UI answers on the
# swarm apex, which the swarm already declares once.
# `enable` is `services.hyperhive.deploy.swarm-ui.enable` — see
# ./deploy.nix, where it derives from the controller's own deploy
# toggle for the same reason. There is no `domain` option: the UI answers
# on the swarm apex, which the swarm already declares once.
imports = [
(lib.mkRemovedOptionModule [ "services" "hyperhive" "swarm" "ui" "domain" ] ''
The swarm UI answers on services.hyperhive.swarm.domain and nothing

View file

@ -211,7 +211,7 @@ in
# it — and this field was set on real deployments.
#
# ⚠️ `lib.mkRemovedOptionModule` cannot do this job here, and
# neither of its two halves survives the move into a submodule:
# neither of its two halves survives inside a submodule:
# its `apply = throw` fires only when the value is READ, and
# nothing reads this (that being the point of removing
# it); its `config.assertions` half would land on a submodule

View file

@ -334,7 +334,7 @@ let
&& (baoForwarder baoWithHiveOtel).settings.exporters.otlphttp.endpoint == route;
}
{
# 🎯 The credential half of this move, and the arm that says the hop
# 🎯 The credential half of the hop, and the arm that says it
# DELIVERS rather than merely resolves. The receiver at the far end
# takes an OIDC token and nothing else, so an exporter with no
# authenticator is a forwarder that retries into 401s while every other

View file

@ -229,7 +229,7 @@ let
ok = !(equalityGuardFired hiveNamesAllLegal) && !(fragmentGuardFired hiveNamesAllLegal);
}
{
# The substring guard came along in the move and has to still work.
# The substring guard has to work with the collector off too.
# `h1-agent` mints exactly the client id hive `h1`'s agents present.
name = "a hive name containing a composed-identifier word is refused, with the collector off";
ok = fragmentGuardFired hiveNameWithComposedWord;

View file

@ -268,9 +268,9 @@ let
}
{
# Not a rename test. `hostClientSecretDir` is `readOnly`, so the fixture
# cannot define it; what can break is a reader left pointing at the
# namespace it moved out of. Several modules read this through an
# `autheliaCfg` alias, where a path-shaped grep does not see it.
# cannot define it; what can break is a reader left pointing at
# `swarm.authelia` instead of `deploy.authelia`. Several modules read this
# through an `autheliaCfg` alias, where a path-shaped grep does not see it.
name = "a consumer of authelia's host client-secret dir renders it from the deploy namespace";
ok = lib.hasPrefix "/var/lib/nixos-containers/swarm-authelia/var/lib/authelia-swarm/oidc-clients/" autheliaOldPath.services.hyperhive.otel.clientSecretFile;
}
@ -332,10 +332,11 @@ let
}
{
# …and the name it resolves through is a DOMAIN, not a host this config
# picked. `127.0.0.1` is what the old default rendered on the IdP host,
# the bridge address is what the queue's defaults still render, and
# neither is an address a client may be handed: the domain is allowed to
# resolve differently in different places, which is the whole property.
# picked. `127.0.0.1` is what a co-location-derived default renders on
# the IdP host, the bridge address is what the queue's defaults render,
# and neither is an address a client may be handed: the domain is
# allowed to resolve differently in different places, which is the
# whole property.
name = "the swarm IdP address names no host address";
ok =
let