feat: expand systemd notify service with libnotify option

This commit is contained in:
Felix Schröter 2023-01-06 19:03:57 +01:00
parent 2afe18d1ce
commit 1da5ce612e
Signed by: felschr
GPG key ID: 671E39E6744C807D
5 changed files with 120 additions and 79 deletions

View file

@ -68,7 +68,7 @@
};
nixosModules = {
flakeDefaults = import ./modules/flakeDefaults.nix;
emailNotify = import ./modules/emailNotify.nix;
systemdNotify = import ./modules/systemdNotify.nix;
};
homeManagerModules = { git = import ./home/modules/git.nix; };
systemDefaults = {

View file

@ -12,8 +12,7 @@
./desktop
./virtualisation/libvirt.nix
./virtualisation/podman.nix
./modules/emailNotify.nix
./services/mail.nix
./modules/systemdNotify.nix
./services/samba/home-pc.nix
./services/restic/home-pc.nix
./services/pcscd.nix
@ -52,10 +51,9 @@
"87.98.162.88" = [ "portcheck.transmissionbt.com" ];
};
systemd.emailNotify.enable = true;
systemd.emailNotify.mailTo = "admin@felschr.com";
systemd.emailNotify.mailFrom =
"${config.networking.hostName} <felschr@web.de>";
systemd.notify.enable = true;
systemd.notify.method = "libnotify";
systemd.notify.libnotify.user = "felschr";
services.printing.drivers = with pkgs; [ epson-escpr ];

View file

@ -14,7 +14,7 @@ in with builtins; {
./hardware/gpu-intel.nix
./desktop/x11.nix
./system/server.nix
./modules/emailNotify.nix
./modules/systemdNotify.nix
./services/mail.nix
./services/restic/home-server.nix
./services/samba/home-server.nix
@ -134,10 +134,12 @@ in with builtins; {
};
};
systemd.emailNotify.enable = true;
systemd.emailNotify.mailTo = "admin@felschr.com";
systemd.emailNotify.mailFrom =
"${config.networking.hostName} <felschr@web.de>";
systemd.notify = {
enable = true;
method = "email";
email.mailTo = "admin@felschr.com";
email.mailFrom = "${config.networking.hostName} <felschr@web.de>";
};
# only change this when specified in release notes
system.stateVersion = "22.11";

View file

@ -1,67 +0,0 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.systemd.emailNotify;
sendmail = pkgs.writeScript "sendmail" ''
#!${pkgs.runtimeShell}
${pkgs.system-sendmail}/bin/sendmail -t <<ERRMAIL
To: ${cfg.mailTo}
From: ${cfg.mailFrom}
Subject: Status of service $1
Content-Transfer-Encoding: 8bit
Content-Type: text/plain; charset=UTF-8
$(systemctl status --full "$1")
ERRMAIL
'';
in {
options = {
systemd.emailNotify = {
enable = mkOption {
type = types.bool;
default = false;
description =
"Whether to enable email notification for failed services.";
};
mailTo = mkOption {
type = types.str;
default = null;
description =
"Email address to which the service status will be mailed.";
};
mailFrom = mkOption {
type = types.str;
default = null;
description =
"Email address from which the service status will be mailed.";
};
};
systemd.services = mkOption {
type = with types;
attrsOf (submodule {
config.onFailure = optional cfg.enable "email@%n.service";
});
};
};
config = mkIf cfg.enable {
assertions = singleton {
assertion = cfg.mailTo != null && cfg.mailFrom != null;
message = "You need to specify a sender and a receiver";
};
systemd.services."email@" = {
description = "Sends a status mail via sendmail on service failures.";
onFailure = lib.mkForce [ ];
serviceConfig = {
ExecStart = "${sendmail} %i";
Type = "oneshot";
};
};
};
}

108
modules/systemdNotify.nix Normal file
View file

@ -0,0 +1,108 @@
{ config, lib, pkgs, ... }:
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
'';
in {
options = {
systemd.notify = {
enable = mkOption {
type = types.bool;
default = false;
description = "Whether to enable notifications for failed services.";
};
method = mkOption {
type = types.enum [ "libnotify" "email" ];
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;
description =
"Email address to which the service status will be mailed.";
};
email.mailFrom = mkOption {
type = types.str;
default = null;
description =
"Email address from which the service status will be mailed.";
};
};
systemd.services = mkOption {
type = with types;
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";
}
{
assertion = cfg.method != "email"
|| (cfg.email.mailTo != null && cfg.email.mailFrom != null);
message = "You need to specify a sender and a receiver";
}
];
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/${
toString config.users.users.${cfg.libnotify.user}.uid
}/bus";
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";
};
};
};
}