85 lines
2.4 KiB
Nix
85 lines
2.4 KiB
Nix
|
# 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));
|
|||
|
};
|
|||
|
}
|