deploy: move the queue toggle
Same shape as the others. Three of the eight references were prose rather than code: two assertion messages naming the option to an operator, and a `defaultText` in the authelia module, whose `oidc.hiveIdentities` derives from whether the queue runs here. Also corrects a comment in swarm.nix that this commit's own hunk sits directly beneath. It said `enableRequiredServices` turns on matrix and authelia "but NOT nats (nats has no mode that enables it)", which stopped being true when the queue was added to that switch — before this change, not by it. The reasoning it introduces is still right and still worth keeping; only the premise had expired.
This commit is contained in:
parent
37ca7676d6
commit
64e8c62f18
7 changed files with 45 additions and 30 deletions
|
|
@ -57,6 +57,10 @@ in
|
|||
[ "services" "hyperhive" "swarm" "authelia" "enable" ]
|
||||
[ "services" "hyperhive" "deploy" "authelia" ]
|
||||
)
|
||||
(lib.mkRenamedOptionModule
|
||||
[ "services" "hyperhive" "swarm" "nats" "enable" ]
|
||||
[ "services" "hyperhive" "deploy" "nats" ]
|
||||
)
|
||||
];
|
||||
|
||||
options.services.hyperhive.deploy = {
|
||||
|
|
@ -119,6 +123,19 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
nats = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Run the swarm's message queue in a `swarm-nats` container on this
|
||||
host. A swarm has one queue, so this belongs on the same host as
|
||||
the rest of the shared services.
|
||||
|
||||
Off by default, and off means *absent*: no container is created
|
||||
and nothing else in the evaluated config changes.
|
||||
'';
|
||||
};
|
||||
|
||||
controller = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ in
|
|||
# ran its first boot on — so they belong to the mode that asserts this
|
||||
# box is the whole deployment, not to the options' own `default`.
|
||||
#
|
||||
# Deriving them from `swarm.nats.enable` / `deploy.authelia`
|
||||
# Deriving them from `deploy.nats` / `deploy.authelia`
|
||||
# inside those defaults is the mixing this file exists to prevent: the
|
||||
# option would be describing a deployment shape instead of describing
|
||||
# itself, and "what does all-local turn on?" would stop having one
|
||||
|
|
|
|||
|
|
@ -467,8 +467,8 @@ in
|
|||
|
||||
oidc.hiveIdentities = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = hyperhiveCfg.swarm.nats.enable;
|
||||
defaultText = lib.literalExpression "services.hyperhive.swarm.nats.enable";
|
||||
default = deployCfg.nats;
|
||||
defaultText = lib.literalExpression "services.hyperhive.deploy.nats";
|
||||
description = ''
|
||||
Mint one machine client per hive in
|
||||
{option}`services.hyperhive.swarm.hives`, so each hive can
|
||||
|
|
|
|||
|
|
@ -539,7 +539,7 @@ in
|
|||
services.hyperhive.swarm.controller.queue.natsUrl is unset.
|
||||
|
||||
It defaults to loopback only when this host also runs the queue
|
||||
(`services.hyperhive.swarm.nats.enable`). A controller on its
|
||||
(`services.hyperhive.deploy.nats`). A controller on its
|
||||
own host has to be told where the queue is.
|
||||
'';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ let
|
|||
hostPath = name: "${secretDir}/${name}";
|
||||
|
||||
# The responder needs all three credentials. Gating on them rather than
|
||||
# on `cfg.enable` keeps a half-configured hive at "queue up, denying
|
||||
# on `deployCfg.nats` keeps a half-configured hive at "queue up, denying
|
||||
# everyone" instead of "unit crash-looping on a missing file".
|
||||
#
|
||||
# In auto mode the seeds are minted on this host before the container
|
||||
|
|
@ -210,18 +210,9 @@ in
|
|||
# per-service vhost pattern do not apply.
|
||||
|
||||
options.services.hyperhive.swarm.nats = {
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Run the swarm's message queue in a `swarm-nats` container on this
|
||||
host. A swarm has one queue, so this belongs on the same host as
|
||||
the rest of the shared services.
|
||||
|
||||
Off by default, and off means *absent*: no container is created
|
||||
and nothing else in the evaluated config changes.
|
||||
'';
|
||||
};
|
||||
# `enable` moved to `services.hyperhive.deploy.nats` — see
|
||||
# ./deploy.nix. What stays here is what the queue IS: its domain,
|
||||
# ports, accounts and callout wiring.
|
||||
|
||||
# ⚠️ Deliberately NO `package` option, unlike this module's siblings.
|
||||
# `services.nats` upstream does not expose one — it resolves
|
||||
|
|
@ -408,7 +399,7 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
config = lib.mkIf deployCfg.nats {
|
||||
# The responder as well as the server: a denial reaches the client as a
|
||||
# timeout, so the server's own log is the only place it is an error.
|
||||
services.hyperhive.swarm.otel.journaldUnits = [
|
||||
|
|
@ -423,7 +414,7 @@ in
|
|||
# several layers from "the operator never set the issuer".
|
||||
assertion = cfg.autoGenerateCallout || cfg.calloutIssuerPublicKey != "";
|
||||
message = ''
|
||||
services.hyperhive.swarm.nats.enable requires
|
||||
services.hyperhive.deploy.nats requires
|
||||
nats.calloutIssuerPublicKey — the public half of the account
|
||||
nkey that signs user JWTs for this queue.
|
||||
|
||||
|
|
@ -440,7 +431,7 @@ in
|
|||
# somebody connects.
|
||||
assertion = cfg.autoGenerateCallout || cfg.calloutUserPublicKey != "";
|
||||
message = ''
|
||||
services.hyperhive.swarm.nats.enable requires
|
||||
services.hyperhive.deploy.nats requires
|
||||
nats.calloutUserPublicKey — the public half of the user nkey
|
||||
the auth-callout responder authenticates as.
|
||||
|
||||
|
|
@ -485,7 +476,7 @@ in
|
|||
{
|
||||
assertion = autheliaUrl != null;
|
||||
message = ''
|
||||
services.hyperhive.swarm.nats.enable requires
|
||||
services.hyperhive.deploy.nats requires
|
||||
services.hyperhive.swarm.authelia.url — the queue authenticates
|
||||
clients by validating tokens that authelia issued.
|
||||
|
||||
|
|
@ -684,7 +675,7 @@ in
|
|||
# door nobody can open, which is the deliberate interim state.
|
||||
#
|
||||
# ⚠️ It is gated on the seeds being configured rather than on
|
||||
# `cfg.enable`, so a half-configured hive gets a running,
|
||||
# `deployCfg.nats`, so a half-configured hive gets a running,
|
||||
# refusing queue instead of a unit that crash-loops on a
|
||||
# missing file. A queue that denies everyone is a legible
|
||||
# failure; a restart loop is not.
|
||||
|
|
|
|||
|
|
@ -60,7 +60,6 @@ in
|
|||
# derives `nats.autoGenerateCallout` from the all-local mode, so that
|
||||
# mode was minting the queue's callout nkeys and then never starting
|
||||
# the queue they authenticate against.
|
||||
nats.enable = lib.mkDefault swarmCfg.enableRequiredServices;
|
||||
|
||||
# The metrics pair and the log store used to derive here too. They now
|
||||
# live under `deploy.*` (below, and ./deploy.nix) because "does THIS
|
||||
|
|
@ -89,6 +88,9 @@ in
|
|||
# at whoever runs it.
|
||||
config.services.hyperhive.deploy.authelia = lib.mkDefault swarmCfg.enableRequiredServices;
|
||||
|
||||
# The queue. Same rule: once per swarm, optional.
|
||||
config.services.hyperhive.deploy.nats = lib.mkDefault swarmCfg.enableRequiredServices;
|
||||
|
||||
# The metrics pair, deriving together on purpose: a store with no UI is
|
||||
# unreadable and a UI with no store is empty, so there is no sensible
|
||||
# deployment that takes one and not the other from this switch. An
|
||||
|
|
|
|||
|
|
@ -80,18 +80,23 @@ let
|
|||
# ONE condition for all three of them, deliberately.
|
||||
#
|
||||
# 🩸 They were three independent conditions first, and that was wrong in
|
||||
# a way only an eval gate finds: `enableRequiredServices` turns on
|
||||
# matrix and authelia but NOT nats (nats has no mode that enables it —
|
||||
# see the auto-deploy question on the swarm-queue issue), so an ordinary
|
||||
# all-local hive resolved authelia's two coordinates and not the queue
|
||||
# URL. Two of three set is exactly what the assertion below rejects, so
|
||||
# every `enableAllLocalDefaults` hive would have stopped evaluating.
|
||||
# a way only an eval gate finds: at the time `enableRequiredServices`
|
||||
# turned on matrix and authelia but NOT nats, so an ordinary all-local
|
||||
# hive resolved authelia's two coordinates and not the queue URL. Two of
|
||||
# three set is exactly what the assertion below rejects, so every
|
||||
# `enableAllLocalDefaults` hive would have stopped evaluating.
|
||||
#
|
||||
# (The queue does derive from that switch now — ./swarm-required-services.nix
|
||||
# — so the original asymmetry is gone. The reasoning below is why the
|
||||
# single predicate stays anyway: it makes the partial state
|
||||
# unrepresentable rather than merely detected, which does not depend on
|
||||
# which services happen to derive together this month.)
|
||||
#
|
||||
# Deriving all three from one predicate makes the partial state
|
||||
# unrepresentable rather than merely detected: a default set is all or
|
||||
# nothing, and the assertion is then only ever about what an operator
|
||||
# typed.
|
||||
queueLocal = swarmCfg.nats.enable && deployCfg.authelia && cfg.hiveName != null;
|
||||
queueLocal = deployCfg.nats && deployCfg.authelia && cfg.hiveName != null;
|
||||
in
|
||||
{
|
||||
options.services.hyperhive.swarm.hives = lib.mkOption {
|
||||
|
|
|
|||
Loading…
Reference in a new issue