apcupsd-service: add services.apcupsd.hooks option
Each attribute in this option should name an apcupsd event and the string value it contains will be executed in a shell in response to that event. See "man apccontrol" for the list of events and what they represent. Now it is easy to hook into the apcupsd event system: services.apcupsd.hooks = { onbattery = ''# shell commands to run when the onbattery event is emitted''; doshutdown = ''# shell commands to notify that the computer is shutting down''; };
This commit is contained in:
parent
6341a12587
commit
dc61694d01
@ -2,12 +2,66 @@
|
||||
|
||||
with pkgs.lib;
|
||||
|
||||
let cfg = config.services.apcupsd;
|
||||
configFile = pkgs.writeText "apcupsd.conf" ''
|
||||
## apcupsd.conf v1.1 ##
|
||||
# apcupsd complains if the first line is not like above.
|
||||
${cfg.configText}
|
||||
'';
|
||||
let
|
||||
cfg = config.services.apcupsd;
|
||||
|
||||
configFile = pkgs.writeText "apcupsd.conf" ''
|
||||
## apcupsd.conf v1.1 ##
|
||||
# apcupsd complains if the first line is not like above.
|
||||
${cfg.configText}
|
||||
SCRIPTDIR ${toString scriptDir}
|
||||
'';
|
||||
|
||||
# List of events from "man apccontrol"
|
||||
eventList = [
|
||||
"annoyme"
|
||||
"battattach"
|
||||
"battdetach"
|
||||
"changeme"
|
||||
"commfailure"
|
||||
"commok"
|
||||
"doreboot"
|
||||
"doshutdown"
|
||||
"emergency"
|
||||
"failing"
|
||||
"killpower"
|
||||
"loadlimit"
|
||||
"mainsback"
|
||||
"onbattery"
|
||||
"offbattery"
|
||||
"powerout"
|
||||
"remotedown"
|
||||
"runlimit"
|
||||
"timeout"
|
||||
"startselftest"
|
||||
"endselftest"
|
||||
];
|
||||
|
||||
shellCmdsForEventScript = eventname: commands: ''
|
||||
echo "#!${pkgs.stdenv.shell}" > "$out/${eventname}"
|
||||
echo "${commands}" >> "$out/${eventname}"
|
||||
chmod a+x "$out/${eventname}"
|
||||
'';
|
||||
|
||||
eventToShellCmds = event: if builtins.hasAttr event cfg.hooks then (shellCmdsForEventScript event (builtins.getAttr event cfg.hooks)) else "";
|
||||
|
||||
scriptDir = pkgs.runCommand "apcupsd-scriptdir" {} (''
|
||||
mkdir "$out"
|
||||
# Copy SCRIPTDIR from apcupsd package
|
||||
cp -r ${pkgs.apcupsd}/etc/apcupsd/* "$out"/
|
||||
# Make the files writeable (nix will unset the write bits afterwards)
|
||||
chmod u+w "$out"/*
|
||||
# Remove the sample event notification scripts, because they don't work
|
||||
# anyways (they try to send mail to "root" with the "mail" command)
|
||||
(cd "$out" && rm changeme commok commfailure onbattery offbattery)
|
||||
# Remove the sample apcupsd.conf file (we're generating our own)
|
||||
rm "$out/apcupsd.conf"
|
||||
# Set the SCRIPTDIR= line in apccontrol to the dir we're creating now
|
||||
sed -i -e "s|^SCRIPTDIR=.*|SCRIPTDIR=$out|" "$out/apccontrol"
|
||||
'' + concatStringsSep "\n" (map eventToShellCmds eventList)
|
||||
|
||||
);
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
@ -47,6 +101,24 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
hooks = mkOption {
|
||||
default = {};
|
||||
example = {
|
||||
doshutdown = ''# shell commands to notify that the computer is shutting down'';
|
||||
};
|
||||
type = types.attrsOf types.string;
|
||||
description = ''
|
||||
Each attribute in this option names an apcupsd event and the string
|
||||
value it contains will be executed in a shell, in response to that
|
||||
event (prior to the default action). See "man apccontrol" for the
|
||||
list of events and what they represent.
|
||||
|
||||
A hook script can stop apccontrol from doing its default action by
|
||||
exiting with value 99. Do not do this unless you know what you're
|
||||
doing.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
@ -56,6 +128,15 @@ in
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
assertions = [ {
|
||||
assertion = let hooknames = builtins.attrNames cfg.hooks; in all (x: elem x eventList) hooknames;
|
||||
message = ''
|
||||
One (or more) attribute names in services.apcupsd.hooks are invalid.
|
||||
Current attribute names: ${toString (builtins.attrNames cfg.hooks)}
|
||||
Valid attribute names : ${toString eventList}
|
||||
'';
|
||||
} ];
|
||||
|
||||
# Give users access to the "apcaccess" tool
|
||||
environment.systemPackages = [ pkgs.apcupsd ];
|
||||
|
||||
@ -66,10 +147,6 @@ in
|
||||
# not connected to a tty (it is connected to the journal):
|
||||
# wall: cannot get tty name: Inappropriate ioctl for device
|
||||
# The message still gets through.
|
||||
#
|
||||
# TODO: apcupsd calls "mail" on powerfail etc. events, how should we
|
||||
# handle that? A configurable mail package or let the event logic be
|
||||
# configured from nix expressions?
|
||||
systemd.services.apcupsd = {
|
||||
description = "UPS daemon";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
Loading…
Reference in New Issue
Block a user