Two corrections from review, applied forward on this branch rather than
by rewriting it.
`deploy.<service>` was a bare bool, which makes
`deploy.forgejo = { enable; ci; }` unrepresentable -- the nested
CI-runner sub-option this namespace was designed around. Every entry is
now an attrset with an `enable`, so a second per-host deployment
decision becomes an ordinary addition rather than a migration.
`deploy.controller` is now `deploy.swarm-controller`, consistent with
`deploy.swarm-ui`, which was introduced in the same commit.
89 references rewritten across 24 files -- nix, Rust, docs, and the
repo's own CLAUDE.md.
The prefix-anchored sweep missed exactly one, and it was live code:
hive-tls.nix spells it `hyperhiveCfg.deploy.controller` -- the only
`hyperhiveCfg` prefix among 45 references. A suffix grep
(`\.deploy\.<name>`) finds it; a path-anchored one cannot, because the
head of a reference is whatever alias the reading file happens to bind.
199 lines
7.6 KiB
Nix
199 lines
7.6 KiB
Nix
# "What does THIS host deploy?"
|
||
#
|
||
# Separated from `services.hyperhive.swarm.*` because those are two
|
||
# different kinds of fact and only one of them varies per machine:
|
||
#
|
||
# swarm.* — swarm-wide truth. The swarm's name, domain, hives, peers,
|
||
# CA, and where each service lives. **Identical on every
|
||
# host**, byte for byte; a hive needs all of it to be a
|
||
# *client* of the swarm.
|
||
# deploy.* — this machine's deployment decisions. Necessarily different
|
||
# on every host, because that is what a deployment is.
|
||
#
|
||
# The `enable` toggles used to live under `swarm.*`, which made the
|
||
# namespace that is supposed to be identical everywhere carry the one
|
||
# thing that must differ.
|
||
#
|
||
# Flat and named for the thing deployed — `deploy.forgejo`, not
|
||
# `deploy.swarmServices.forgejo`: grouping by "swarm service" re-encodes
|
||
# the service-side taxonomy into a layer that does not care about it.
|
||
#
|
||
# ⚠️ Each entry is an attrset with an `enable`, not a bare bool, so a
|
||
# service that grows a second *deployment* decision has somewhere to put
|
||
# it — `deploy.forgejo = { enable; ci; }` is then an ordinary addition
|
||
# rather than a migration. `ci` ("does this host run the runner too") is
|
||
# 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
|
||
# and a single file to delete when the deprecation window closes — the
|
||
# shape ./swarm-peers-removed.nix already uses.
|
||
{ lib, config, ... }:
|
||
let
|
||
deployCfg = config.services.hyperhive.deploy;
|
||
in
|
||
{
|
||
imports = [
|
||
# Same type, same meaning, new path — so a rename carries it exactly
|
||
# and existing configs keep evaluating with one warning naming both
|
||
# paths. Precedent: ./hive-forge/default.nix, ./hive-matrix.nix.
|
||
(lib.mkRenamedOptionModule
|
||
[ "services" "hyperhive" "swarm" "grafana" "enable" ]
|
||
[ "services" "hyperhive" "deploy" "grafana" "enable" ]
|
||
)
|
||
(lib.mkRenamedOptionModule
|
||
[ "services" "hyperhive" "swarm" "victoriametrics" "enable" ]
|
||
[ "services" "hyperhive" "deploy" "victoriametrics" "enable" ]
|
||
)
|
||
(lib.mkRenamedOptionModule
|
||
[ "services" "hyperhive" "swarm" "victorialogs" "enable" ]
|
||
[ "services" "hyperhive" "deploy" "victorialogs" "enable" ]
|
||
)
|
||
(lib.mkRenamedOptionModule
|
||
[ "services" "hyperhive" "swarm" "controller" "enable" ]
|
||
[ "services" "hyperhive" "deploy" "swarm-controller" "enable" ]
|
||
)
|
||
(lib.mkRenamedOptionModule
|
||
[ "services" "hyperhive" "swarm" "ui" "enable" ]
|
||
[ "services" "hyperhive" "deploy" "swarm-ui" "enable" ]
|
||
)
|
||
(lib.mkRenamedOptionModule
|
||
[ "services" "hyperhive" "swarm" "authelia" "enable" ]
|
||
[ "services" "hyperhive" "deploy" "authelia" "enable" ]
|
||
)
|
||
(lib.mkRenamedOptionModule
|
||
[ "services" "hyperhive" "swarm" "nats" "enable" ]
|
||
[ "services" "hyperhive" "deploy" "nats" "enable" ]
|
||
)
|
||
(lib.mkRenamedOptionModule
|
||
[ "services" "hyperhive" "swarm" "otel" "enable" ]
|
||
[ "services" "hyperhive" "deploy" "otel" "enable" ]
|
||
)
|
||
];
|
||
|
||
options.services.hyperhive.deploy = {
|
||
grafana.enable = lib.mkOption {
|
||
type = lib.types.bool;
|
||
default = false;
|
||
description = ''
|
||
Run the swarm's metrics UI on this host.
|
||
|
||
Off by default and not derived from
|
||
{option}`services.hyperhive.enable`: a swarm has one Grafana, so
|
||
running it is a decision about this host rather than about
|
||
whether hyperhive is installed.
|
||
'';
|
||
};
|
||
|
||
victoriametrics.enable = lib.mkOption {
|
||
type = lib.types.bool;
|
||
default = false;
|
||
description = ''
|
||
Run the swarm's metrics store on this host.
|
||
|
||
Derives from
|
||
{option}`services.hyperhive.swarm.enableRequiredServices` together
|
||
with {option}`services.hyperhive.deploy.grafana.enable`: 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
|
||
that switch. Set either directly to run exactly one.
|
||
'';
|
||
};
|
||
|
||
victorialogs.enable = lib.mkOption {
|
||
type = lib.types.bool;
|
||
default = false;
|
||
description = ''
|
||
Run the swarm's log store on this host.
|
||
|
||
Derives from
|
||
{option}`services.hyperhive.swarm.enableRequiredServices` for the
|
||
same reason as the metrics pair above: a hive that is not the
|
||
service host is a *client* of this store, not a second one.
|
||
'';
|
||
};
|
||
|
||
authelia.enable = lib.mkOption {
|
||
type = lib.types.bool;
|
||
default = false;
|
||
example = true;
|
||
description = ''
|
||
Run the swarm's authelia in a `swarm-authelia` container on this
|
||
host. {option}`services.hyperhive.swarm.enableRequiredServices`
|
||
turns this on — a swarm has one SSO provider, and that says it
|
||
lives here.
|
||
|
||
With it off, this hive is a *client*:
|
||
{option}`services.hyperhive.swarm.authelia.url` still points at
|
||
whoever runs it, and no container is created. That asymmetry is
|
||
why the two live in different namespaces — every hive needs the
|
||
client half, only one runs the server half.
|
||
'';
|
||
};
|
||
|
||
otel.enable = lib.mkOption {
|
||
type = lib.types.bool;
|
||
default = false;
|
||
description = ''
|
||
Run the **swarm's** telemetry collector on this host.
|
||
|
||
Derives from
|
||
{option}`services.hyperhive.swarm.enableRequiredServices` with the
|
||
metrics pair it feeds: a swarm has one of these, and it belongs
|
||
wherever the shared services live rather than on every hive.
|
||
|
||
⚠️ Not to be confused with
|
||
{option}`services.hyperhive.otel.enable`, the **hive-tier**
|
||
collector, which every hive runs and which is a different option.
|
||
A hive that does not run the swarm collector still runs its own,
|
||
and reaches this one by name at
|
||
{option}`services.hyperhive.swarm.otel.domain`.
|
||
'';
|
||
};
|
||
|
||
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.
|
||
'';
|
||
};
|
||
|
||
swarm-controller.enable = lib.mkOption {
|
||
type = lib.types.bool;
|
||
default = false;
|
||
description = ''
|
||
Run the swarm-controller daemon on this host.
|
||
|
||
Off by default and deliberately not derived from
|
||
{option}`services.hyperhive.enable`: a swarm has one controller,
|
||
so running it is a decision about this host rather than about
|
||
whether hyperhive is installed.
|
||
'';
|
||
};
|
||
|
||
swarm-ui.enable = lib.mkOption {
|
||
type = lib.types.bool;
|
||
default = deployCfg.swarm-controller.enable;
|
||
defaultText = lib.literalExpression "services.hyperhive.deploy.swarm-controller.enable";
|
||
example = true;
|
||
description = ''
|
||
Serve the swarm UI from this host.
|
||
|
||
Derived from
|
||
{option}`services.hyperhive.deploy.swarm-controller.enable` rather
|
||
than from
|
||
{option}`services.hyperhive.swarm.enableRequiredServices`: the UI
|
||
is a view onto the controller's state and reaches it over that
|
||
daemon's unix socket, so the host that runs the controller is the
|
||
host that can serve the UI. A hive that merely *uses* a swarm has
|
||
nothing to serve here.
|
||
'';
|
||
};
|
||
};
|
||
}
|