lol

nixos/munin: fix broken plugin wrappers

The munin-node service used wrapProgram to inject environment variables.
This doesn't work because munin plugins depend on argv[0], which is
overwritten when the executable is a script with a shebang line (example
below).

This commit removes the wrappers and instead passes the required
environment variables to munin-node.

Eliminating the wrappers resulted in some broken plugins, e.g., meminfo
and hddtemp_smartctl. That was fixed with the per-plugin configuration.

Example:

The plugin if_eth0 is a symlink to /.../plugins/if_, which uses $0
to determine that it should monitor traffic on the eth0 interface.

if_ is a wrapped program, and runs `exec -a "$0" .if_-wrapped`

.if_-wrapped has a "#!/nix/.../bash" line, which results in bash
changing $0, and as a result the plugin thinks my interface
is called "-wrapped".

authored by

Kjetil Orbekk and committed by
Bjørn Forsman
bd3e49a8 a2dc37c7

+31 -37
+31 -37
nixos/modules/services/monitoring/munin.nix
··· 17 17 nodeCfg = config.services.munin-node; 18 18 cronCfg = config.services.munin-cron; 19 19 20 - muninPlugins = pkgs.stdenv.mkDerivation { 21 - name = "munin-available-plugins"; 22 - buildCommand = '' 23 - mkdir -p $out 24 - 25 - cp --preserve=mode ${pkgs.munin}/lib/plugins/* $out/ 26 - 27 - for file in $out/*; do 28 - case "$file" in 29 - */plugin.sh|*/plugins.history) 30 - chmod +x "$file" 31 - continue;; 32 - esac 33 - 34 - # read magic makers from the file 35 - family=$(sed -nr 's/.*#%#\s+family\s*=\s*(\S+)\s*/\1/p' $file) 36 - cap=$(sed -nr 's/.*#%#\s+capabilities\s*=\s*(.+)/\1/p' $file) 37 - 38 - wrapProgram $file \ 39 - --set PATH "/run/wrappers/bin:/run/current-system/sw/bin" \ 40 - --set MUNIN_LIBDIR "${pkgs.munin}/lib" \ 41 - --set MUNIN_PLUGSTATE "/var/run/munin" 42 - 43 - # munin uses markers to tell munin-node-configure what a plugin can do 44 - echo "#%# family=$family" >> $file 45 - echo "#%# capabilities=$cap" >> $file 46 - done 47 - 48 - # NOTE: we disable disktstats because plugin seems to fail and it hangs html generation (100% CPU + memory leak) 49 - rm -f $out/diskstats 50 - ''; 51 - buildInputs = [ pkgs.makeWrapper ]; 52 - }; 53 - 54 20 muninConf = pkgs.writeText "munin.conf" 55 21 '' 56 22 dbdir /var/lib/munin ··· 83 49 84 50 ${nodeCfg.extraConfig} 85 51 ''; 52 + 53 + pluginConf = pkgs.writeText "munin-plugin-conf" 54 + '' 55 + [hddtemp_smartctl] 56 + user root 57 + group root 58 + 59 + [meminfo] 60 + user root 61 + group root 62 + 63 + [ipmi*] 64 + user root 65 + group root 66 + ''; 67 + 68 + pluginConfDir = pkgs.stdenv.mkDerivation { 69 + name = "munin-plugin-conf.d"; 70 + buildCommand = '' 71 + mkdir $out 72 + ln -s ${pluginConf} $out/nixos-config 73 + ''; 74 + }; 86 75 in 87 76 88 77 { ··· 179 168 description = "Munin Node"; 180 169 after = [ "network.target" ]; 181 170 wantedBy = [ "multi-user.target" ]; 182 - path = [ pkgs.munin ]; 171 + path = with pkgs; [ munin smartmontools "/run/current-system/sw" "/run/wrappers" ]; 172 + environment.MUNIN_LIBDIR = "${pkgs.munin}/lib"; 183 173 environment.MUNIN_PLUGSTATE = "/var/run/munin"; 174 + environment.MUNIN_LOGDIR = "/var/log/munin"; 184 175 preStart = '' 185 176 echo "updating munin plugins..." 186 177 187 178 mkdir -p /etc/munin/plugins 188 179 rm -rf /etc/munin/plugins/* 189 - PATH="/run/wrappers/bin:/run/current-system/sw/bin" ${pkgs.munin}/sbin/munin-node-configure --shell --families contrib,auto,manual --config ${nodeConf} --libdir=${muninPlugins} --servicedir=/etc/munin/plugins 2>/dev/null | ${pkgs.bash}/bin/bash 180 + ${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 181 + 182 + # NOTE: we disable disktstats because plugin seems to fail and it hangs html generation (100% CPU + memory leak) 183 + rm /etc/munin/plugins/diskstats || true 190 184 ''; 191 185 serviceConfig = { 192 - ExecStart = "${pkgs.munin}/sbin/munin-node --config ${nodeConf} --servicedir /etc/munin/plugins/"; 186 + ExecStart = "${pkgs.munin}/sbin/munin-node --config ${nodeConf} --servicedir /etc/munin/plugins/ --sconfdir=${pluginConfDir}"; 193 187 }; 194 188 }; 195 189