diff options
Diffstat (limited to 'modules/zfssnap/default.nix')
-rw-r--r-- | modules/zfssnap/default.nix | 95 |
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 | |||
3 | with lib; | ||
4 | |||
5 | let | ||
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; | ||
36 | in { | ||
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 | } | ||