Merge pull request #264552 from vifino/watchdogd

watchdogd: init at 4.0; add module
This commit is contained in:
h7x4 2024-01-20 06:21:24 +01:00 committed by GitHub
commit 66cb51263e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 189 additions and 0 deletions

View file

@ -152,6 +152,8 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m
The module now includes an optional config check, that is enabled by default, to make the change obvious before any deployment.
More information about the configuration syntax change is available in the [upstream repository](https://github.com/prometheus/snmp_exporter/blob/b75fc6b839ee3f3ccbee68bee55f1ae99555084a/auth-split-migration.md).
- [watchdogd](https://troglobit.com/projects/watchdogd/), a system and process supervisor using watchdog timers. Available as [services.watchdogd](#opt-services.watchdogd.enable).
## Other Notable Changes {#sec-release-24.05-notable-changes}
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->

View file

@ -849,6 +849,7 @@
./services/monitoring/vmagent.nix
./services/monitoring/vmalert.nix
./services/monitoring/vnstat.nix
./services/monitoring/watchdogd.nix
./services/monitoring/zabbix-agent.nix
./services/monitoring/zabbix-proxy.nix
./services/monitoring/zabbix-server.nix

View file

@ -0,0 +1,131 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.watchdogd;
mkPluginOpts = plugin: defWarn: defCrit: {
enabled = mkEnableOption "watchdogd plugin ${plugin}";
interval = mkOption {
type = types.ints.unsigned;
default = 300;
description = ''
Amount of seconds between every poll.
'';
};
logmark = mkOption {
type = types.bool;
default = false;
description = ''
Whether to log current stats every poll interval.
'';
};
warning = mkOption {
type = types.numbers.nonnegative;
default = defWarn;
description = ''
The high watermark level. Alert sent to log.
'';
};
critical = mkOption {
type = types.numbers.nonnegative;
default = defCrit;
description = ''
The critical watermark level. Alert sent to log, followed by reboot or script action.
'';
};
};
in {
options.services.watchdogd = {
enable = mkEnableOption "watchdogd, an advanced system & process supervisor";
package = mkPackageOption pkgs "watchdogd" { };
settings = mkOption {
type = with types; submodule {
freeformType = let
valueType = oneOf [
bool
int
float
str
];
in attrsOf (either valueType (attrsOf valueType));
options = {
timeout = mkOption {
type = types.ints.unsigned;
default = 15;
description = ''
The WDT timeout before reset.
'';
};
interval = mkOption {
type = types.ints.unsigned;
default = 5;
description = ''
The kick interval, i.e. how often {manpage}`watchdogd(8)` should reset the WDT timer.
'';
};
safe-exit = mkOption {
type = types.bool;
default = true;
description = ''
With {var}`safeExit` enabled, the daemon will ask the driver to disable the WDT before exiting.
However, some WDT drivers (or hardware) may not support this.
'';
};
filenr = mkPluginOpts "filenr" 0.9 1.0;
loadavg = mkPluginOpts "loadavg" 1.0 2.0;
meminfo = mkPluginOpts "meminfo" 0.9 0.95;
};
};
default = { };
description = ''
Configuration to put in {file}`watchdogd.conf`.
See {manpage}`watchdogd.conf(5)` for more details.
'';
};
};
config = let
toConfig = attrs: concatStringsSep "\n" (mapAttrsToList toValue attrs);
toValue = name: value:
if isAttrs value
then pipe value [
(mapAttrsToList toValue)
(map (s: " ${s}"))
(concatStringsSep "\n")
(s: "${name} {\n${s}\n}")
]
else if isBool value
then "${name} = ${boolToString value}"
else if any (f: f value) [isString isInt isFloat]
then "${name} = ${toString value}"
else throw ''
Found invalid type in `services.watchdogd.settings`: '${typeOf value}'
'';
watchdogdConf = pkgs.writeText "watchdogd.conf" (toConfig cfg.settings);
in mkIf cfg.enable {
environment.systemPackages = [ cfg.package ];
systemd.services.watchdogd = {
documentation = [
"man:watchdogd(8)"
"man:watchdogd.conf(5)"
];
wantedBy = [ "multi-user.target" ];
description = "Advanced system & process supervisor";
serviceConfig = {
Type = "simple";
ExecStart = "${cfg.package}/bin/watchdogd -n -f ${watchdogdConf}";
};
};
};
meta.maintainers = with maintainers; [ vifino ];
}

View file

@ -944,6 +944,7 @@ in {
vsftpd = handleTest ./vsftpd.nix {};
warzone2100 = handleTest ./warzone2100.nix {};
wasabibackend = handleTest ./wasabibackend.nix {};
watchdogd = handleTest ./watchdogd.nix {};
webhook = runTest ./webhook.nix;
wiki-js = handleTest ./wiki-js.nix {};
wine = handleTest ./wine.nix {};

22
nixos/tests/watchdogd.nix Normal file
View file

@ -0,0 +1,22 @@
import ./make-test-python.nix ({ lib, ... }: {
name = "watchdogd";
meta.maintainers = with lib.maintainers; [ vifino ];
nodes.machine = { pkgs, ... }: {
virtualisation.qemu.options = [
"-device i6300esb" # virtual watchdog timer
];
boot.kernelModules = [ "i6300esb" ];
services.watchdogd.enable = true;
services.watchdogd.settings = {
supervisor.enabled = true;
};
};
testScript = ''
machine.wait_for_unit("watchdogd.service")
assert "i6300ESB" in machine.succeed("watchdogctl status")
machine.succeed("watchdogctl test")
'';
})

View file

@ -0,0 +1,32 @@
{ lib
, stdenv
, fetchFromGitHub
, pkg-config
, autoreconfHook
, libite
, libuev
, libconfuse
}:
stdenv.mkDerivation rec {
pname = "watchdogd";
version = "4.0";
src = fetchFromGitHub {
owner = "troglobit";
repo = "watchdogd";
rev = version;
hash = "sha256-JNJj0CJGJXuIRpob2RXYqDRrU4Cn20PRxOjQ6TFsVYQ=";
};
nativeBuildInputs = [ pkg-config autoreconfHook ];
buildInputs = [ libite libuev libconfuse ];
meta = with lib; {
description = "Advanced system & process supervisor for Linux";
homepage = "https://troglobit.com/watchdogd.html";
changelog = "https://github.com/troglobit/watchdogd/releases/tag/${version}";
license = licenses.isc;
platforms = platforms.linux;
maintainers = with maintainers; [ vifino ];
};
}