swarm: move grafana's package to deploy, beside the rest of its host knobs

Same rule as the matrix pair: which build a service runs is a decision of
the host that runs it, so `package` follows `enable` out of the namespace
every hive must agree on byte for byte.

Grafana already had a `deploy.grafana` block holding the datasources, the
plugin list and the socket directory, so this is the package joining
options it belongs with rather than a new namespace.

Prose: the swarm-side header listed "its package" among what stays; the
deploy-side header listed what the host decides without it. Both edited,
which is the fix — a substitution on the first alone would have left the
second silently incomplete.

`swarm-grafana.nix:219` was on the sweep list and is NOT edited: it says
what stays above is what the service is to every hive, and that stays
true once the package leaves. The stale half was the sentence after it.

Refs #3772.
This commit is contained in:
atlas 2026-09-07 18:46:19 +02:00
commit 0002c15dc3
3 changed files with 23 additions and 18 deletions

View file

@ -349,6 +349,10 @@ in
[ "services" "hyperhive" "swarm" "matrix" "gui" "package" ]
[ "services" "hyperhive" "deploy" "matrix" "gui" "package" ]
)
(lib.mkRenamedOptionModule
[ "services" "hyperhive" "swarm" "grafana" "package" ]
[ "services" "hyperhive" "deploy" "grafana" "package" ]
)
];
# ⚠️ `deploy.forgejo` is declared in ./hive-ci.nix, not here, and it is the

View file

@ -111,20 +111,13 @@ in
# `enable` moved to `services.hyperhive.deploy.grafana.enable` — see
# ./deploy.nix. Whether this host runs the swarm's Grafana is a
# deployment decision, and `swarm.*` has to be identical on every host.
# What stays here is what the service IS to every hive: its package, the
# name it is served under, the port its `/metrics` is re-served on, and
# the OIDC client it is registered as. What the host running it decides —
# where its datasources point, which plugins are in its store path, and
# the socket directory it shares with nginx — is below, under
# `deploy.grafana`.
# What stays here is what the service IS to every hive: the name it is
# served under, the port its `/metrics` is re-served on, and the OIDC
# client it is registered as. What the host running it decides — which
# build it runs, where its datasources point, which plugins are in its
# store path, and the socket directory it shares with nginx — is below,
# under `deploy.grafana`.
options.services.hyperhive.swarm.grafana = {
package = lib.mkOption {
type = lib.types.package;
default = pkgs.grafana;
defaultText = lib.literalExpression "pkgs.grafana";
description = "Grafana package to run.";
};
machine = lib.mkOption {
type = lib.types.str;
readOnly = true;
@ -217,15 +210,22 @@ in
};
# What stays above is what the service IS to every hive. What the host
# running it decides is here: where its datasources point, which plugins sit
# in its store path, and the directory it shares a socket with nginx
# through. `enable` already lives in ./deploy.nix, which also carries the
# renames.
# running it decides is here: which build it runs, where its datasources
# point, which plugins sit in its 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
# 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 = {
package = lib.mkOption {
type = lib.types.package;
default = pkgs.grafana;
defaultText = lib.literalExpression "pkgs.grafana";
description = "Grafana package to run.";
};
socketDir = lib.mkOption {
type = lib.types.str;
default = "/run/swarm-grafana";
@ -624,7 +624,7 @@ in
services.grafana = {
enable = true;
package = cfg.package;
package = deployCfg.grafana.package;
# Passed through unconditionally, empty default included.
# Upstream distinguishes `null` from `[ ]`, and both differences

View file

@ -160,6 +160,7 @@ let
swarm.grafana.datasourceUrl = "http://127.0.0.1:19999";
swarm.grafana.logsDatasourceUrl = "http://127.0.0.1:19998";
swarm.grafana.plugins = [ ];
swarm.grafana.package = pkgs.emptyDirectory;
};
# The first slice to leave options on BOTH sides of the split, so the