restic/vm-image: Init
This commit is contained in:
parent
0fa4e6d855
commit
5693e6b75d
|
@ -24,6 +24,16 @@ let
|
|||
};
|
||||
in
|
||||
{
|
||||
sbruder.restic = {
|
||||
enable = true;
|
||||
backups.vm-image = {
|
||||
enable = true;
|
||||
lvm.lvs = [
|
||||
"hiroshi"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
virtualisation.libvirtd = {
|
||||
enable = true;
|
||||
qemu.package = pkgs.qemu_kvm;
|
||||
|
|
|
@ -10,7 +10,7 @@ let
|
|||
sftpPort = 23;
|
||||
repository = "sftp://${sftpTarget}:${toString sftpPort}/personal";
|
||||
|
||||
mkPruneConfig = { tag, timerConfig }: {
|
||||
mkPruneConfig = { tag, timerConfig, opts }: {
|
||||
inherit repository timerConfig;
|
||||
passwordFile = config.sops.secrets.restic-password.path;
|
||||
paths = [ ];
|
||||
|
@ -20,18 +20,15 @@ let
|
|||
];
|
||||
pruneOpts = [
|
||||
"--compression auto"
|
||||
"--keep-daily 7"
|
||||
"--keep-monthly 12"
|
||||
"--keep-weekly 5"
|
||||
"--keep-yearly 10"
|
||||
"--tag ${tag}"
|
||||
"--verbose"
|
||||
];
|
||||
] ++ opts;
|
||||
};
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
./system.nix
|
||||
./vm-image.nix
|
||||
];
|
||||
|
||||
options.sbruder.restic = {
|
||||
|
@ -71,6 +68,23 @@ in
|
|||
OnCalendar = "*-1/2-07 03:00:00";
|
||||
RandomizedDelaySec = "4h";
|
||||
};
|
||||
opts = [
|
||||
"--keep-daily 7"
|
||||
"--keep-monthly 12"
|
||||
"--keep-weekly 5"
|
||||
"--keep-yearly 10"
|
||||
];
|
||||
};
|
||||
|
||||
vm-image-prune = mkPruneConfig {
|
||||
tag = "vm-image";
|
||||
timerConfig = {
|
||||
OnCalendar = "06:00";
|
||||
RandomizedDelaySec = "1h";
|
||||
};
|
||||
opts = [
|
||||
"--keep-last 1"
|
||||
];
|
||||
};
|
||||
};
|
||||
})
|
||||
|
|
84
modules/restic/vm-image.nix
Normal file
84
modules/restic/vm-image.nix
Normal file
|
@ -0,0 +1,84 @@
|
|||
# SPDX-FileCopyrightText: 2024 Simon Bruder <simon@sbruder.de>
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.sbruder.restic.backups.vm-image;
|
||||
in
|
||||
{
|
||||
options.sbruder.restic.backups.vm-image = {
|
||||
enable = lib.mkEnableOption "restic vm image backup";
|
||||
timerConfig = lib.mkOption {
|
||||
type = with lib.types; attrsOf str;
|
||||
default = {
|
||||
OnCalendar = "03:00";
|
||||
RandomizedDelaySec = "3h";
|
||||
};
|
||||
};
|
||||
lvm = {
|
||||
vg = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "${config.networking.hostName}-vg";
|
||||
};
|
||||
lvs = lib.mkOption {
|
||||
type = with lib.types; listOf str;
|
||||
default = [ ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.services = lib.listToAttrs (map
|
||||
(lv: lib.nameValuePair "restic-backups-vm-image-${lv}" {
|
||||
wants = [ "network-online.target" ];
|
||||
after = [ "network-online.target" ];
|
||||
restartIfChanged = false;
|
||||
|
||||
path = with pkgs; [ lvm2 restic ];
|
||||
|
||||
script = ''
|
||||
set -euo pipefail
|
||||
|
||||
LV_NAME=${lib.escapeShellArg lv}
|
||||
FULL_LV_NAME=${lib.escapeShellArg cfg.lvm.vg}/"$LV_NAME"
|
||||
SNAPSHOT_LV_NAME="restic-snapshot-$LV_NAME"
|
||||
FULL_SNAPSHOT_LV_NAME=${lib.escapeShellArg cfg.lvm.vg}/"$SNAPSHOT_LV_NAME"
|
||||
|
||||
lvcreate --name "$SNAPSHOT_LV_NAME" --snapshot "$FULL_LV_NAME" --permission r --ignoreactivationskip
|
||||
|
||||
function cleanup {
|
||||
lvchange --activate n "$FULL_SNAPSHOT_LV_NAME"
|
||||
lvremove "$FULL_SNAPSHOT_LV_NAME"
|
||||
}
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
restic backup \
|
||||
--tag vm-image \
|
||||
--host ${config.networking.hostName}-hypervisor \
|
||||
--verbose \
|
||||
--stdin \
|
||||
--stdin-filename "$LV_NAME" \
|
||||
< "/dev/$FULL_SNAPSHOT_LV_NAME"
|
||||
'';
|
||||
|
||||
environment = {
|
||||
RESTIC_CACHE_DIR = "/var/cache/restic-backups-system"; # hack: reuse system backup’s directory
|
||||
RESTIC_REPOSITORY_FILE = config.sops.secrets.restic-repository.path;
|
||||
RESTIC_PASSWORD_FILE = config.sops.secrets.restic-password.path;
|
||||
};
|
||||
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
};
|
||||
})
|
||||
cfg.lvm.lvs);
|
||||
|
||||
systemd.timers = (lib.listToAttrs (map
|
||||
(lv: lib.nameValuePair "restic-backups-vm-image-${lv}" {
|
||||
wantedBy = [ "timers.target" ];
|
||||
inherit (cfg) timerConfig;
|
||||
})
|
||||
cfg.lvm.lvs));
|
||||
};
|
||||
}
|
Loading…
Reference in a new issue