diff --git a/modules/nixos/services/systemd-email-notify/default.nix b/modules/nixos/services/systemd-email-notify/default.nix index fb55801..f3b58b1 100644 --- a/modules/nixos/services/systemd-email-notify/default.nix +++ b/modules/nixos/services/systemd-email-notify/default.nix @@ -32,11 +32,33 @@ let $(systemctl status --full "$2") ERRMAIL ''; + + onFailureUnits = + [ "email@%n.service" ] + ++ optionals (cfg.ntfy.tokenFile != null) [ "ntfy-failure@%n.service" ]; in { options = { metacfg.emailOnFailure = with types; { enable = mkBoolOpt false "Whether or not to send mails on failure."; + + ntfy.tokenFile = mkOption { + type = types.nullOr types.path; + default = null; + description = "Path to a file containing the ntfy bearer token. Enables ntfy notifications when set."; + }; + + ntfy.url = mkOption { + type = types.str; + default = "http://127.0.0.1:2586"; + description = "Base URL of the ntfy server."; + }; + + ntfy.topic = mkOption { + type = types.str; + default = "alerts"; + description = "Ntfy topic to publish failure notifications to."; + }; }; systemd.email-notify.mailTo = mkOption { @@ -55,24 +77,48 @@ in type = with types; attrsOf (submodule { - config.onFailure = [ "email@%n.service" ]; + config.onFailure = onFailureUnits; }); }; }; - config = mkIf cfg.enable { - systemd.services."email@" = { - description = "Sends a status mail via sendmail on service failures."; - onFailure = mkForce [ ]; - unitConfig = { - StartLimitIntervalSec = "5m"; - StartLimitBurst = 1; + config = mkIf cfg.enable (mkMerge [ + { + systemd.services."email@" = { + description = "Sends a status mail via sendmail on service failures."; + onFailure = mkForce [ ]; + unitConfig = { + StartLimitIntervalSec = "5m"; + StartLimitBurst = 1; + }; + serviceConfig = { + ExecCondition = "${checkConditions} %i"; + ExecStart = "${sendmail} ${config.systemd.email-notify.mailTo} %i"; + Type = "oneshot"; + }; }; - serviceConfig = { - ExecCondition = "${checkConditions} %i"; - ExecStart = "${sendmail} ${config.systemd.email-notify.mailTo} %i"; - Type = "oneshot"; + } + + (mkIf (cfg.ntfy.tokenFile != null) { + systemd.services."ntfy-failure@" = { + description = "Send ntfy notification on service failure"; + onFailure = mkForce [ ]; + serviceConfig = { + Type = "oneshot"; + ExecStart = pkgs.writeShellScript "ntfy-failure-notify" '' + TOKEN=$(cat ${cfg.ntfy.tokenFile}) + UNIT="$1" + ${pkgs.curl}/bin/curl -s \ + -H "Authorization: Bearer $TOKEN" \ + -H "Title: Service failed: $UNIT" \ + -H "Priority: urgent" \ + -H "Tags: rotating_light" \ + -d "$(systemctl status --full "$UNIT" 2>&1 | head -40)" \ + ${cfg.ntfy.url}/${cfg.ntfy.topic} + ''; + }; + scriptArgs = "%i"; }; - }; - }; + }) + ]); } diff --git a/systems/x86_64-linux/mx/ntfy.nix b/systems/x86_64-linux/mx/ntfy.nix index 037532a..67f6a3d 100644 --- a/systems/x86_64-linux/mx/ntfy.nix +++ b/systems/x86_64-linux/mx/ntfy.nix @@ -1,4 +1,4 @@ -{ config, pkgs, lib, ... }: +{ config, ... }: { services.ntfy-sh = { enable = true; @@ -19,30 +19,9 @@ }; }; - # Notify via ntfy on any service failure (alongside email) - systemd.services."ntfy-failure@" = { - description = "Send ntfy notification on service failure"; - onFailure = lib.mkForce [ ]; - serviceConfig = { - Type = "oneshot"; - ExecStart = pkgs.writeShellScript "ntfy-failure-notify" '' - TOKEN=$(cat ${config.sops.secrets.ntfy.path}) - UNIT="$1" - ${pkgs.curl}/bin/curl -s \ - -H "Authorization: Bearer $TOKEN" \ - -H "Title: Service failed: $UNIT" \ - -H "Priority: urgent" \ - -H "Tags: rotating_light" \ - -d "$(systemctl status --full "$UNIT" 2>&1 | head -40)" \ - http://127.0.0.1:2586/alerts - ''; - }; - scriptArgs = "%i"; - }; - - systemd.services = lib.mkOption { - type = lib.types.attrsOf (lib.types.submodule { - config.onFailure = [ "ntfy-failure@%n.service" ]; - }); + metacfg.emailOnFailure.ntfy = { + tokenFile = config.sops.secrets.ntfy.path; + url = "http://127.0.0.1:2586"; + topic = "alerts"; }; }