2024-05-26 16:45:38 +02:00
|
|
|
{
|
|
|
|
config,
|
|
|
|
lib,
|
|
|
|
pkgs,
|
|
|
|
...
|
|
|
|
}:
|
2023-01-06 19:03:57 +01:00
|
|
|
|
|
|
|
with lib;
|
|
|
|
|
|
|
|
# TODO replace with more secure service, e.g. matrix-sendmail (matrix-commander)
|
|
|
|
# needs to support queueing
|
|
|
|
# flake: https://github.com/emmanuelrosa/erosanix/blob/master/modules/matrix-sendmail.nix
|
|
|
|
# call `matrix-commander --login` with credentials on service start
|
|
|
|
let
|
|
|
|
cfg = config.systemd.notify;
|
|
|
|
sendmail = pkgs.writeScript "sendmail" ''
|
|
|
|
#!${pkgs.runtimeShell}
|
|
|
|
|
|
|
|
${pkgs.system-sendmail}/bin/sendmail -t <<ERRMAIL
|
|
|
|
To: ${cfg.email.mailTo}
|
|
|
|
From: ${cfg.email.mailFrom}
|
|
|
|
Subject: Service $1 failed
|
|
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Content-Type: text/plain; charset=UTF-8
|
|
|
|
|
|
|
|
$(systemctl status --full "$1")
|
|
|
|
ERRMAIL
|
|
|
|
'';
|
2024-05-26 16:45:38 +02:00
|
|
|
in
|
|
|
|
{
|
2023-01-06 19:03:57 +01:00
|
|
|
options = {
|
|
|
|
systemd.notify = {
|
|
|
|
enable = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = false;
|
|
|
|
description = "Whether to enable notifications for failed services.";
|
|
|
|
};
|
|
|
|
|
|
|
|
method = mkOption {
|
2024-05-26 16:45:38 +02:00
|
|
|
type = types.enum [
|
|
|
|
"libnotify"
|
|
|
|
"email"
|
|
|
|
];
|
2023-01-06 19:03:57 +01:00
|
|
|
default = "libnotify";
|
|
|
|
description = "The method for sending notifications.";
|
|
|
|
};
|
|
|
|
|
|
|
|
libnotify.user = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = null;
|
|
|
|
description = "User session to which the notification will be sent.";
|
|
|
|
};
|
|
|
|
|
|
|
|
email.mailTo = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = null;
|
2024-05-26 16:45:38 +02:00
|
|
|
description = "Email address to which the service status will be mailed.";
|
2023-01-06 19:03:57 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
email.mailFrom = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = null;
|
2024-05-26 16:45:38 +02:00
|
|
|
description = "Email address from which the service status will be mailed.";
|
2023-01-06 19:03:57 +01:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
systemd.services = mkOption {
|
2024-05-26 16:45:38 +02:00
|
|
|
type =
|
|
|
|
with types;
|
2023-01-06 19:03:57 +01:00
|
|
|
attrsOf (submodule {
|
|
|
|
config.onFailure = optional cfg.enable "notify@%n.service";
|
|
|
|
});
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
config = mkIf cfg.enable {
|
|
|
|
assertions = [
|
|
|
|
{
|
|
|
|
assertion = cfg.method != "libnotify" || cfg.libnotify.user != null;
|
|
|
|
message = "You need to specify a user";
|
|
|
|
}
|
|
|
|
{
|
2024-05-26 16:45:38 +02:00
|
|
|
assertion = cfg.method != "email" || (cfg.email.mailTo != null && cfg.email.mailFrom != null);
|
2023-01-06 19:03:57 +01:00
|
|
|
message = "You need to specify a sender and a receiver";
|
|
|
|
}
|
|
|
|
];
|
|
|
|
|
2024-05-26 16:45:38 +02:00
|
|
|
systemd.services."notify@" =
|
|
|
|
{
|
|
|
|
onFailure = lib.mkForce [ ];
|
|
|
|
}
|
|
|
|
// optionalAttrs (cfg.method == "libnotify") {
|
|
|
|
description = "Desktop notifications for %i service failure";
|
|
|
|
environment = {
|
|
|
|
DBUS_SESSION_BUS_ADDRESS = "unix:path=/run/user/${
|
2023-01-06 19:03:57 +01:00
|
|
|
toString config.users.users.${cfg.libnotify.user}.uid
|
|
|
|
}/bus";
|
2024-05-26 16:45:38 +02:00
|
|
|
INSTANCE = "%i";
|
|
|
|
};
|
|
|
|
script = ''
|
|
|
|
${pkgs.libnotify}/bin/notify-send --urgency=critical \
|
|
|
|
"Service '$INSTANCE' failed" \
|
|
|
|
"$(journalctl -n 6 -o cat -u $INSTANCE)"
|
|
|
|
'';
|
|
|
|
serviceConfig = {
|
|
|
|
Type = "oneshot";
|
|
|
|
User = cfg.libnotify.user;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
// optionalAttrs (cfg.method == "email") {
|
|
|
|
description = "E-Mail notifications for %i service failure";
|
|
|
|
serviceConfig = {
|
|
|
|
ExecStart = "${sendmail} %i";
|
|
|
|
Type = "oneshot";
|
|
|
|
};
|
2023-01-06 19:03:57 +01:00
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|