at 24.11-pre 3.7 kB view raw
1{ config, lib, pkgs, ... }: 2with lib; 3let 4 cfg = config.services.watchdogd; 5 6 mkPluginOpts = plugin: defWarn: defCrit: { 7 enabled = mkEnableOption "watchdogd plugin ${plugin}"; 8 interval = mkOption { 9 type = types.ints.unsigned; 10 default = 300; 11 description = '' 12 Amount of seconds between every poll. 13 ''; 14 }; 15 logmark = mkOption { 16 type = types.bool; 17 default = false; 18 description = '' 19 Whether to log current stats every poll interval. 20 ''; 21 }; 22 warning = mkOption { 23 type = types.numbers.nonnegative; 24 default = defWarn; 25 description = '' 26 The high watermark level. Alert sent to log. 27 ''; 28 }; 29 critical = mkOption { 30 type = types.numbers.nonnegative; 31 default = defCrit; 32 description = '' 33 The critical watermark level. Alert sent to log, followed by reboot or script action. 34 ''; 35 }; 36 }; 37in { 38 options.services.watchdogd = { 39 enable = mkEnableOption "watchdogd, an advanced system & process supervisor"; 40 package = mkPackageOption pkgs "watchdogd" { }; 41 42 settings = mkOption { 43 type = with types; submodule { 44 freeformType = let 45 valueType = oneOf [ 46 bool 47 int 48 float 49 str 50 ]; 51 in attrsOf (either valueType (attrsOf valueType)); 52 53 options = { 54 timeout = mkOption { 55 type = types.ints.unsigned; 56 default = 15; 57 description = '' 58 The WDT timeout before reset. 59 ''; 60 }; 61 interval = mkOption { 62 type = types.ints.unsigned; 63 default = 5; 64 description = '' 65 The kick interval, i.e. how often {manpage}`watchdogd(8)` should reset the WDT timer. 66 ''; 67 }; 68 69 safe-exit = mkOption { 70 type = types.bool; 71 default = true; 72 description = '' 73 With {var}`safeExit` enabled, the daemon will ask the driver to disable the WDT before exiting. 74 However, some WDT drivers (or hardware) may not support this. 75 ''; 76 }; 77 78 filenr = mkPluginOpts "filenr" 0.9 1.0; 79 80 loadavg = mkPluginOpts "loadavg" 1.0 2.0; 81 82 meminfo = mkPluginOpts "meminfo" 0.9 0.95; 83 }; 84 }; 85 default = { }; 86 description = '' 87 Configuration to put in {file}`watchdogd.conf`. 88 See {manpage}`watchdogd.conf(5)` for more details. 89 ''; 90 }; 91 }; 92 93 config = let 94 toConfig = attrs: concatStringsSep "\n" (mapAttrsToList toValue attrs); 95 96 toValue = name: value: 97 if isAttrs value 98 then pipe value [ 99 (mapAttrsToList toValue) 100 (map (s: " ${s}")) 101 (concatStringsSep "\n") 102 (s: "${name} {\n${s}\n}") 103 ] 104 else if isBool value 105 then "${name} = ${boolToString value}" 106 else if any (f: f value) [isString isInt isFloat] 107 then "${name} = ${toString value}" 108 else throw '' 109 Found invalid type in `services.watchdogd.settings`: '${typeOf value}' 110 ''; 111 112 watchdogdConf = pkgs.writeText "watchdogd.conf" (toConfig cfg.settings); 113 in mkIf cfg.enable { 114 environment.systemPackages = [ cfg.package ]; 115 116 systemd.services.watchdogd = { 117 documentation = [ 118 "man:watchdogd(8)" 119 "man:watchdogd.conf(5)" 120 ]; 121 wantedBy = [ "multi-user.target" ]; 122 description = "Advanced system & process supervisor"; 123 serviceConfig = { 124 Type = "simple"; 125 ExecStart = "${cfg.package}/bin/watchdogd -n -f ${watchdogdConf}"; 126 }; 127 }; 128 }; 129 130 meta.maintainers = with maintainers; [ vifino ]; 131}