From c02564e37c6159408d09ef762ad2dde854bef50c Mon Sep 17 00:00:00 2001 From: Ben Kelly Date: Thu, 13 Dec 2018 18:08:56 -0500 Subject: [PATCH 1/9] nixos/munin: fix documentation links Since this module was written, Munin has moved their documentation from munin-monitoring.org/wiki to guide.munin-monitoring.org. Most of the links were broken, and the ones that weren't went to "please use the new site" pages. --- nixos/modules/services/monitoring/munin.nix | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/nixos/modules/services/monitoring/munin.nix b/nixos/modules/services/monitoring/munin.nix index 2b265d5b5a9..fb1a11a44f9 100644 --- a/nixos/modules/services/monitoring/munin.nix +++ b/nixos/modules/services/monitoring/munin.nix @@ -4,7 +4,7 @@ # TODO: LWP/Pg perl libs aren't recognized # TODO: support fastcgi -# http://munin-monitoring.org/wiki/CgiHowto2 +# http://guide.munin-monitoring.org/en/latest/example/webserver/apache-cgi.html # spawn-fcgi -s /run/munin/fastcgi-graph.sock -U www-data -u munin -g munin /usr/lib/munin/cgi/munin-cgi-graph # spawn-fcgi -s /run/munin/fastcgi-html.sock -U www-data -u munin -g munin /usr/lib/munin/cgi/munin-cgi-html # https://paste.sh/vofcctHP#-KbDSXVeWoifYncZmLfZzgum @@ -86,7 +86,7 @@ in Enable Munin Node agent. Munin node listens on 0.0.0.0 and by default accepts connections only from 127.0.0.1 for security reasons. - See . + See . ''; }; @@ -95,7 +95,7 @@ in type = types.lines; description = '' munin-node.conf extra configuration. See - + ''; }; @@ -121,9 +121,9 @@ in default = ""; description = '' munin.conf extra global configuration. - See . + See . Useful to setup notifications, see - + ''; example = '' contact.email.command mail -s "Munin notification for ''${var:host}" someone@example.com @@ -137,8 +137,8 @@ in ''; description = '' Definitions of hosts of nodes to collect data from. Needs at least one - hosts for cron to succeed. See - + host for cron to succeed. See + ''; }; @@ -173,7 +173,7 @@ in environment.MUNIN_PLUGSTATE = "/run/munin"; environment.MUNIN_LOGDIR = "/var/log/munin"; preStart = '' - echo "updating munin plugins..." + echo "Updating munin plugins..." mkdir -p /etc/munin/plugins rm -rf /etc/munin/plugins/* From c74abf763af37fd453a2dd5aa8390da8256e4f8e Mon Sep 17 00:00:00 2001 From: Ben Kelly Date: Thu, 13 Dec 2018 18:14:21 -0500 Subject: [PATCH 2/9] nixos/munin: add extraPluginConfig option This lets you specify additional plugin-specific configuration to go in plugin-conf.d, and complements the extraConfig and extraGlobalConfig options. --- nixos/modules/services/monitoring/munin.nix | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/nixos/modules/services/monitoring/munin.nix b/nixos/modules/services/monitoring/munin.nix index fb1a11a44f9..47ccf9b0a34 100644 --- a/nixos/modules/services/monitoring/munin.nix +++ b/nixos/modules/services/monitoring/munin.nix @@ -63,6 +63,8 @@ let [ipmi*] user root group root + + ${nodeCfg.extraPluginConfig} ''; pluginConfDir = pkgs.stdenv.mkDerivation { @@ -100,6 +102,18 @@ in }; # TODO: add option to add additional plugins + extraPluginConfig = mkOption { + default = ""; + type = types.lines; + description = '' + plugin-conf.d extra plugin configuration. See + + ''; + example = '' + [fail2ban_*] + user root + ''; + }; }; From 0c3208a8e462c95a1deeb5bd7ab3c467ff2eec49 Mon Sep 17 00:00:00 2001 From: Ben Kelly Date: Thu, 13 Dec 2018 18:16:07 -0500 Subject: [PATCH 3/9] nixos/munin: add disabledPlugins option This is just a set of globs to remove from the active plugins directory after autoconfiguration is complete. I also removed the hard-coded disabling of "diskstats", since it seems to work just fine now. --- nixos/modules/services/monitoring/munin.nix | 21 +++++++++++++++++++-- nixos/tests/munin.nix | 4 +--- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/nixos/modules/services/monitoring/munin.nix b/nixos/modules/services/monitoring/munin.nix index 47ccf9b0a34..dcdad6fac1b 100644 --- a/nixos/modules/services/monitoring/munin.nix +++ b/nixos/modules/services/monitoring/munin.nix @@ -115,6 +115,17 @@ in ''; }; + disabledPlugins = mkOption { + default = []; + type = with types; listOf string; + description = '' + Munin plugins to disable, even if + munin-node-configure --suggest tries to enable + them. To disable a wildcard plugin, use an actual wildcard, as in + the example. + ''; + example = [ "diskstats" "zfs_usage_*" ]; + }; }; services.munin-cron = { @@ -191,10 +202,16 @@ in mkdir -p /etc/munin/plugins rm -rf /etc/munin/plugins/* + + # Autoconfigure builtin plugins ${pkgs.munin}/bin/munin-node-configure --suggest --shell --families contrib,auto,manual --config ${nodeConf} --libdir=${pkgs.munin}/lib/plugins --servicedir=/etc/munin/plugins --sconfdir=${pluginConfDir} 2>/dev/null | ${pkgs.bash}/bin/bash - # NOTE: we disable disktstats because plugin seems to fail and it hangs html generation (100% CPU + memory leak) - rm /etc/munin/plugins/diskstats || true + + ${lib.optionalString (nodeCfg.disabledPlugins != []) '' + # Disable plugins + cd /etc/munin/plugins + rm -f ${toString nodeCfg.disabledPlugins} + ''} ''; serviceConfig = { ExecStart = "${pkgs.munin}/sbin/munin-node --config ${nodeConf} --servicedir /etc/munin/plugins/ --sconfdir=${pluginConfDir}"; diff --git a/nixos/tests/munin.nix b/nixos/tests/munin.nix index 9f66005292a..95cecf17b8c 100644 --- a/nixos/tests/munin.nix +++ b/nixos/tests/munin.nix @@ -15,9 +15,7 @@ import ./make-test.nix ({ pkgs, ...} : { munin-node = { enable = true; # disable a failing plugin to prevent irrelevant error message, see #23049 - extraConfig = '' - ignore_file ^apc_nis$ - ''; + disabledPlugins = [ "apc_nis" ]; }; munin-cron = { enable = true; From b5b82b2caee7bb2c0ea80353397fc7fadf470025 Mon Sep 17 00:00:00 2001 From: Ben Kelly Date: Thu, 13 Dec 2018 18:17:21 -0500 Subject: [PATCH 4/9] nixos/munin: require DejaVu fonts if enabled munin-graph is hardcoded to use DejaVu Mono for the graph legends; if it can't find it, there's no guarantee it finds a monospaced font at all, and if it can't find a monospaced font the legends come out badly misformatted. --- nixos/modules/services/monitoring/munin.nix | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nixos/modules/services/monitoring/munin.nix b/nixos/modules/services/monitoring/munin.nix index dcdad6fac1b..431d0397546 100644 --- a/nixos/modules/services/monitoring/munin.nix +++ b/nixos/modules/services/monitoring/munin.nix @@ -223,6 +223,10 @@ in }) (mkIf cronCfg.enable { + # Munin is hardcoded to use DejaVu Mono and the graphs come out wrong if + # it's not available. + fonts.fonts = [ pkgs.dejavu_fonts ]; + systemd.timers.munin-cron = { description = "batch Munin master programs"; wantedBy = [ "timers.target" ]; From 6c907851f4fbb1252b7d667b46389989e3207cac Mon Sep 17 00:00:00 2001 From: Ben Kelly Date: Thu, 13 Dec 2018 19:58:12 -0500 Subject: [PATCH 5/9] nixos/munin: add extraPlugins and extraAutoPlugins options [#17895] extraAutoPlugins lets you list plugins and plugin directories to be autoconfigured, and extraPlugins lets you enable plugins on a one-by-one basis. This can be used to enable plugins from contrib (although you'll need to download and check out contrib yourself, then point these options at it), or plugins you've written yourself. --- nixos/modules/services/monitoring/munin.nix | 108 +++++++++++++++++++- 1 file changed, 107 insertions(+), 1 deletion(-) diff --git a/nixos/modules/services/monitoring/munin.nix b/nixos/modules/services/monitoring/munin.nix index 431d0397546..af3562befde 100644 --- a/nixos/modules/services/monitoring/munin.nix +++ b/nixos/modules/services/monitoring/munin.nix @@ -74,6 +74,46 @@ let ln -s ${pluginConf} $out/nixos-config ''; }; + + # Copy one Munin plugin into the Nix store with a specific name. + # This is suitable for use with plugins going directly into /etc/munin/plugins, + # i.e. munin.extraPlugins. + internOnePlugin = name: path: + "cp -a '${path}' '${name}'"; + + # Copy an entire tree of Munin plugins into a single directory in the Nix + # store, with no renaming. + # This is suitable for use with munin-node-configure --suggest, i.e. + # munin.extraAutoPlugins. + internManyPlugins = name: path: + "find '${path}' -type f -perm /a+x -exec cp -a -t . '{}' '+'"; + + # Use the appropriate intern-fn to copy the plugins into the store and patch + # them afterwards in an attempt to get them to run on NixOS. + internAndFixPlugins = name: intern-fn: paths: + pkgs.runCommand name {} '' + mkdir -p "$out" + cd "$out" + ${lib.concatStringsSep "\n" + (lib.attrsets.mapAttrsToList intern-fn paths)} + chmod -R u+w . + find . -type f -exec sed -E -i ' + s,(/usr)?/s?bin/,/run/current-system/sw/bin/,g + ' '{}' '+' + ''; + + # TODO: write a derivation for munin-contrib, so that for contrib plugins + # you can just refer to them by name rather than needing to include a copy + # of munin-contrib in your nixos configuration. + extraPluginDir = internAndFixPlugins "munin-extra-plugins.d" + internOnePlugin nodeCfg.extraPlugins; + + extraAutoPluginDir = internAndFixPlugins "munin-extra-auto-plugins.d" + internManyPlugins + (builtins.listToAttrs + (map + (path: { name = baseNameOf path; value = path; }) + nodeCfg.extraAutoPlugins)); in { @@ -101,7 +141,6 @@ in ''; }; - # TODO: add option to add additional plugins extraPluginConfig = mkOption { default = ""; type = types.lines; @@ -115,6 +154,66 @@ in ''; }; + extraPlugins = mkOption { + default = {}; + type = with types; attrsOf path; + description = '' + Additional Munin plugins to activate. Keys are the name of the plugin + symlink, values are the path to the underlying plugin script. You + can use the same plugin script multiple times (e.g. for wildcard + plugins). + + Note that these plugins do not participate in autoconfiguration. If + you want to autoconfigure additional plugins, use + . + + Plugins enabled in this manner take precedence over autoconfigured + plugins. + + Plugins will be copied into the Nix store, and it will attempt to + modify them to run properly by fixing hardcoded references to + /bin, /usr/bin, + /sbin, and /usr/sbin. + ''; + example = literalExample '' + { + zfs_usage_bigpool = /src/munin-contrib/plugins/zfs/zfs_usage_; + zfs_usage_smallpool = /src/munin-contrib/plugins/zfs/zfs_usage_; + zfs_list = /src/munin-contrib/plugins/zfs/zfs_list; + }; + ''; + }; + + extraAutoPlugins = mkOption { + default = []; + type = with types; listOf path; + description = '' + Additional Munin plugins to autoconfigure, using + munin-node-configure --suggest. These should be + the actual paths to the plugin files (or directories containing them), + not just their names. + + If you want to manually enable individual plugins instead, use + . + + Note that only plugins that have the 'autoconfig' capability will do + anything if listed here, since plugins that cannot autoconfigure + won't be automatically enabled by + munin-node-configure. + + Plugins will be copied into the Nix store, and it will attempt to + modify them to run properly by fixing hardcoded references to + /bin, /usr/bin, + /sbin, and /usr/sbin. + ''; + example = literalExample '' + [ + /src/munin-contrib/plugins/zfs + /src/munin-contrib/plugins/ssh + ]; + ''; + }; + disabledPlugins = mkOption { default = []; type = with types; listOf string; @@ -206,6 +305,13 @@ in # Autoconfigure builtin plugins ${pkgs.munin}/bin/munin-node-configure --suggest --shell --families contrib,auto,manual --config ${nodeConf} --libdir=${pkgs.munin}/lib/plugins --servicedir=/etc/munin/plugins --sconfdir=${pluginConfDir} 2>/dev/null | ${pkgs.bash}/bin/bash + # Autoconfigure extra plugins + ${pkgs.munin}/bin/munin-node-configure --suggest --shell --families contrib,auto,manual --config ${nodeConf} --libdir=${extraAutoPluginDir} --servicedir=/etc/munin/plugins --sconfdir=${pluginConfDir} 2>/dev/null | ${pkgs.bash}/bin/bash + + ${lib.optionalString (nodeCfg.extraPlugins != {}) '' + # Link in manually enabled plugins + ln -f -s -t /etc/munin/plugins ${extraPluginDir}/* + ''} ${lib.optionalString (nodeCfg.disabledPlugins != []) '' # Disable plugins From c4437fee7e41d54d58ef680546cc8814b0da3575 Mon Sep 17 00:00:00 2001 From: Ben Kelly Date: Thu, 13 Dec 2018 21:55:41 -0500 Subject: [PATCH 6/9] nixos/munin: add extraCSS option This permits custom styling of the generated HTML without needing to build your own Munin package from source. Also comes with an example that works as a passable dark theme for Munin. --- nixos/modules/services/monitoring/munin.nix | 28 +++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/nixos/modules/services/monitoring/munin.nix b/nixos/modules/services/monitoring/munin.nix index af3562befde..c65432b4bbf 100644 --- a/nixos/modules/services/monitoring/munin.nix +++ b/nixos/modules/services/monitoring/munin.nix @@ -24,6 +24,8 @@ let logdir /var/log/munin rundir /run/munin + ${lib.optionalString (cronCfg.extraCSS != "") "staticdir ${customStaticDir}"} + ${cronCfg.extraGlobalConfig} ${cronCfg.hosts} @@ -114,6 +116,14 @@ let (map (path: { name = baseNameOf path; value = path; }) nodeCfg.extraAutoPlugins)); + + customStaticDir = pkgs.runCommand "munin-custom-static-data" {} '' + cp -a "${pkgs.munin}/etc/opt/munin/static" "$out" + cd "$out" + chmod -R u+w . + echo "${cronCfg.extraCSS}" >> style.css + echo "${cronCfg.extraCSS}" >> style-new.css + ''; in { @@ -266,6 +276,24 @@ in ''; }; + extraCSS = mkOption { + default = ""; + type = types.lines; + description = '' + Custom styling for the HTML that munin-cron generates. This will be + appended to the CSS files used by munin-cron and will thus take + precedence over the builtin styles. + ''; + example = '' + /* A simple dark theme. */ + html, body { background: #222222; } + #header, #footer { background: #333333; } + img.i, img.iwarn, img.icrit, img.iunkn { + filter: invert(100%) hue-rotate(-30deg); + } + ''; + }; + }; }; From e7c1449ae92646723296bf3da12dcc53af8aa272 Mon Sep 17 00:00:00 2001 From: Ben Kelly Date: Fri, 14 Dec 2018 19:24:00 -0500 Subject: [PATCH 7/9] nixos/munin: add types to Munin options Some options were missing their types. --- nixos/modules/services/monitoring/munin.nix | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/nixos/modules/services/monitoring/munin.nix b/nixos/modules/services/monitoring/munin.nix index c65432b4bbf..bf1be56ee9e 100644 --- a/nixos/modules/services/monitoring/munin.nix +++ b/nixos/modules/services/monitoring/munin.nix @@ -134,6 +134,7 @@ in enable = mkOption { default = false; + type = types.bool; description = '' Enable Munin Node agent. Munin node listens on 0.0.0.0 and by default accepts connections only from 127.0.0.1 for security reasons. @@ -241,6 +242,7 @@ in enable = mkOption { default = false; + type = types.bool; description = '' Enable munin-cron. Takes care of all heavy lifting to collect data from nodes and draws graphs to html. Runs munin-update, munin-limits, @@ -253,6 +255,7 @@ in extraGlobalConfig = mkOption { default = ""; + type = types.lines; description = '' munin.conf extra global configuration. See . @@ -265,15 +268,17 @@ in }; hosts = mkOption { - example = '' - [''${config.networking.hostName}] - address localhost - ''; + default = ""; + type = types.lines; description = '' Definitions of hosts of nodes to collect data from. Needs at least one host for cron to succeed. See ''; + example = '' + [''${config.networking.hostName}] + address localhost + ''; }; extraCSS = mkOption { From ace4855cf6998d43c2d347aec03a65d0089201ed Mon Sep 17 00:00:00 2001 From: Ben Kelly Date: Fri, 14 Dec 2018 19:26:02 -0500 Subject: [PATCH 8/9] nixos/munin: enable munin_update and disable munin_stats munin_update relies on a stats file that exists, but isn't found in the default location on NixOS; the appropriate plugin configuration is added. munin_stats relies on munin-cron writing a logfile, which the NixOS build of munin does not. (This is probably fixable in the munin package, but I don't have time to dig into that right now.) --- nixos/modules/services/monitoring/munin.nix | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/nixos/modules/services/monitoring/munin.nix b/nixos/modules/services/monitoring/munin.nix index bf1be56ee9e..f6798632724 100644 --- a/nixos/modules/services/monitoring/munin.nix +++ b/nixos/modules/services/monitoring/munin.nix @@ -66,6 +66,9 @@ let user root group root + [munin*] + env.UPDATE_STATSFILE /var/lib/munin/munin-update.stats + ${nodeCfg.extraPluginConfig} ''; @@ -226,13 +229,20 @@ in }; disabledPlugins = mkOption { - default = []; + # TODO: figure out why Munin isn't writing the log file and fix it. + # In the meantime this at least suppresses a useless graph full of + # NaNs in the output. + default = [ "munin_stats" ]; type = with types; listOf string; description = '' Munin plugins to disable, even if munin-node-configure --suggest tries to enable them. To disable a wildcard plugin, use an actual wildcard, as in the example. + + munin_stats is disabled by default as it tries to read + /var/log/munin/munin-update.log for timing + information, and the NixOS build of Munin does not write this file. ''; example = [ "diskstats" "zfs_usage_*" ]; }; @@ -312,6 +322,7 @@ in description = "Munin monitoring user"; group = "munin"; uid = config.ids.uids.munin; + home = "/var/lib/munin"; }]; users.groups = [{ From 85cdd06e0c079369a46351a126ef67f9a7142a80 Mon Sep 17 00:00:00 2001 From: Ben Kelly Date: Sat, 15 Dec 2018 15:02:54 -0500 Subject: [PATCH 9/9] munin: 2.0.37 -> 2.0.43 Also creates the RELEASE file in preBuild so that munin knows its own version number at runtime. --- pkgs/servers/monitoring/munin/default.nix | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkgs/servers/monitoring/munin/default.nix b/pkgs/servers/monitoring/munin/default.nix index 032789ef05d..5153fcc5ef6 100644 --- a/pkgs/servers/monitoring/munin/default.nix +++ b/pkgs/servers/monitoring/munin/default.nix @@ -3,14 +3,14 @@ }: stdenv.mkDerivation rec { - version = "2.0.37"; + version = "2.0.43"; name = "munin-${version}"; src = fetchFromGitHub { owner = "munin-monitoring"; repo = "munin"; rev = version; - sha256 = "10niyzckx90dwdr4d7vj07d1qjy3nk7xzp30nqnlxzbaww7n5v78"; + sha256 = "1ydhf9hcb3n5h0ss5f1zf9yz4r4njqxazlz931ixvx5gyhj9gq5l"; }; buildInputs = [ @@ -75,6 +75,7 @@ stdenv.mkDerivation rec { ]; preBuild = '' + echo "${version}" > RELEASE substituteInPlace "Makefile" \ --replace "/bin/pwd" "pwd" \ --replace "HTMLOld.3pm" "HTMLOld.3"