@cryptotaxi247 / infra-1 / commits / cd3ce466

modules/backup: add support for ZFS snapshots

Martin Weinelt committed Feb 25, 2024 at 12:40 UTC cd3ce46601a0c97ee268c964018904656b6afc5c
1 file changed +31 -3
modules/backup.nix
+31 -3
@@ -1,10 +1,24 @@
1 { lib
2 , config
3 +, pkgs
4 , ...
5 }:
6
7 let
8 cfg = config.services.backup;
9 +
10 + mkZfsPreHook = mountpoint: ''
11 + DATASET="$(findmnt -nr -o source "${mountpoint}")"
12 + zfs snapshot -r "$DATASET@borg"
13 +
14 + # https://github.com/borgbackup/borg/issues/6652
15 + ls ${mountpoint}/.zfs/snapshot/backup/ > /dev/null
16 + '';
17 +
18 + mkZfsPostHook = mountpoint: ''
19 + DATASET="$(findmnt -nr -o source "${mountpoint}")"
20 + zfs destroy -r "$DATASET@borg"
21 + '';
22 in
23 {
24 options.services.backup = with lib; with types; {
@@ -71,6 +85,13 @@ in
85 Paths to include in the backup.
86 '';
87 };
88 + includesZfsDatasets = mkOption {
89 + type = listOf str;
90 + default = [];
91 + description = ''
92 + ZFS datasets referenced by mountpoint to snapshot and include
93 + '';
94 + };
95
96 excludes = mkOption {
97 type = listOf path;
@@ -105,7 +126,7 @@ in
126 };
127 };
128
108 - config = lib.mkIf (cfg.includes != []) {
129 + config = lib.mkIf (cfg.includes != [] || cfg.includesZfsDatasets != []) {
130 programs.ssh.knownHosts."${if cfg.port != 22 then "[${cfg.host}]:${cfg.port}" else cfg.host}" = {
131 publicKey = "${cfg.hostPublicKey}";
132 };
@@ -113,6 +134,11 @@ in
134 systemd.services.borgbackup-job-state = {
135 wants = cfg.wantedUnits;
136 after = cfg.wantedUnits;
137 +
138 + path = lib.optionals (cfg.includesZfsDatasets != []) [
139 + config.boot.zfs.package
140 + pkgs.util-linux
141 + ];
142 };
143
144 systemd.timers.borgbackup-job-state.timerConfig = {
@@ -122,7 +148,8 @@ in
148 };
149
150 services.borgbackup.jobs.state = {
125 - inherit (cfg) preHook postHook;
151 + preHook = lib.concatMapStringsSep "\n" mkZfsPreHook cfg.includesZfsDatasets;
152 + postHook = lib.concatMapStringsSep "\n" mkZfsPostHook cfg.includesZfsDatasets;
153
154 # Create the repo
155 doInit = true;
@@ -136,7 +163,8 @@ in
163 };
164
165 # What to backup
139 - paths = cfg.includes;
166 + paths = cfg.includes ++
167 + (map (mp: "${mp}/.zfs/snapshot/borg") cfg.includesZfsDatasets);
168 exclude = cfg.excludes;
169
170 # Where to backup it to