summaryrefslogtreecommitdiff
path: root/modules/zfssnap/default.nix
diff options
context:
space:
mode:
Diffstat (limited to 'modules/zfssnap/default.nix')
-rw-r--r--modules/zfssnap/default.nix95
1 files changed, 95 insertions, 0 deletions
diff --git a/modules/zfssnap/default.nix b/modules/zfssnap/default.nix
new file mode 100644
index 00000000..a0590c9f
--- /dev/null
+++ b/modules/zfssnap/default.nix
@@ -0,0 +1,95 @@
1{ config, pkgs, lib, ... }:
2
3with lib;
4
5let
6 zfssnap = pkgs.stdenv.mkDerivation rec {
7 name = "zfssnap";
8 src = ./zfssnap.py;
9
10 phases = [ "buildPhase" "checkPhase" "installPhase" ];
11
12 buildInputs = with pkgs; [makeWrapper];
13
14 python = pkgs.python39.withPackages (ps: with ps; [pyxdg pytimeparse dateutil systemd]);
15
16 buildPhase = ''
17 substitute $src zfssnap \
18 --subst-var-by python ${escapeShellArg python}
19 '';
20
21 doCheck = true;
22 checkPhase = ''
23 ${python}/bin/python -m py_compile zfssnap
24 '';
25
26 installPhase = ''
27 install -m 0755 -D -t $out/bin \
28 zfssnap
29
30 wrapProgram $out/bin/zfssnap \
31 --prefix PATH : ${makeBinPath [config.boot.zfs.package]}
32 '';
33 };
34
35 cfg = config.services.zfssnap;
36in {
37 options = {
38 services.zfssnap = {
39 enable = mkEnableOption "zfssnap service";
40
41 config = mkOption {
42 type = with types; attrsOf (attrsOf str);
43 default = {
44 keep = {
45 within = "5m";
46 "5m" = "24";
47 hourly = "24";
48 daily = "31";
49 monthly = "24";
50 yearly = "-1";
51 };
52 };
53 };
54
55 snapInterval = mkOption {
56 type = types.str;
57 default = "*-*-* *:00/5:00 Europe/Berlin";
58 };
59 };
60 };
61
62 config = mkIf cfg.enable {
63 systemd.services."zfssnap" = {
64 description = "Create automatic ZFS snapshots";
65 after = [ "zfs-import.target" ];
66 wants = [ "zfssnap-prune.service" ];
67 before = [ "zfssnap-prune.service" ];
68 serviceConfig = {
69 Type = "oneshot";
70 ExecStart = "${zfssnap}/bin/zfssnap --no-stderr -vv";
71 };
72 };
73 systemd.services."zfssnap-prune" = {
74 description = "Prune automatic ZFS snapshots";
75 after = [ "zfs-import.target" "zfssnap.service" ];
76 serviceConfig = {
77 Type = "oneshot";
78 ExecStart = let
79 mkSectionName = name: strings.escape [ "[" "]" ] (strings.toUpper name);
80 zfssnapConfig = generators.toINI { inherit mkSectionName; } cfg.config;
81 in "${zfssnap}/bin/zfssnap --no-stderr -vv prune --config=${zfssnapConfig}";
82 };
83 };
84
85 systemd.timers."zfssnap" = {
86 wantedBy = ["timers.target"];
87 timerConfig = {
88 OnCalendar = cfg.snapInterval;
89 Persistent = true;
90 };
91 };
92
93 environment.systemPackages = [zfssnap];
94 };
95}