Merge pull request #33331 from cransom/netdata-module

netdata service: fix permissions for apps.plugin

Changed files
+76 -10
nixos
modules
services
monitoring
tests
+44 -10
nixos/modules/services/monitoring/netdata.nix
···
let
cfg = config.services.netdata;
-
configFile = pkgs.writeText "netdata.conf" cfg.configText;
+
wrappedPlugins = pkgs.runCommand "wrapped-plugins" {} ''
+
mkdir -p $out/libexec/netdata/plugins.d
+
ln -s /run/wrappers/bin/apps.plugin $out/libexec/netdata/plugins.d/apps.plugin
+
'';
+
+
localConfig = {
+
global = {
+
"plugins directory" = "${wrappedPlugins}/libexec/netdata/plugins.d ${pkgs.netdata}/libexec/netdata/plugins.d";
+
};
+
};
+
mkConfig = generators.toINI {} (recursiveUpdate localConfig cfg.config);
+
configFile = pkgs.writeText "netdata.conf" (if cfg.configText != null then cfg.configText else mkConfig);
defaultUser = "netdata";
in {
options = {
services.netdata = {
-
enable = mkOption {
-
default = false;
-
type = types.bool;
-
description = "Whether to enable netdata monitoring.";
-
};
+
enable = mkEnableOption "netdata";
user = mkOption {
type = types.str;
···
};
configText = mkOption {
-
type = types.lines;
-
default = "";
-
description = "netdata.conf configuration.";
+
type = types.nullOr types.lines;
+
description = "Verbatim netdata.conf, cannot be combined with config.";
+
default = null;
example = ''
[global]
debug log = syslog
···
'';
};
+
config = mkOption {
+
type = types.attrsOf types.attrs;
+
default = {};
+
description = "netdata.conf configuration as nix attributes. cannot be combined with configText.";
+
example = literalExample ''
+
global = {
+
"debug log" = "syslog";
+
"access log" = "syslog";
+
"error log" = "syslog";
+
};
+
'';
+
};
+
};
};
-
};
config = mkIf cfg.enable {
+
assertions =
+
[ { assertion = cfg.config != {} -> cfg.configText == null ;
+
message = "Cannot specify both config and configText";
+
}
+
];
systemd.services.netdata = {
+
path = with pkgs; [ gawk curl ];
description = "Real time performance monitoring";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
···
TimeoutStopSec = 60;
};
};
+
+
security.wrappers."apps.plugin" = {
+
source = "${pkgs.netdata}/libexec/netdata/plugins.d/apps.plugin";
+
capabilities = "cap_dac_read_search,cap_sys_ptrace+ep";
+
owner = cfg.user;
+
group = cfg.group;
+
permissions = "u+rx,g+rx,o-rwx";
+
};
+
users.extraUsers = optional (cfg.user == defaultUser) {
name = defaultUser;
+1
nixos/release.nix
···
tests.nat.firewall = callTest tests/nat.nix { withFirewall = true; };
tests.nat.firewall-conntrack = callTest tests/nat.nix { withFirewall = true; withConntrackHelpers = true; };
tests.nat.standalone = callTest tests/nat.nix { withFirewall = false; };
+
tests.netdata = callTest tests/netdata.nix { };
tests.networking.networkd = callSubTests tests/networking.nix { networkd = true; };
tests.networking.scripted = callSubTests tests/networking.nix { networkd = false; };
# TODO: put in networking.nix after the test becomes more complete
+31
nixos/tests/netdata.nix
···
+
# This test runs netdata and checks for data via apps.plugin
+
+
import ./make-test.nix ({ pkgs, ...} : {
+
name = "netdata";
+
meta = with pkgs.stdenv.lib.maintainers; {
+
maintainers = [ cransom ];
+
};
+
+
nodes = {
+
netdata =
+
{ config, pkgs, ... }:
+
{
+
environment.systemPackages = with pkgs; [ curl jq ];
+
services.netdata.enable = true;
+
};
+
};
+
+
testScript = ''
+
startAll;
+
+
$netdata->waitForUnit("netdata.service");
+
# check if netdata can read disk ops for root owned processes.
+
# if > 0, successful. verifies both netdata working and
+
# apps.plugin has elevated capabilities.
+
my $cmd = <<'CMD';
+
curl -s http://localhost:19999/api/v1/data\?chart=users.pwrites | \
+
jq -e '[.data[range(10)][.labels | indices("root")[0]]] | add | . > 0'
+
CMD
+
$netdata->waitUntilSucceeds($cmd);
+
'';
+
})