From 13203a72164794dd7ee7541952a8d6228076f09a Mon Sep 17 00:00:00 2001 From: Adrian Pistol Date: Tue, 31 Oct 2023 09:46:49 +0100 Subject: [PATCH 1/3] watchdogd: init at 4.0 --- pkgs/by-name/wa/watchdogd/package.nix | 32 +++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 pkgs/by-name/wa/watchdogd/package.nix diff --git a/pkgs/by-name/wa/watchdogd/package.nix b/pkgs/by-name/wa/watchdogd/package.nix new file mode 100644 index 000000000000..34567dbe566d --- /dev/null +++ b/pkgs/by-name/wa/watchdogd/package.nix @@ -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 ]; + }; +} From 58cbe00eb63f9e590965c2b05ef84b2b046e5eea Mon Sep 17 00:00:00 2001 From: Adrian Pistol Date: Thu, 2 Nov 2023 18:46:12 +0100 Subject: [PATCH 2/3] nixos/watchdog: add module --- .../manual/release-notes/rl-2405.section.md | 2 + nixos/modules/module-list.nix | 1 + .../modules/services/monitoring/watchdogd.nix | 131 ++++++++++++++++++ 3 files changed, 134 insertions(+) create mode 100644 nixos/modules/services/monitoring/watchdogd.nix diff --git a/nixos/doc/manual/release-notes/rl-2405.section.md b/nixos/doc/manual/release-notes/rl-2405.section.md index bae98714077b..6475239d4cd1 100644 --- a/nixos/doc/manual/release-notes/rl-2405.section.md +++ b/nixos/doc/manual/release-notes/rl-2405.section.md @@ -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} diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index ea3fcea48b83..00e6240f531d 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -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 diff --git a/nixos/modules/services/monitoring/watchdogd.nix b/nixos/modules/services/monitoring/watchdogd.nix new file mode 100644 index 000000000000..e8d104651c6a --- /dev/null +++ b/nixos/modules/services/monitoring/watchdogd.nix @@ -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 ]; +} From 07d610c8ab3104c5e13d605e475ab7d1b28c08ff Mon Sep 17 00:00:00 2001 From: Adrian Pistol Date: Fri, 19 Jan 2024 23:38:27 +0100 Subject: [PATCH 3/3] nixosTests.watchdogd: init --- nixos/tests/all-tests.nix | 1 + nixos/tests/watchdogd.nix | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 nixos/tests/watchdogd.nix diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index a6cfd22d541f..9e27969190f7 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -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 {}; diff --git a/nixos/tests/watchdogd.nix b/nixos/tests/watchdogd.nix new file mode 100644 index 000000000000..663e97cbae10 --- /dev/null +++ b/nixos/tests/watchdogd.nix @@ -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") + ''; +})