btrfsborg for fwminex

This commit is contained in:
Motiejus Jakštys 2024-07-31 09:40:05 +03:00
parent 8e80b76c12
commit 23f399024a
6 changed files with 144 additions and 4 deletions

View File

@ -207,6 +207,7 @@
motiejus-server-passwd-hash.file = ./secrets/motiejus_server_passwd_hash.age; motiejus-server-passwd-hash.file = ./secrets/motiejus_server_passwd_hash.age;
root-server-passwd-hash.file = ./secrets/root_server_passwd_hash.age; root-server-passwd-hash.file = ./secrets/root_server_passwd_hash.age;
sasl-passwd.file = ./secrets/postfix_sasl_passwd.age; sasl-passwd.file = ./secrets/postfix_sasl_passwd.age;
borgbackup-password.file = ./secrets/fwminex/borgbackup-password.age;
syncthing-key.file = ./secrets/fwminex/syncthing/key.pem.age; syncthing-key.file = ./secrets/fwminex/syncthing/key.pem.age;
syncthing-cert.file = ./secrets/fwminex/syncthing/cert.pem.age; syncthing-cert.file = ./secrets/fwminex/syncthing/cert.pem.age;
}; };

View File

@ -81,10 +81,17 @@ in
timeZone = "Europe/Vilnius"; timeZone = "Europe/Vilnius";
username = "motiejus"; username = "motiejus";
base.users = { base = {
enable = true; users = {
root.hashedPasswordFile = config.age.secrets.root-server-passwd-hash.path; enable = true;
user.hashedPasswordFile = config.age.secrets.motiejus-server-passwd-hash.path; root.hashedPasswordFile = config.age.secrets.root-server-passwd-hash.path;
user.hashedPasswordFile = config.age.secrets.motiejus-server-passwd-hash.path;
};
unitstatus = {
enable = true;
email = "motiejus+alerts@jakstys.lt";
};
}; };
services = { services = {
@ -94,6 +101,22 @@ in
verboseLogs = false; verboseLogs = false;
}; };
btrfsborg = {
enable = true;
passwordPath = config.age.secrets.borgbackup-password.path;
sshKeyPath = "/etc/ssh/ssh_host_ed25519_key";
dirs = [
{
subvolume = "/home";
repo = "borgstor@${
myData.hosts."vno3-rp3b.servers.jakst".jakstIP
}:${config.networking.hostName}.${config.networking.domain}-home-motiejus-annex2";
paths = [ "motiejus/annex2" ];
backup_at = "*-*-* 02:30:01 UTC";
}
];
};
btrfssnapshot = { btrfssnapshot = {
enable = true; enable = true;
subvolumes = [ subvolumes = [

View File

@ -0,0 +1,101 @@
{ config, lib, ... }:
let
cfg = config.mj.services.btrfsborg;
mkPreHook = btrfs_name: i: ''
set -x
sleep ${toString i}
SNAPSHOT=$(btrfs subvolume list --sort=-gen -r -o ${btrfs_name} | awk '{print $9; exit}')
cd ${btrfs_name}/$SNAPSHOT
'';
in
{
options.mj.services.btrfsborg = with lib.types; {
enable = lib.mkEnableOption "backup zfs snapshots with borg";
passwordPath = lib.mkOption { type = str; };
sshKeyPath = lib.mkOption {
type = nullOr path;
default = null;
};
dirs = lib.mkOption {
default = { };
type = listOf (submodule {
options = {
subvolume = lib.mkOption { type = path; };
repo = lib.mkOption { type = str; };
paths = lib.mkOption { type = listOf str; };
patterns = lib.mkOption {
type = listOf str;
default = [ ];
};
prune = lib.mkOption {
type = anything;
default = { };
};
backup_at = lib.mkOption { type = str; };
};
});
};
};
config = lib.mkIf cfg.enable {
systemd.services = lib.listToAttrs (
lib.imap0 (
i: attr:
let
svcName = "borgbackup-job-${lib.strings.sanitizeDerivationName attr.subvolume}-${toString i}";
in
lib.nameValuePair svcName { serviceConfig.RuntimeDirectory = svcName; }
) cfg.dirs
);
services.borgbackup.jobs = builtins.listToAttrs (
lib.imap0 (
i: attrs:
let
subvolume = builtins.getAttr "subvolume" attrs;
in
assert lib.assertMsg config.mj.base.unitstatus.enable
"config.mj.base.unitstatus.enable must be true";
lib.nameValuePair "${lib.strings.sanitizeDerivationName subvolume}-${toString i}" (
{
inherit (attrs) repo paths;
doInit = true;
encryption = {
mode = "repokey-blake2";
passCommand = "cat ${cfg.passwordPath}";
};
extraArgs = "--remote-path=borg1";
compression = "auto,zstd,10";
extraCreateArgs = "--chunker-params buzhash,10,23,16,4095";
startAt = attrs.backup_at;
preHook = mkPreHook subvolume i;
prune.keep = {
within = "1d";
daily = 7;
weekly = 4;
monthly = 3;
};
environment = {
BORG_HOST_ID =
let
h = config.networking;
in
"${h.hostName}.${h.domain}@${h.hostId}";
} // lib.optionalAttrs (cfg.sshKeyPath != null) { BORG_RSH = ''ssh -i "${cfg.sshKeyPath}"''; };
}
// lib.optionalAttrs (attrs ? patterns) { inherit (attrs) patterns; }
// lib.optionalAttrs (attrs ? prune) { inherit (attrs) prune; }
)
) cfg.dirs
);
mj.base.unitstatus.units =
let
sanitized = map lib.strings.sanitizeDerivationName (lib.catAttrs "subvolume" cfg.dirs);
in
lib.imap0 (i: name: "borgbackup-job-${name}-${toString i}") sanitized;
};
}

View File

@ -2,6 +2,7 @@
{ {
imports = [ imports = [
./borgstor ./borgstor
./btrfsborg
./btrfssnapshot ./btrfssnapshot
./deployerbot ./deployerbot
./friendlyport ./friendlyport

View File

@ -57,6 +57,7 @@ in
"secrets/motiejus_server_passwd_hash.age" "secrets/motiejus_server_passwd_hash.age"
"secrets/root_server_passwd_hash.age" "secrets/root_server_passwd_hash.age"
"secrets/fwminex/borgbackup-password.age"
"secrets/fwminex/syncthing/key.pem.age" "secrets/fwminex/syncthing/key.pem.age"
"secrets/fwminex/syncthing/cert.pem.age" "secrets/fwminex/syncthing/cert.pem.age"
] ]

View File

@ -0,0 +1,13 @@
age-encryption.org/v1
-> ssh-ed25519 fqSa6A xif2+1IgaLJHElfSr09ZoA8FeU9F6RXfuvQXtz5r9yI
iEdmfQLdk3c4EldnMFXujALxa7yjUuWiGBFVb4S6QiQ
-> X25519 8DRa9UHe3f8WeNEUk6KZ3d5nP7Q3vRfQtrr34YXOiVk
DzCYUiz5K0Y7nBjWB2NSgt4o/udXqIQOWT28v0vg71Q
-> X25519 jCQTUY2BgcPWvByTroBsx8HStgU8Z+rUjckVuqhypgY
vrYgKCAT5YYNMTzAubLNSonR8EcPuC3i+82uI6hFoPY
-> piv-p256 +y2G/w AsR1WyGPSiKL5D6RWTXRDKmlH7r7zqvcb4vyJ9aEnZqA
yLq97BNhPA+OhzHkB7dEI78wUSmlyLR8ph8BUsjOtMY
-> piv-p256 jNqd3A A+62kLQITa9nfTdRPtVl4EwdW8xPrFQ30iP3cVbGDTA3
w+cDRsmrg466V9LKRhM/a6rTDxttiKZxyImgsI4KpMs
--- pryTljLfZTkOpwNO9zqAUX0JPjd3hBMEM8b5WxhuPDo
5ÉŸ5L αÈrÍ÷²‡æ}rËU»H´öQFrÌ<72>Ÿ„ZUIDnÊ