| { config, pkgs, lib, ... }:
with lib;
let
cfg = config.services.sanoid;
configToText = let
toString = v:
if builtins.isBool v then
if v then "yes" else "no"
else builtins.toString v;
item = k: v: "${k} = ${toString v}";
items = v: concatStringsSep "\n" (mapAttrsToList item v);
section = k: v: "[${k}]\n${items v}\n";
in c: concatStringsSep "\n" (mapAttrsToList section c);
in {
options.services.sanoid = with types; {
enable = mkEnableOption "sanoid";
package = mkOption {
type = package;
default = pkgs.sanoid;
};
config = mkOption {
type = attrs;
default = {};
};
configText = mkOption {
type = lines;
default = configToText cfg.config;
};
configDir = mkOption {
type = path;
default = pkgs.runCommand "sanoid-config" {} ''
mkdir $out
echo '${cfg.configText}' > $out/sanoid.conf
cp ${cfg.package}/etc/sanoid $out/sanoid.defaults.conf
'';
};
allowPermissions = mkOption {
type = listOf str;
default = [];
};
};
config = mkIf cfg.enable {
users.users.sanoid = {
isSystemUser = true;
home = "/var/cache/sanoid";
createHome = true;
};
systemd.services.sanoid = {
# recommended to prevent problems with daylight saving times (what's the default?)
environment.TZ = "UTC";
preStart = ''
${lib.concatMapStringsSep "\n"
(pool: "/run/booted-system/sw/bin/zfs allow sanoid snapshot,destroy,mount,send,receive ${lib.escapeShellArg pool}")
cfg.allowPermissions}
'';
script = ''
${cfg.package}/bin/sanoid \
--cron \
--verbose \
--configdir=${cfg.configDir}
'';
serviceConfig = {
User = "sanoid";
PermissionsStartOnly = true;
};
};
systemd.timers.sanoid = {
timerConfig.OnCalendar = "minutely";
wantedBy = [ "timers.target" ];
};
};
}
|