at 23.11-pre 4.3 kB view raw
1{ config, pkgs, lib, ... }: 2 3with lib; 4 5let 6 cfg = config.services.collectd; 7 8 baseDirLine = ''BaseDir "${cfg.dataDir}"''; 9 unvalidated_conf = pkgs.writeText "collectd-unvalidated.conf" cfg.extraConfig; 10 11 conf = if cfg.validateConfig then 12 pkgs.runCommand "collectd.conf" {} '' 13 echo testing ${unvalidated_conf} 14 cp ${unvalidated_conf} collectd.conf 15 # collectd -t fails if BaseDir does not exist. 16 substituteInPlace collectd.conf --replace ${lib.escapeShellArgs [ baseDirLine ]} 'BaseDir "."' 17 ${package}/bin/collectd -t -C collectd.conf 18 cp ${unvalidated_conf} $out 19 '' else unvalidated_conf; 20 21 package = 22 if cfg.buildMinimalPackage 23 then minimalPackage 24 else cfg.package; 25 26 minimalPackage = cfg.package.override { 27 enabledPlugins = [ "syslog" ] ++ builtins.attrNames cfg.plugins; 28 }; 29 30in { 31 options.services.collectd = with types; { 32 enable = mkEnableOption (lib.mdDoc "collectd agent"); 33 34 validateConfig = mkOption { 35 default = true; 36 description = lib.mdDoc '' 37 Validate the syntax of collectd configuration file at build time. 38 Disable this if you use the Include directive on files unavailable in 39 the build sandbox, or when cross-compiling. 40 ''; 41 type = types.bool; 42 }; 43 44 package = mkOption { 45 default = pkgs.collectd; 46 defaultText = literalExpression "pkgs.collectd"; 47 description = lib.mdDoc '' 48 Which collectd package to use. 49 ''; 50 type = types.package; 51 }; 52 53 buildMinimalPackage = mkOption { 54 default = false; 55 description = lib.mdDoc '' 56 Build a minimal collectd package with only the configured `services.collectd.plugins` 57 ''; 58 type = bool; 59 }; 60 61 user = mkOption { 62 default = "collectd"; 63 description = lib.mdDoc '' 64 User under which to run collectd. 65 ''; 66 type = nullOr str; 67 }; 68 69 dataDir = mkOption { 70 default = "/var/lib/collectd"; 71 description = lib.mdDoc '' 72 Data directory for collectd agent. 73 ''; 74 type = path; 75 }; 76 77 autoLoadPlugin = mkOption { 78 default = false; 79 description = lib.mdDoc '' 80 Enable plugin autoloading. 81 ''; 82 type = bool; 83 }; 84 85 include = mkOption { 86 default = []; 87 description = lib.mdDoc '' 88 Additional paths to load config from. 89 ''; 90 type = listOf str; 91 }; 92 93 plugins = mkOption { 94 default = {}; 95 example = { cpu = ""; memory = ""; network = "Server 192.168.1.1 25826"; }; 96 description = lib.mdDoc '' 97 Attribute set of plugin names to plugin config segments 98 ''; 99 type = attrsOf lines; 100 }; 101 102 extraConfig = mkOption { 103 default = ""; 104 description = lib.mdDoc '' 105 Extra configuration for collectd. Use mkBefore to add lines before the 106 default config, and mkAfter to add them below. 107 ''; 108 type = lines; 109 }; 110 111 }; 112 113 config = mkIf cfg.enable { 114 # 1200 is after the default (1000) but before mkAfter (1500). 115 services.collectd.extraConfig = lib.mkOrder 1200 '' 116 ${baseDirLine} 117 AutoLoadPlugin ${boolToString cfg.autoLoadPlugin} 118 Hostname "${config.networking.hostName}" 119 120 LoadPlugin syslog 121 <Plugin "syslog"> 122 LogLevel "info" 123 NotifyLevel "OKAY" 124 </Plugin> 125 126 ${concatStrings (mapAttrsToList (plugin: pluginConfig: '' 127 LoadPlugin ${plugin} 128 <Plugin "${plugin}"> 129 ${pluginConfig} 130 </Plugin> 131 '') cfg.plugins)} 132 133 ${concatMapStrings (f: '' 134 Include "${f}" 135 '') cfg.include} 136 ''; 137 138 systemd.tmpfiles.rules = [ 139 "d '${cfg.dataDir}' - ${cfg.user} - - -" 140 ]; 141 142 systemd.services.collectd = { 143 description = "Collectd Monitoring Agent"; 144 after = [ "network.target" ]; 145 wantedBy = [ "multi-user.target" ]; 146 147 serviceConfig = { 148 ExecStart = "${package}/sbin/collectd -C ${conf} -f"; 149 User = cfg.user; 150 Restart = "on-failure"; 151 RestartSec = 3; 152 }; 153 }; 154 155 users.users = optionalAttrs (cfg.user == "collectd") { 156 collectd = { 157 isSystemUser = true; 158 group = "collectd"; 159 }; 160 }; 161 162 users.groups = optionalAttrs (cfg.user == "collectd") { 163 collectd = {}; 164 }; 165 }; 166}