Watch
0
0
Fork
You've already forked hyperhive
0

feat(#3405): declarative grafana plugins for the swarm dashboard

Plugin management is server-admin scoped, and on an SSO hive nobody holds that
role: auto_assign_org_role grants an org role, and the built-in local admin
that does hold server admin cannot log in because the login form is disabled
whenever SSO is configured. Two individually-correct decisions leaving no path
to the plugin UI at all.

Declarative is the way through rather than a workaround for it -- plugins land
in the store and in git, survive a rebuild and a state reset, and the container
needs no runtime egress to grafana.com.

mkIf rather than passing the list through: upstream's default is null, while an
empty list is a real value pointing the plugin path at an empty store dir, so a
hive that sets nothing must keep seeing null.
This commit is contained in:
atlas 2026-08-17 21:15:18 +02:00 • committed by mara
commit bfe921c254

View file

@ -174,6 +174,30 @@ in
'';
};
};
plugins = lib.mkOption {
type = lib.types.listOf lib.types.package;
default = [ ];
example = lib.literalExpression "[ pkgs.grafanaPlugins.grafana-piechart-panel ]";
description = ''
Grafana plugins to install, as packages. Declarative rather than
installed through the UI, which is the only shape that works here:
plugin management is **server-admin** scoped, and on an SSO hive
nobody holds that role — `users.auto_assign_org_role` grants an
*org* role, and the built-in local admin that does hold server
admin cannot log in because the login form is disabled whenever
SSO is configured.
That is a deliberate pair of decisions rather than an oversight,
and this option is the way through it: plugins live in the store
and in git, so they survive a container rebuild and a state reset,
and the container needs no runtime egress to grafana.com.
Empty by default, which leaves grafana's own plugin handling
untouched. Setting it takes over the plugin directory entirely —
anything installed by other means stops being visible.
'';
};
};
config = lib.mkIf (hyperhiveCfg.enable && cfg.enable) {
@ -437,6 +461,25 @@ in
enable = true;
package = cfg.package;
# Passed through unconditionally, empty default included.
# Upstream distinguishes `null` from `[ ]`, and both differences
# favour always handing it a list:
#
# - `null` points the plugin path at grafana's mutable
# `<dataDir>/plugins`; any list points it at a store path.
# Switching on the day someone adds their first plugin would
# bury that change inside an unrelated one.
# - upstream defaults its plugin update-check to
# `declarativePlugins == null`, so a list also stops the
# container phoning grafana.com. That is the no-runtime-egress
# property this option exists for — it should not arrive only
# once a plugin happens to be listed.
#
# Nothing is taken over by claiming the directory on a hive with no
# plugins: manual installation is already impossible here (see the
# option's description), so there is nothing in it to lose.
declarativePlugins = cfg.plugins;
settings = {
server = {
# Already upstream's default (measured), but pinned rather