nix: comments state current behaviour, not history
Rewrite comments and option descriptions under nix/ that narrate how the
code got here ("used to", "new name", "sat at the TOP", "no longer",
renamed/moved narration, attributions) to say what the code does now and
why. Comments and description strings only; no logic changes.
Files in open PR #4970's diff are left alone. Refs #3902
This commit is contained in:
parent
ea63b0d150
commit
1c90619fbb
45 changed files with 331 additions and 411 deletions
|
|
@ -79,10 +79,10 @@ in
|
|||
#
|
||||
# Both spellings, for the same reason ../host-modules/deploy.nix lists both
|
||||
# of `swarm|deploy.matrix.registrationTokenFile`: an existing agent.nix may
|
||||
# carry either the pre-rename `hyperhive.*` path or the current one, and only
|
||||
# the one it actually carries will fire. The rename shim that used to bridge
|
||||
# them is gone from ./renamed-options.nix — a rename pointing at an
|
||||
# undeclared option breaks evaluation for everyone, removed or not.
|
||||
# carry either the `hyperhive.*` path or the `services.hyperhive.agent.*`
|
||||
# one, and only the one it actually carries will fire. Neither is an entry
|
||||
# in ./renamed-options.nix — a rename pointing at an undeclared option
|
||||
# breaks evaluation for everyone, removed or not.
|
||||
(lib.mkRemovedOptionModule [ "hyperhive" "matrix" "enable" ] matrixEnableRemoved)
|
||||
(lib.mkRemovedOptionModule [ "services" "hyperhive" "agent" "matrix" "enable" ] matrixEnableRemoved)
|
||||
];
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@
|
|||
let
|
||||
userName = config.services.hyperhive.agent.user.name;
|
||||
# The token the agent fetched from the swarm secret store
|
||||
# (./forge-token.nix), then the state-dir file the hive used to write,
|
||||
# which is still the only copy for an agent without a store identity.
|
||||
# (./forge-token.nix), then the state-dir file the hive writes, which is
|
||||
# the only copy for an agent without a store identity.
|
||||
# Both are PATHS; each reader below takes the first that holds a token.
|
||||
fetchedTokenFile = config.services.hyperhive.agent.forge.tokenFile;
|
||||
stateTokenFile = "/agents/${userName}/state/forge-token";
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ let
|
|||
# per-agent "does this agent have a homeserver to reach" fact. So an agent the
|
||||
# hive handed no homeserver URL, whose operator declared no external account
|
||||
# either, has an empty set here and gets none of the units — the case the
|
||||
# deleted `matrix.enable = false` used to express.
|
||||
# "matrix off" case.
|
||||
#
|
||||
# No cycle: `matrixAccounts`'s own definition reads `matrix.url`, never this
|
||||
# binding, so the `mkIf`s below may read the merged option value freely.
|
||||
|
|
@ -75,9 +75,9 @@ in
|
|||
then talks to the wrong machine. An absent integration, never a
|
||||
misdirected one.
|
||||
|
||||
`null` is also this agent's **matrix off switch**, and the
|
||||
replacement for the `services.hyperhive.agent.matrix.enable`
|
||||
boolean that used to exist: the hive-internal `main` account in
|
||||
`null` is also this agent's **matrix off switch** — there is no
|
||||
separate `services.hyperhive.agent.matrix.enable` boolean: the
|
||||
hive-internal `main` account in
|
||||
`services.hyperhive.agent.matrixAccounts` is declared from this
|
||||
URL, so `null` leaves that set empty and the whole integration —
|
||||
daemon unit, path watcher, injected MCP entry — is not generated
|
||||
|
|
@ -214,12 +214,11 @@ in
|
|||
|
||||
config = {
|
||||
assertions = [
|
||||
# The "extras require `matrix.enable`" assertion that used to head this
|
||||
# list is gone with the option: a non-empty account set is now what
|
||||
# enables matrix, so the condition it checked has become the definition
|
||||
# of the thing it was checking. An operator declaring only an external
|
||||
# account, with no hive homeserver, is a config this module now renders
|
||||
# rather than rejects — matrix on, no `main`.
|
||||
# There is no "extras require `matrix.enable`" assertion: a non-empty
|
||||
# account set is what enables matrix, so that condition is the
|
||||
# definition of the thing it would check. An operator declaring only an
|
||||
# external account, with no hive homeserver, gets a rendered config —
|
||||
# matrix on, no `main`.
|
||||
#
|
||||
# `main` is not a forbidden key --- this module declares it
|
||||
# itself (see the `matrixAccounts.main` definition below), so the
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
# Deprecation shims for the agent tier's old option namespace.
|
||||
# Deprecation shims for the agent tier's top-level `hyperhive.*` spelling.
|
||||
#
|
||||
# Every per-agent option used to live at the top level, `hyperhive.<name>`,
|
||||
# while the host tier has always been under `services.hyperhive.*`. The agent
|
||||
# tier moved to `services.hyperhive.agent.<name>`; these entries keep an
|
||||
# existing `agent.nix` evaluating (with a deprecation warning) against the old
|
||||
# spelling.
|
||||
# Per-agent options live at `services.hyperhive.agent.<name>`, beside the host
|
||||
# tier's `services.hyperhive.*`. These entries keep an `agent.nix` that still
|
||||
# uses the top-level `hyperhive.<name>` spelling evaluating, with a
|
||||
# deprecation warning.
|
||||
#
|
||||
# ⚠️ One entry per LEAF, not per namespace. A single entry for a parent path
|
||||
# only covers its children when the parent is a submodule-typed option; every
|
||||
|
|
@ -119,9 +118,9 @@
|
|||
[ "hyperhive" "logs" "queryUrl" ]
|
||||
[ "services" "hyperhive" "agent" "logs" "queryUrl" ]
|
||||
)
|
||||
# `matrix.enable` is deliberately absent from this list: the option it
|
||||
# renamed to no longer exists, and a rename pointing at an undeclared
|
||||
# option breaks evaluation for everyone. Both of its spellings are
|
||||
# `matrix.enable` is deliberately absent from this list: it has no
|
||||
# replacement option, and a rename pointing at an undeclared option
|
||||
# breaks evaluation for everyone. Both of its spellings are
|
||||
# `mkRemovedOptionModule` in ./default.nix instead.
|
||||
(lib.mkRenamedOptionModule
|
||||
[ "hyperhive" "matrix" "url" ]
|
||||
|
|
|
|||
|
|
@ -239,8 +239,8 @@ in
|
|||
# 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: it was renamed
|
||||
# earlier and its shim lives in ./hive-matrix.nix, so that file is the one
|
||||
# the other `*.package` moves. ⚠️ `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
|
||||
[ "services" "hyperhive" "swarm" "matrix" "openFirewall" ]
|
||||
|
|
@ -255,7 +255,7 @@ in
|
|||
[ "services" "hyperhive" "deploy" "matrix" "maxRequestSize" ]
|
||||
)
|
||||
# Both spellings of the registration token, removed rather than renamed:
|
||||
# the homeserver no longer accepts a shared registration secret at all,
|
||||
# the homeserver does not accept a shared registration secret at all,
|
||||
# so there is no path to point a definition at. Accounts are created by
|
||||
# the swarm's appservice.
|
||||
(lib.mkRemovedOptionModule [ "services" "hyperhive" "swarm" "matrix" "registrationTokenFile" ] ''
|
||||
|
|
@ -301,28 +301,27 @@ in
|
|||
[ "services" "hyperhive" "deploy" "victorialogs" "retentionPeriod" ]
|
||||
)
|
||||
|
||||
# The switch over all of the above, and the name changes with the path
|
||||
# because the old one described the wrong subject: those services are
|
||||
# required of the SWARM, while the option says whether THIS host runs
|
||||
# them. `allSwarmServices` is mara's own phrasing of what it means.
|
||||
# The switch over all of the above. `allSwarmServices` says whether THIS
|
||||
# host runs every service the swarm requires; those services are
|
||||
# required of the SWARM, so the name is about the swarm rather than this
|
||||
# host's wiring.
|
||||
(lib.mkRenamedOptionModule
|
||||
[ "services" "hyperhive" "swarm" "enableRequiredServices" ]
|
||||
[ "services" "hyperhive" "deploy" "allSwarmServices" ]
|
||||
)
|
||||
|
||||
# The mode above that one. It sat at the TOP of `services.hyperhive`,
|
||||
# which is the same defect one tier up: that namespace is everything
|
||||
# about hyperhive, not the settings of a single hive. The new name says
|
||||
# what the mode asserts — the whole swarm runs on this host — instead of
|
||||
# naming its mechanism.
|
||||
# The mode above that one lives under `deploy`, not at the TOP of
|
||||
# `services.hyperhive`: that namespace is everything about hyperhive, not
|
||||
# the settings of a single hive. `singleHostSwarm` names what the mode
|
||||
# asserts — the whole swarm runs on this host — instead of its mechanism.
|
||||
(lib.mkRenamedOptionModule
|
||||
[ "services" "hyperhive" "enableAllLocalDefaults" ]
|
||||
[ "services" "hyperhive" "deploy" "singleHostSwarm" ]
|
||||
)
|
||||
|
||||
# The hive TLS state dir sat at the TOP of `services.hyperhive`, which is
|
||||
# meant to be everything about hyperhive rather than the settings of one
|
||||
# hive. `hive-controller` is hive-c0re's new name (mara, on the issue).
|
||||
# The hive TLS state dir lives under `deploy.hive-controller` (the
|
||||
# hive-c0re daemon's namespace), not at the TOP of `services.hyperhive`,
|
||||
# which is everything about hyperhive rather than the settings of one hive.
|
||||
(lib.mkRenamedOptionModule
|
||||
[ "services" "hyperhive" "tls" "stateDir" ]
|
||||
[ "services" "hyperhive" "deploy" "hive-controller" "tls" "stateDir" ]
|
||||
|
|
|
|||
|
|
@ -86,8 +86,8 @@ in
|
|||
clientKeyFile = lib.mkDefault "${pkiDir}/client-key.pem";
|
||||
serverCaFile = lib.mkDefault "${pkiDir}/ca.pem";
|
||||
|
||||
# 🩸 Readers that used to present `client.pem` above, each now pointed at
|
||||
# a leaf of its own. The leaf is what bao sees, so this pairing is the
|
||||
# 🩸 The readers below each present a leaf of their own rather than
|
||||
# `client.pem` above. The leaf is what bao sees, so this pairing is the
|
||||
# whole of what turns "one principal with the union of their grants" into
|
||||
# one principal per grant — see ./swarm-bao.nix's `perHiveReaders` block
|
||||
# for the grants themselves.
|
||||
|
|
@ -193,11 +193,11 @@ in
|
|||
[ -s ${pkiDir}/matrix-ctl.pem ] || ${signLeaf} ${pkiDir} matrix-ctl \
|
||||
${lib.escapeShellArg deployCfg.bao.matrixCtlCommonName} "" clientAuth
|
||||
|
||||
# 🩸 The readers that used to present `client.pem` above. Each carries
|
||||
# 🩸 The readers' leaves, separate from `client.pem` above. Each carries
|
||||
# its own subject, which is the entire mechanism: bao matches a
|
||||
# cert-auth role on the CN, so units sharing one leaf were one principal
|
||||
# holding the union of their grants, and the union included every agent
|
||||
# credential in the swarm.
|
||||
# cert-auth role on the CN, so units sharing one leaf would be one
|
||||
# principal holding the union of their grants, and the union would
|
||||
# include every agent credential in the swarm.
|
||||
#
|
||||
# ⚠️ The first carries THIS hive's name in the subject, unlike the three
|
||||
# service leaves above. Its grant names one hive's path, because a queue
|
||||
|
|
|
|||
|
|
@ -42,9 +42,9 @@ let
|
|||
# a certificate the store accepts, and that is true on the store's own host
|
||||
# and on a hive three networks away for exactly the same reason.
|
||||
#
|
||||
# 🩸 This principal's OWN leaf, not `clientCertFile` — the hive's, which four
|
||||
# units used to share. Bao matches a cert-auth role on the CN, so one leaf for
|
||||
# four readers was ONE principal holding the union of four grants: read on
|
||||
# 🩸 This principal's OWN leaf, not `clientCertFile` — the hive's. Bao
|
||||
# matches a cert-auth role on the CN, so one leaf shared by four readers
|
||||
# would be ONE principal holding the union of four grants: read on
|
||||
# `swarm/agents/*` AND `swarm/hives/<hive>/*` AND `swarm/services/*`, when
|
||||
# this unit reads one queue credential and nothing else. Its own leaf carries
|
||||
# `<queueAgentCommonNamePrefix>-<hive>` and its role grants the single path
|
||||
|
|
@ -53,11 +53,11 @@ let
|
|||
baoDeploy.queueAgentClientCertFile != null && baoDeploy.queueAgentClientKeyFile != null;
|
||||
|
||||
# Does this host read the store at all — the hive's own leaf, which is the
|
||||
# one thing a remote-store deployment has always had to place by hand. Only
|
||||
# used to decide whether a missing per-principal leaf is a mistake or a
|
||||
# deployment that has no store: a host holding neither is the supported
|
||||
# no-store shape, and one holding this pair but not the pair above stopped
|
||||
# short of naming this reader's own.
|
||||
# one thing a remote-store deployment has to place by hand. Only used to
|
||||
# decide whether a missing per-principal leaf is a mistake or a deployment
|
||||
# that has no store: a host holding neither is the supported no-store
|
||||
# shape, and one holding this pair but not the pair above reads the store
|
||||
# without a reader identity of its own.
|
||||
hiveReaderIdentity = baoDeploy.clientCertFile != null && baoDeploy.clientKeyFile != null;
|
||||
|
||||
credentialDir = toString deployCfg.hive-controller.queue.agentCredentialDir;
|
||||
|
|
|
|||
|
|
@ -115,17 +115,14 @@ in
|
|||
HYPERHIVE_OTEL_EXTRA_RESOURCE_ATTRIBUTES = otel.extraResourceAttributes;
|
||||
}
|
||||
# HYPERHIVE_OTEL_HEADERS_CREDENTIAL is deliberately NOT emitted, and
|
||||
# its absence is the security half of this design: it was the variable
|
||||
# that put the upstream token into an agent's own settings.json. The
|
||||
# delivery path it drove — an nspawn credential forwarded by
|
||||
# host_config.rs, then written to an agent-readable file by
|
||||
# claude-settings.nix's `hive-otel-header` oneshot — no longer exists
|
||||
# anywhere; it was removed along with this variable's last consumer.
|
||||
# its absence is the security half of this design: that variable would
|
||||
# put the upstream token into an agent's own settings.json. Nothing
|
||||
# delivers the token into the container — no nspawn credential, no
|
||||
# agent-readable header file.
|
||||
#
|
||||
# Kept as a comment rather than deleted because the useful part is the
|
||||
# RULE, not the history: the collector holding the credential achieves
|
||||
# nothing while anything else hands out a copy, so there is exactly one
|
||||
# holder and it is on the host.
|
||||
# The rule: the collector holding the credential achieves nothing while
|
||||
# anything else hands out a copy, so there is exactly one holder and it
|
||||
# is on the host.
|
||||
// lib.optionalAttrs (otel.metricIntervalMs != null) {
|
||||
HYPERHIVE_OTEL_METRIC_INTERVAL_MS = toString otel.metricIntervalMs;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -207,11 +207,8 @@ in
|
|||
|
||||
# `caTrust.containerOrdering` orders this unit after `hive-tls-ca.service`
|
||||
# in self-signed mode (see the hive-ca-trust helper). Runner registration
|
||||
# is no longer on the boot-critical path — hive-c0re owns it out of band —
|
||||
# so the container boots immediately and needs no start-timeout bump. The
|
||||
# former `TimeoutStartSec = mkForce "180s"` band-aid (which papered over a
|
||||
# boot-path forge + core-token round-trip that could trip the nspawn start
|
||||
# timeout into a ~60s restart loop) is gone with that move.
|
||||
# is not on the boot-critical path — hive-c0re owns it out of band — so
|
||||
# the container boots immediately and needs no start-timeout bump.
|
||||
systemd.services."container@hive-ci" = caTrust.containerOrdering;
|
||||
|
||||
containers.hive-ci = {
|
||||
|
|
@ -415,7 +412,7 @@ in
|
|||
# runner stays down (Restart=on-failure retries) until c0re
|
||||
# registers it, rather than blocking the container's start.
|
||||
#
|
||||
# No nix-daemon wait anymore: builds route through the HOST daemon
|
||||
# No nix-daemon wait: builds route through the HOST daemon
|
||||
# (bound socket above), which is up before the container — nix's
|
||||
# own connect retries cover any brief window. `mkBefore` runs this
|
||||
# ahead of any upstream pre-steps.
|
||||
|
|
|
|||
|
|
@ -142,11 +142,6 @@ in
|
|||
matter for access from outside the host. Flip to `true` when
|
||||
you want the operator's browser or external git clients to
|
||||
hit the forge directly.
|
||||
|
||||
**Breaking change**: this used to default to `true`. If you
|
||||
relied on the old default for external reach, add
|
||||
`services.hyperhive.deploy.forgejo.openFirewall = true;` to your
|
||||
host config before rebuilding.
|
||||
'';
|
||||
};
|
||||
|
||||
|
|
@ -783,7 +778,7 @@ in
|
|||
Group = "forgejo";
|
||||
SyslogIdentifier = "forgejo-sso-source";
|
||||
};
|
||||
# `FORGEJO_CUSTOM` (not `GITEA_CUSTOM` — forgejo renamed it)
|
||||
# `FORGEJO_CUSTOM` (the forgejo-prefixed name, not `GITEA_CUSTOM`)
|
||||
# is how the CLI finds the app.ini upstream's module wrote.
|
||||
#
|
||||
# This unit is also a trust-bundle consumer (declared in the
|
||||
|
|
@ -930,29 +925,25 @@ in
|
|||
# re-mint instead of being silently masked by a stamp that
|
||||
# outlived what it claims exists.
|
||||
if [ ! -s "$token_path" ]; then
|
||||
# `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.
|
||||
# `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.
|
||||
#
|
||||
# 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.
|
||||
# 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.
|
||||
out=$(forgejo admin user generate-access-token \
|
||||
--username ${lib.escapeShellArg swarmControllerForgeUser} \
|
||||
--token-name "swarm-controller-boot-$(date +%s)" \
|
||||
|
|
|
|||
|
|
@ -30,9 +30,10 @@ let
|
|||
effectiveRootUrl = if cfg.rootUrl != null then cfg.rootUrl else defaultRootUrl;
|
||||
in
|
||||
{
|
||||
# Forge moved under `swarm` when the swarm-global services were
|
||||
# consolidated. One rename for the namespace: the subtree comes with it,
|
||||
# so existing hives keep evaluating and get one warning naming both paths.
|
||||
# Forge lives under `swarm`, beside the other swarm-global services. One
|
||||
# rename for the top-level `services.hyperhive.forge` namespace: the
|
||||
# subtree comes with it, so existing hives keep evaluating and get one
|
||||
# warning naming both paths.
|
||||
imports = [
|
||||
(lib.mkRenamedOptionModule
|
||||
[ "services" "hyperhive" "forge" ]
|
||||
|
|
|
|||
|
|
@ -55,10 +55,9 @@ let
|
|||
# `cfg.useSelfSigned` (options.nix) is the derived single source of truth.
|
||||
useSelfSigned = cfg.useSelfSigned;
|
||||
|
||||
# nginx's own state dir. Kept at the historical `/var/lib/hive-gateway`
|
||||
# path rather than renamed with the move: it holds the imported leaf
|
||||
# across reboots, and renaming it would strand every existing hive's
|
||||
# certs for no gain.
|
||||
# nginx's own state dir, fixed at `/var/lib/hive-gateway` independent of
|
||||
# this module's own path: it holds the imported leaf across reboots, and
|
||||
# a different path would strand every existing hive's certs.
|
||||
tlsDir = "/var/lib/hive-gateway/tls";
|
||||
# TLS cert + key paths.
|
||||
# - self-signed (default): the hive leaf the store issues (the
|
||||
|
|
@ -207,14 +206,12 @@ in
|
|||
# before c0re has run, and pin owner + mode rather than leaving it
|
||||
# to whoever creates the path first.
|
||||
#
|
||||
# ⚠️ There is deliberately NO rule for /var/lib/hyperhive here. One
|
||||
# used to declare it `0755 root root` and could never win:
|
||||
# ⚠️ There is deliberately NO rule for /var/lib/hyperhive here.
|
||||
# `hive-c0re.service` sets `StateDirectory = "hyperhive"` with
|
||||
# `StateDirectoryMode = "0750"`, which systemd re-applies on every
|
||||
# start. Two mechanisms owning one path, and the loser still read as
|
||||
# a guarantee — it is why the resulting outage was first misdiagnosed
|
||||
# as someone having changed the mode. c0re's own unit owns that dir;
|
||||
# this module no longer has an opinion about it.
|
||||
# start, so a tmpfiles rule for the same path could never win: two
|
||||
# mechanisms owning one path, the loser still reading as a guarantee.
|
||||
# c0re's own unit owns that dir; this module has no opinion about it.
|
||||
systemd.tmpfiles.rules = [
|
||||
# The gateway's own config dir — NOT under /var/lib/hyperhive. c0re
|
||||
# writes here, nginx reads here, and neither needs any access to the
|
||||
|
|
@ -393,23 +390,15 @@ in
|
|||
# ⚠️ NO `SupplementaryGroups = [ "hive-core" ]` on nginx, and its
|
||||
# absence is load-bearing rather than an omission.
|
||||
#
|
||||
# It used to be here, to let nginx traverse `/var/lib/hyperhive` and
|
||||
# reach the config fragments that lived inside: `hive-c0re.service`
|
||||
# declares `StateDirectory = "hyperhive"` with `StateDirectoryMode =
|
||||
# "0750"` owned by `hive-core`, and systemd re-applies that on every
|
||||
# c0re start — beating this module's own tmpfiles rule for the same
|
||||
# path. Without the group, nginx failed its config test and never
|
||||
# started (`nginx: [emerg] open() ".../agents.conf" failed (13:
|
||||
# Permission denied)`), taking the gateway and every hive domain
|
||||
# behind it down.
|
||||
#
|
||||
# The group fixed the symptom and paid for it: it also gave nginx
|
||||
# read access to everything ELSE group-readable under that dir,
|
||||
# including the broker sqlite — i.e. every message between every
|
||||
# agent, reachable by the process whose entire job is parsing
|
||||
# untrusted network input. Moving the fragments to the gateway's own
|
||||
# dir removes the need and the exposure together. Re-adding this line
|
||||
# would restore both.
|
||||
# `hive-c0re.service` declares `StateDirectory = "hyperhive"` with
|
||||
# `StateDirectoryMode = "0750"` owned by `hive-core`, and systemd
|
||||
# re-applies that on every c0re start. The group would let nginx
|
||||
# traverse that dir, but it also gives nginx read access to everything
|
||||
# ELSE group-readable under it, including the broker sqlite — i.e.
|
||||
# every message between every agent, reachable by the process whose
|
||||
# entire job is parsing untrusted network input. The config fragments
|
||||
# nginx reads live in the gateway's own dir instead, so nginx needs no
|
||||
# access to c0re's tree. Adding this line would reopen that exposure.
|
||||
|
||||
networking.firewall = lib.mkIf cfg.openFirewall {
|
||||
allowedTCPPorts = [
|
||||
|
|
@ -424,12 +413,11 @@ in
|
|||
# every name a service module contributed. See `docs/networking/gateway.md`
|
||||
# ("Local dev").
|
||||
#
|
||||
# This used to restate the per-service list a THIRD time (after the
|
||||
# vhosts and the dnsmasq records), with its own copy of each
|
||||
# service's guard. It is the same question — "which names does this
|
||||
# host answer for" — so it reads the same answer; a service added
|
||||
# later lands here with no edit, and cannot land here with a
|
||||
# different condition than it used for DNS.
|
||||
# This does not restate the per-service list (the vhosts and the
|
||||
# dnsmasq records already carry it). It is the same question —
|
||||
# "which names does this host answer for" — so it reads the same
|
||||
# answer; a service added later lands here with no edit, and cannot
|
||||
# land here with a different condition than it used for DNS.
|
||||
networking.hosts = lib.mkIf cfg.localHostsEntry {
|
||||
"127.0.0.1" = lib.unique ([ hyperhiveDomain ] ++ cfg.localNames);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -82,10 +82,6 @@ in
|
|||
nginx vhost. Leave off when running behind another reverse
|
||||
proxy (e.g. caddy / traefik on the host) that handles TLS
|
||||
termination + forwards to `port`.
|
||||
|
||||
**Note**: this used to default to `true`. Add
|
||||
`services.hyperhive.gateway.openFirewall = true;` to your host
|
||||
config if external reach stopped working after a recent upgrade.
|
||||
'';
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -187,22 +187,19 @@ let
|
|||
# Swagger UI: nginx hosts the FULL themed dist (`swaggerUiTheme` —
|
||||
# vendored Swagger UI + our overlay, see nix/packages/swagger-ui-
|
||||
# dist.nix + swagger-ui-theme.nix) straight from the store, with NO
|
||||
# fallback to hive-c0re at all — per the operator's shape: "core
|
||||
# should not need the swagger ui at all if it is hosted in gateway"
|
||||
# / "core only hosts the json". Only `/api/openapi.json`
|
||||
# (the live-generated spec `index.html` fetches; not under this
|
||||
# prefix) still proxies to c0re via "/api/" below — that's the one
|
||||
# thing that has to stay dynamic.
|
||||
# fallback to hive-c0re at all: core hosts only the JSON. Only
|
||||
# `/api/openapi.json` (the live-generated spec `index.html` fetches;
|
||||
# not under this prefix) proxies to c0re via "/api/" below — that's
|
||||
# the one thing that has to stay dynamic.
|
||||
#
|
||||
# Prefix location, not exact-match: wins over "/api/" on plain
|
||||
# prefix length (no ordering/`=` needed), and now needs to cover
|
||||
# every file in the tree (bundle.js, maps, favicons, …), not just
|
||||
# our 2 override files — hive-c0re no longer serves any of this as
|
||||
# a fallback once its own `utoipa-swagger-ui` mount is removed.
|
||||
# `= /api/docs` (no trailing slash) issues the same redirect
|
||||
# `utoipa-swagger-ui`'s router used to: that mount is going away
|
||||
# too, so nginx has to own it now, or the H0M3 hub's own `/api/docs`
|
||||
# link (no trailing slash) would 404 once hive-c0re drops the route.
|
||||
# prefix length (no ordering/`=` needed), and covers every file in
|
||||
# the tree (bundle.js, maps, favicons, …), not just our 2 override
|
||||
# files — hive-c0re serves none of this as a fallback.
|
||||
# `= /api/docs` (no trailing slash) redirects to `/api/docs/`: nginx
|
||||
# owns that redirect because hive-c0re has no route for it, and the
|
||||
# H0M3 hub's own `/api/docs` link (no trailing slash) would 404
|
||||
# without it.
|
||||
swaggerUiLocations = {
|
||||
"= /api/docs" = {
|
||||
extraConfig = ''
|
||||
|
|
|
|||
|
|
@ -153,12 +153,11 @@ let
|
|||
# to host it — otherwise moving the container between hives would look
|
||||
# like a different homeserver.
|
||||
#
|
||||
# ⚠️ Changing this default is a BREAKING change in a way that moving
|
||||
# `gatewayHost` was not: `serverName` is baked irrevocably into every
|
||||
# user and room id, so a deployment that rebuilds onto a new one is a
|
||||
# *different homeserver*, not a renamed one. Existing hives pin the old
|
||||
# value explicitly (see the option's description); the default is what
|
||||
# a fresh swarm gets.
|
||||
# ⚠️ Changing this default is breaking: `serverName` is baked
|
||||
# irrevocably into every user and room id, so a deployment that
|
||||
# rebuilds onto a new one is a *different homeserver*. Existing hives
|
||||
# pin their value explicitly (see the option's description); the
|
||||
# default is what a fresh swarm gets.
|
||||
#
|
||||
# Total on a null swarm domain, deliberately: the required-domain
|
||||
# assertion in hive-network.nix is what should fire, not a coercion
|
||||
|
|
@ -251,9 +250,10 @@ in
|
|||
# settings: docs/integrations/matrix.md. Vhost map + discovery flow + tuning
|
||||
# knobs: docs/networking/gateway.md.
|
||||
|
||||
# Matrix moved under `swarm` when the swarm-global services were
|
||||
# consolidated. One rename for the namespace: the subtree comes with it,
|
||||
# so existing hives keep evaluating and get one warning naming both paths.
|
||||
# Matrix lives under `swarm`, beside the other swarm-global services. One
|
||||
# rename for the top-level `services.hyperhive.matrix` namespace: the
|
||||
# subtree comes with it, so existing hives keep evaluating and get one
|
||||
# warning naming both paths.
|
||||
imports = [
|
||||
(lib.mkRenamedOptionModule
|
||||
[ "services" "hyperhive" "matrix" ]
|
||||
|
|
@ -311,11 +311,6 @@ in
|
|||
the homeserver to other hives or when an external matrix
|
||||
client needs to reach the client-server API directly.
|
||||
|
||||
**Breaking change**: this used to default to `true`. If you
|
||||
relied on the old default for external reach, add
|
||||
`services.hyperhive.deploy.matrix.openFirewall = true;` to your host
|
||||
config before rebuilding.
|
||||
|
||||
Note: federation (the matrix-spec well-known port 8448) is
|
||||
intentionally not opened here. tuwunel serves the federation
|
||||
API on the same `httpPort` as the client-server API by
|
||||
|
|
|
|||
|
|
@ -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 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.
|
||||
# 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.
|
||||
want_svc=${if localServiceDomains == [ ] then "0" else "1"}
|
||||
|
||||
# Expiry is not the only way a leaf goes wrong. One signed when the
|
||||
|
|
@ -346,17 +346,14 @@ in
|
|||
};
|
||||
|
||||
config = lib.mkIf active {
|
||||
# 🚫 The "these service names are outside this hive's domain and this
|
||||
# host cannot sign for them" warning is GONE, and its absence is the
|
||||
# deliverable rather than a tidy-up. It fired on
|
||||
# `!swarm.ca.autoConfigure` — i.e. "this host does not hold the swarm
|
||||
# root key" — which was the whole reason a hive could end up serving
|
||||
# its own leaf on a swarm-service name. The services leaf now comes
|
||||
# from the secret store's `pki` mount, which every hive reaches over
|
||||
# the network with its own identity, so holding the root key stopped
|
||||
# being the thing that decides. Left in place it would warn, on every
|
||||
# rebuild of every hive that is not the CA host, about a fallback
|
||||
# that no longer happens.
|
||||
# 🚫 There is deliberately NO warning that these service names are
|
||||
# outside this hive's domain and this host cannot sign for them. The
|
||||
# services leaf comes from the secret store's `pki` mount, which every
|
||||
# hive reaches over the network with its own identity, so holding the
|
||||
# swarm root key does not decide whether a hive can serve a
|
||||
# swarm-service name. Such a warning would fire on every rebuild of
|
||||
# every hive that is not the CA host, about a fallback that does not
|
||||
# happen.
|
||||
|
||||
# The state dir and the trust bundle. Never waits on the store: the
|
||||
# store's container is ordered after this unit, which writes the
|
||||
|
|
|
|||
|
|
@ -103,8 +103,8 @@ in
|
|||
|
||||
# Where the swarm lives. Declared beside the hive's own identity
|
||||
# because it is what that identity is derived FROM — every hive in a
|
||||
# swarm is a sub-domain of it. Unlike the renamed options nearby, this
|
||||
# is genuinely new: nothing moved here, so there is no alias.
|
||||
# swarm is a sub-domain of it. No alias: this option has no earlier
|
||||
# spelling.
|
||||
options.services.hyperhive.swarm.domain = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
|
|
@ -145,7 +145,7 @@ in
|
|||
(`services.hyperhive.deploy.hive-controller.enable`,
|
||||
`deploy.bao.enable`, `deploy.matrix.enable`). Distinct from
|
||||
`services.hyperhive.domain` (the machine-addressable DNS name)
|
||||
but no longer merely cosmetic: a hive occupies
|
||||
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
|
||||
|
|
|
|||
|
|
@ -60,9 +60,8 @@ in
|
|||
# rather than the file.
|
||||
#
|
||||
# ⛔ **Do not hand this path to a consumer that reads only ONE
|
||||
# certificate from it.** This comment used to offer an OIDC verifier's
|
||||
# `issuer_ca_path` as the motivating example; that is exactly what took
|
||||
# the swarm collector down for forty minutes once. The bundle is
|
||||
# certificate from it** — an OIDC verifier's `issuer_ca_path` is
|
||||
# exactly such a reader, and takes the swarm collector down. The bundle is
|
||||
# `system CAs ++ hive anchors`, so the anchor is ~123rd, and a
|
||||
# first-certificate-only reader gets whichever public CA sorts first and
|
||||
# can verify nothing of ours — with a full, valid, 125-certificate file
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ in
|
|||
⚠️ The collector is therefore in the path of all telemetry. It runs
|
||||
on the same host as the agents and restarts on failure, and
|
||||
telemetry is not the control plane, so degraded telemetry is not
|
||||
degraded operation — but the export no longer survives independently
|
||||
degraded operation — but the export does not survive independently
|
||||
of anything host-side
|
||||
'';
|
||||
|
||||
|
|
@ -239,7 +239,7 @@ in
|
|||
onward, which is one hop for the whole hive rather than one per
|
||||
target.
|
||||
|
||||
No longer empty on a default hive: this collector's own endpoint
|
||||
Not empty on a default hive: this collector's own endpoint
|
||||
is always in here, so the scrape receiver is emitted everywhere.
|
||||
The `!= { }` guards around it stay meaningful — the set can still
|
||||
be forced empty, and a `prometheus` receiver with nothing to
|
||||
|
|
|
|||
|
|
@ -132,10 +132,10 @@ in
|
|||
tracked as a follow-up rather than papered over.
|
||||
|
||||
On by default: a swarm's hives have identities, and that is a
|
||||
fact about the swarm rather than about any one host. It used to
|
||||
default to whether the queue ran on *this* machine, which made
|
||||
the answer differ between two hosts of one swarm — set it false
|
||||
for a swarm whose hives authenticate to nothing.
|
||||
fact about the swarm rather than about any one host. It does not
|
||||
depend on whether the queue runs on *this* machine, so the answer
|
||||
is the same on every host of one swarm — set it false for a swarm
|
||||
whose hives authenticate to nothing.
|
||||
|
||||
The clients are inert until something authenticates with them:
|
||||
each is a client id and a secret sitting on this host. What
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue