This commit is contained in:
Motiejus Jakštys 2023-07-19 14:16:56 +03:00
parent 97f720558d
commit 9b090ff8ae
3 changed files with 117 additions and 51 deletions

View File

@ -77,6 +77,30 @@ in {
enable = true; enable = true;
mountpoints = ["/var/lib" "/var/log"]; mountpoints = ["/var/lib" "/var/log"];
}; };
zfsborg = {
enable = true;
repo = "zh2769@zh2769.rsync.net:hel1-a.servers.jakst";
passwdPath = config.age.secrets.borgbackup-password.path;
mountpoints = {
"/var/lib" = {
paths = [
"/var/lib/.snapshot-latest/gitea"
"/var/lib/.snapshot-latest/headscale"
"/var/lib/.snapshot-latest/matrix-synapse"
];
backup_at = "*-*-* 00:11:00";
};
"/var/log" = {
paths = ["/var/log/.snapshot-latest/caddy/"];
patterns = [
"+ /var/log/.snapshot-latest/caddy/access-jakstys.lt.log-*.zst"
"- *"
];
backup_at = "*-*-* 00:10:00";
};
};
};
}; };
}; };
@ -147,43 +171,6 @@ in {
localuser = null; localuser = null;
}; };
borgbackup.jobs =
lib.mapAttrs' (name: value: let
snapshot = {
mountpoint = value.mountpoint;
zfs_name = value.zfs_name;
};
rwpath = value.mountpoint + "/.snapshot-latest";
in {
name = name;
value =
{
doInit = true;
repo = "zh2769@zh2769.rsync.net:hel1-a.servers.jakst";
encryption = {
mode = "repokey-blake2";
passCommand = "cat ${config.age.secrets.borgbackup-password.path}";
};
paths = value.paths;
extraArgs = "--remote-path=borg1";
compression = "auto,lzma";
startAt = value.backup_at;
readWritePaths = [rwpath];
preHook = mountLatest snapshot;
postHook = umountLatest snapshot;
prune.keep = {
within = "1d";
daily = 7;
weekly = 4;
monthly = 3;
};
}
// lib.optionalAttrs (value ? patterns) {
patterns = value.patterns;
};
})
backup_paths;
headscale = { headscale = {
enable = true; enable = true;
settings = { settings = {
@ -539,20 +526,6 @@ in {
systemd.services = systemd.services =
{ {
"make-snapshot-dirs" = let
vals = builtins.attrValues backup_paths;
mountpoints = builtins.catAttrs "mountpoint" vals;
unique_mountpoints = lib.unique mountpoints;
in {
description = "prepare snapshot directories for backups";
wantedBy = ["multi-user.target"];
serviceConfig = {
Type = "oneshot";
ExecStart = builtins.map (d: "${pkgs.coreutils}/bin/mkdir -p ${d}/.snapshot-latest") unique_mountpoints;
RemainAfterExit = true;
};
};
coturn = { coturn = {
preStart = '' preStart = ''
ln -sf ''${CREDENTIALS_DIRECTORY}/tls-key.pem /run/coturn/tls-key.pem ln -sf ''${CREDENTIALS_DIRECTORY}/tls-key.pem /run/coturn/tls-key.pem

View File

@ -9,6 +9,7 @@
./sshd ./sshd
./initrd ./initrd
./snapshot ./snapshot
./zfsborg
]; ];
options.mj = { options.mj = {

View File

@ -0,0 +1,92 @@
{
config,
lib,
pkgs,
myData,
...
}: let
mountLatest = mountpoint: zfs_name: ''
set -euo pipefail
${pkgs.util-linux}/bin/umount ${mountpoint}/.snapshot-latest &>/dev/null || :
mkdir -p ${mountpoint}/.snapshot-latest
${pkgs.util-linux}/bin/mount -t zfs $(${pkgs.zfs}/bin/zfs list -H -t snapshot -o name ${zfs_name} | sort | tail -1) ${mountpoint}/.snapshot-latest
'';
umountLatest = mountpoint: ''
exec ${pkgs.util-linux}/bin/umount ${mountpoint}/.snapshot-latest
'';
in {
options.mj.base.zfsborg = {
enable = lib.mkEnableOption "backup zfs snapshots with borg";
repo = with lib.types; lib.mkOption {type = str;};
passwdPath = with lib.types; lib.mkOption {type = str;};
mountpoints = lib.mkOption {
default = {};
type = with lib.types;
attrsOf (submodule (
{...}: {
options = {
paths = lib.mkOption {type = listOf path;};
patterns = lib.mkOption {
type = listOf str;
default = [];
};
backup_at = lib.mkOption {type = str;};
};
}
));
};
};
config = lib.mkIf config.mj.base.zfsborg.enable {
systemd.services."zfsborg-snapshot-dirs" = let
mountpoints = lib.unique (lib.attrNames config.mj.base.zfsborg.mountpoints);
in {
description = "zfsborg prepare snapshot directories";
wantedBy = ["multi-user.target"];
serviceConfig = {
Type = "oneshot";
ExecStart =
builtins.map
(d: "${pkgs.coreutils}/bin/mkdir -p ${d}/.snapshot-latest")
mountpoints;
RemainAfterExit = true;
};
};
services.borgbackup.jobs = lib.mapAttrs' (mountpoint: attrs: let
fs = builtins.getAttr mountpoint config.fileSystems;
in
assert fs.fsType == "zfs"; {
name = lib.strings.sanitizeDerivationName mountpoint;
value =
{
doInit = true;
repo = config.mj.base.zfsborg.repo;
encryption = {
mode = "repokey-blake2";
passCommand = "cat ${config.mj.base.zfsborg.passwdPath}";
};
paths = attrs.paths;
extraArgs = "--remote-path=borg1";
compression = "auto,lzma";
startAt = attrs.backup_at;
readWritePaths = let p = mountpoint + "/.snapshot-latest"; in [p];
preHook = mountLatest mountpoint fs.device;
postHook = umountLatest mountpoint;
prune.keep = {
within = "1d";
daily = 7;
weekly = 4;
monthly = 3;
};
}
// lib.optionalAttrs (attrs ? patterns) {
patterns = attrs.patterns;
};
})
config.mj.base.zfsborg.mountpoints;
};
}