nixos-config/modules/restic/vm-image.nix

85 lines
2.4 KiB
Nix
Raw Normal View History

2024-08-22 22:36:47 +02:00
# 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 backups 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));
};
}