refactor and modularize btrbk

This commit is contained in:
Daniel Langbein 2023-11-17 15:06:01 +01:00
parent d0614fa608
commit fdc67467d5
Signed by: langfingaz
GPG Key ID: 6C47C753F0823002
5 changed files with 198 additions and 78 deletions

View File

@ -0,0 +1,54 @@
{ config, pkgs, ... }:
let
ssd-subvolumes = {
"arch.p1st.de" = {};
"blogger.privacy1st.de" = {};
"changedetection.p1st.de" = {};
"cloud.privacy1st.de" = {};
"git.privacy1st.de" = {};
"mastodon-toot-follower.privacy1st.de" = {};
"money.p1st.de" = {};
"music.privacy1st.de" = {};
"paste.p1st.de" = {};
"proxy" = {};
"recipe.privacy1st.de" = {};
"traggo.privacy1st.de" = {};
};
hdd-subvolumes = {
"cloud.privacy1st.de" = {};
# MediaKollektiv: 796 GiB
"cloud.media-kollektiv.eu" = {};
};
in
{
yoda.btrbkSnapshots = [
{
instance = "local-snapshot-ssd";
volume = "/jc-data";
snapshot_dir = "/snap";
subvolume = ssd-subvolumes;
}
{
instance = "local-snapshot-hdd";
volume = "/mnt/data/jc-data";
snapshot_dir = "/mnt/data/snap2";
subvolume = hdd-subvolumes;
}
];
yoda.btrbkBackups = [
{
instance = "local-backup-ssd";
volume = "/jc-data";
snapshot_dir = "/snap";
target = "/mnt/backup/snap";
subvolume = ssd-subvolumes;
}
{
instance = "local-backup-hdd";
volume = "/mnt/data/jc-data";
snapshot_dir = "/mnt/data/snap2";
target = "/mnt/backup/snap2";
subvolume = hdd-subvolumes;
}
];
}

View File

@ -23,6 +23,7 @@
../../modules/journalwatch.nix
../../modules/btrbk
./btrbk-config.nix
../../modules/netcup-dns.nix
../../modules/de-p1st-monitor.nix
../../modules/spin-down.nix

73
modules/btrbk/backup.nix Normal file
View File

@ -0,0 +1,73 @@
{ lib, config, options, pkgs, modulesPath, ... }:
with lib;
let
cfg = config.yoda.btrbkBackups;
daily = {
preserve-min = "no";
preserve = "7d 4w 6m";
};
in
{
options = {
yoda.btrbkBackups = mkOption {
type = types.listOf types.attrs;
default = [];
example = [{
# Optional.
# If this is `true` and `volume` starts with `ssh://`, `lz4` transport compression is enabled.
lz4 = true;
instance = "local-backup-ssd";
volume = "/jc-data";
snapshot_dir = "/snap";
target = "/mnt/backup/snap";
subvolume = {
"arch.p1st.de" = {};
};
}];
description = ''
List containing attrsets.
Each attrset is used to create one btrbk instance.
'';
};
};
# lib.forEach:
# https://github.com/NixOS/nixpkgs/blob/54f00576aa6139a9d54062d0edc2fb31423f0ffb/lib/lists.nix#L36
# lib.attrsets.mergeAttrsList:
# https://github.com/NixOS/nixpkgs/blob/54f00576aa6139a9d54062d0edc2fb31423f0ffb/lib/attrsets.nix#L786
config = {
services.btrbk.instances =
# Merge list of attr sets into one attr set.
attrsets.mergeAttrsList (
forEach
cfg
(x:
# `services.btrbk.instances` template.
{
"${x.instance}" = {
#onCalendar = null;
onCalendar = "00:05";
settings = {
timestamp_format = "long";
stream_compress = mkIf ((x.lz4 or false) && strings.hasPrefix "ssh://" x.volume) "lz4";
# Create backups.
target_preserve_min = daily.preserve-min;
target_preserve = daily.preserve;
# Don't create or delete snapshots.
snapshot_preserve_min = "all";
snapshot_create = "no";
volume."${x.volume}" = {
snapshot_dir = x.snapshot_dir;
target = x.target;
subvolume = x.subvolume;
};
};
};
}
)
);
};
}

View File

@ -11,88 +11,18 @@
# #=> ExecStart=/nix/store/53nvbl1c0w14524j7v3fpn9py31yi2hb-btrbk-0.32.6/bin/btrbk -c /etc/btrbk/local-backup.conf run
{ config, pkgs, ... }:
let
ssd-subvolumes = {
"arch.p1st.de" = {};
"blogger.privacy1st.de" = {};
"changedetection.p1st.de" = {};
"cloud.privacy1st.de" = {};
"git.privacy1st.de" = {};
"mastodon-toot-follower.privacy1st.de" = {};
"money.p1st.de" = {};
"music.privacy1st.de" = {};
"paste.p1st.de" = {};
"proxy" = {};
"recipe.privacy1st.de" = {};
"traggo.privacy1st.de" = {};
};
hdd-subvolumes = {
"cloud.privacy1st.de" = {};
# MediaKollektiv: 796 GiB
"cloud.media-kollektiv.eu" = {};
};
preserve-hourly = "24h 7d 4w 6m";
preserve-daily = "7d 4w 6m";
in
{
imports = [
./snapshot.nix
./backup.nix
];
services.btrbk = {
# Transport compression with `lz4`,
# see `./backup.nix`.
extraPackages = [ pkgs.lz4 ];
# Lowest scheduling priority.
niceness = 19;
# Set of btrbk instances. The instance named btrbk is the default one.
instances = {
"local-snapshot" = {
onCalendar = "hourly";
#onCalendar = "*:0/15"; # Every 15min
settings = {
timestamp_format = "long";
#stream_compress = "lz4";
snapshot_preserve_min = "2d";
snapshot_preserve = preserve-hourly;
volume."/jc-data" = {
snapshot_dir = "/snap";
subvolume = ssd-subvolumes;
};
volume."/mnt/data/jc-data" = {
snapshot_dir = "/mnt/data/snap2";
subvolume = hdd-subvolumes;
};
};
};
"local-backup" = {
# Run daily, 5 minutes after `local-snapshot` 0'o'clock timer.
onCalendar = "00:05";
settings = {
timestamp_format = "long";
#stream_compress = "lz4";
# Create backups.
target_preserve_min = "no";
target_preserve = preserve-daily;
# Don't create or delete snapshots.
snapshot_preserve_min = "all";
snapshot_create = "no";
volume."/jc-data" = {
snapshot_dir = "/snap";
target = "/mnt/backup/snap";
subvolume = ssd-subvolumes;
};
volume."/mnt/data/jc-data" = {
snapshot_dir = "/mnt/data/snap2";
target = "/mnt/backup/snap2";
subvolume = hdd-subvolumes;
};
};
};
};
# The `instances` option is set by `./snapshot.nix` and `./backup.nix`.
};
}

View File

@ -0,0 +1,62 @@
{ lib, config, options, pkgs, modulesPath, ... }:
with lib;
let
cfg = config.yoda.btrbkSnapshots;
hourly = {
preserve-min = "2d";
preserve = "24h 7d 4w 6m";
};
in
{
options = {
yoda.btrbkSnapshots = mkOption {
type = types.listOf types.attrs;
default = [];
example = [{
instance = "local-snapshot-ssd";
volume = "/jc-data";
snapshot_dir = "/snap";
subvolume = {
"arch.p1st.de" = {};
};
}];
description = ''
List containing attrsets.
Each attrset is used to create one btrbk instance.
'';
};
};
# lib.forEach:
# https://github.com/NixOS/nixpkgs/blob/54f00576aa6139a9d54062d0edc2fb31423f0ffb/lib/lists.nix#L36
# lib.attrsets.mergeAttrsList:
# https://github.com/NixOS/nixpkgs/blob/54f00576aa6139a9d54062d0edc2fb31423f0ffb/lib/attrsets.nix#L786
config = {
services.btrbk.instances =
# Merge list of attr sets into one attr set.
attrsets.mergeAttrsList (
forEach
cfg
(x:
# `services.btrbk.instances` template.
{
"${x.instance}" = {
#onCalendar = null;
onCalendar = "hourly";
settings = {
timestamp_format = "long";
snapshot_preserve_min = hourly.preserve-min;
snapshot_preserve = hourly.preserve;
volume."${x.volume}" = {
snapshot_dir = x.snapshot_dir;
subvolume = x.subvolume;
};
};
};
}
)
);
};
}