2023-02-10 01:37:49 +00:00
|
|
|
{ instances ? [ ]
|
2023-05-06 20:39:28 +00:00
|
|
|
, localMountDir ? null
|
2023-01-27 00:08:51 +00:00
|
|
|
}:
|
|
|
|
|
|
|
|
{ config, pkgs, ... }:
|
|
|
|
|
|
|
|
let
|
|
|
|
btrbkPrimary = { subvolumes ? [ ] }: {
|
|
|
|
snapshot_dir = "@snapshots";
|
|
|
|
subvolume = builtins.foldl'
|
|
|
|
(acc: subvol: acc // {
|
|
|
|
${subvol} = { };
|
|
|
|
})
|
|
|
|
{ }
|
|
|
|
subvolumes;
|
|
|
|
};
|
|
|
|
|
|
|
|
btrbkSecondary = { targetDir, subvolumes ? [ ] }: {
|
|
|
|
target = "send-receive ${targetDir}";
|
|
|
|
subvolume = builtins.foldl'
|
|
|
|
(acc: subvol: acc // {
|
|
|
|
${subvol} = {
|
|
|
|
snapshot_dir = "@snapshots";
|
|
|
|
snapshot_preserve_min = "all";
|
|
|
|
snapshot_create = "no";
|
|
|
|
};
|
|
|
|
})
|
|
|
|
{ }
|
|
|
|
subvolumes;
|
|
|
|
};
|
|
|
|
|
2023-02-10 01:37:49 +00:00
|
|
|
primary = mountDir: subvolumes: {
|
2023-01-27 00:08:51 +00:00
|
|
|
snapshot_preserve_min = "2d";
|
2023-02-27 17:30:45 +00:00
|
|
|
snapshot_preserve = "7d 5w";
|
2023-01-27 00:08:51 +00:00
|
|
|
transaction_log = "/var/log/btrbk.log";
|
|
|
|
volume = {
|
|
|
|
"${mountDir}" = btrbkPrimary {
|
|
|
|
inherit subvolumes;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2023-02-10 01:37:49 +00:00
|
|
|
secondary = primaryIp: mountDir: subvolumes: {
|
2023-01-27 00:08:51 +00:00
|
|
|
backend_remote = "btrfs-progs-sudo";
|
|
|
|
ssh_identity = config.sops.secrets.private_key.path;
|
|
|
|
ssh_user = "btrbk";
|
|
|
|
stream_buffer = "512m";
|
|
|
|
target_preserve = "24h 7d";
|
|
|
|
target_preserve_min = "24h";
|
|
|
|
transaction_log = "/var/log/btrbk.log";
|
|
|
|
volume = {
|
|
|
|
"ssh://${primaryIp}${mountDir}" = btrbkSecondary {
|
|
|
|
targetDir = "${mountDir}/@snapshots";
|
|
|
|
inherit subvolumes;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
2023-05-06 19:22:29 +00:00
|
|
|
|
2023-05-06 20:39:28 +00:00
|
|
|
backup = instances: {
|
2023-05-06 19:22:29 +00:00
|
|
|
backend_remote = "btrfs-progs-sudo";
|
|
|
|
ssh_identity = config.sops.secrets.private_key.path;
|
|
|
|
ssh_user = "btrbk";
|
|
|
|
stream_buffer = "512m";
|
|
|
|
target_preserve = "2h 2d 10w *m";
|
|
|
|
target_preserve_min = "24h";
|
|
|
|
transaction_log = "/var/log/btrbk.log";
|
2023-05-06 20:39:28 +00:00
|
|
|
volume = builtins.foldl' (acc: { primaryIp, mountDir, name, subvolumes }: acc // {
|
|
|
|
"ssh://${primaryIp}${mountDir}" = btrbkSecondary {
|
|
|
|
targetDir = "${localMountDir}/@snapshots/${name}";
|
2023-05-06 19:22:29 +00:00
|
|
|
inherit subvolumes;
|
|
|
|
};
|
2023-05-06 20:39:28 +00:00
|
|
|
}) { } instances;
|
2023-05-06 19:22:29 +00:00
|
|
|
};
|
2023-01-27 00:08:51 +00:00
|
|
|
in
|
|
|
|
{
|
|
|
|
sops.secrets.private_key = {
|
|
|
|
format = "yaml";
|
|
|
|
sopsFile = ../../secrets/btrbk.yaml;
|
|
|
|
owner = config.users.users.btrbk.name;
|
|
|
|
group = config.users.users.btrbk.group;
|
|
|
|
};
|
|
|
|
|
|
|
|
environment.systemPackages = with pkgs; [
|
|
|
|
btrbk
|
2023-01-27 05:35:19 +00:00
|
|
|
btrfs-progs
|
2023-01-27 00:08:51 +00:00
|
|
|
(writeShellScriptBin "restore-snapshot" (builtins.readFile ./restore-snapshot))
|
|
|
|
(writeShellScriptBin "restore-all-snapshots" (builtins.readFile ./restore-all-snapshots))
|
2023-05-06 20:39:28 +00:00
|
|
|
] ++ (if localMountDir != null then [
|
|
|
|
(writeShellScriptBin
|
|
|
|
"make-backup-subdirectories"
|
|
|
|
(builtins.foldl'
|
|
|
|
(acc: { name, ... }:
|
|
|
|
"${acc}\nmkdir -p ${localMountDir}/@snapshots/${name}"
|
|
|
|
)
|
|
|
|
""
|
|
|
|
instances
|
|
|
|
)
|
|
|
|
)
|
|
|
|
] else []);
|
2023-01-27 00:08:51 +00:00
|
|
|
|
|
|
|
services.btrbk = {
|
|
|
|
sshAccess = [
|
|
|
|
{
|
|
|
|
key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHTqU3EvTgY5/e9m6YyQWypQPK58t9iPmPnPYAvnODGB asonix@lionheart";
|
|
|
|
roles = [ "source" "info" "send" ];
|
|
|
|
}
|
|
|
|
];
|
|
|
|
extraPackages = with pkgs; [ gzip ];
|
2023-05-06 20:39:28 +00:00
|
|
|
instances = if localMountDir == null then
|
|
|
|
(builtins.foldl'
|
|
|
|
(acc: { primaryIp ? null, mountDir, subvolumes, name ? "btrbk" }:
|
|
|
|
let
|
|
|
|
selected =
|
|
|
|
if primaryIp == null then
|
|
|
|
(primary mountDir subvolumes)
|
|
|
|
else
|
|
|
|
(secondary primaryIp mountDir subvolumes);
|
|
|
|
in
|
|
|
|
acc //
|
|
|
|
{
|
|
|
|
${name} = {
|
|
|
|
onCalendar = "hourly";
|
|
|
|
settings = selected;
|
|
|
|
};
|
|
|
|
})
|
|
|
|
{ }
|
|
|
|
instances)
|
|
|
|
else
|
2023-02-10 01:37:49 +00:00
|
|
|
{
|
2023-05-06 20:39:28 +00:00
|
|
|
btrbk = {
|
2023-02-10 01:37:49 +00:00
|
|
|
onCalendar = "hourly";
|
2023-05-06 20:39:28 +00:00
|
|
|
settings = (backup instances);
|
2023-02-10 01:37:49 +00:00
|
|
|
};
|
2023-05-06 20:39:28 +00:00
|
|
|
};
|
2023-01-27 00:08:51 +00:00
|
|
|
};
|
|
|
|
}
|