create NixOS module to periodically backup data using borgmatic
This commit is contained in:
parent
96399c3809
commit
dbf84c7f93
3 changed files with 108 additions and 1 deletions
|
@ -38,6 +38,7 @@
|
|||
|
||||
nixosModule.custom = {
|
||||
disko.osDiskDevice = "/dev/sda";
|
||||
backups.enable = true;
|
||||
|
||||
dataDisk = {
|
||||
enable = true;
|
||||
|
|
106
modules/custom/backups.nix
Normal file
106
modules/custom/backups.nix
Normal file
|
@ -0,0 +1,106 @@
|
|||
{ pkgs, lib, config, ... }:
|
||||
let
|
||||
cfg = config.custom.backups;
|
||||
snapshotFile = "/tmp/snapshot.qcow2";
|
||||
snapshotMount = "/tmp/snapshot";
|
||||
beforeEverything = pkgs.writeShellScriptBin "beforeEverything" ''
|
||||
${pkgs.libvirt}/bin/virsh snapshot-create-as --domain ${cfg.domainName} --name backup-${cfg.domainName} --disk-only --quiesce --no-metadata --diskspec vda,snapshot=no --diskspec vdb,file=${snapshotFile} && ${pkgs.coreutils}/bin/sleep 1
|
||||
${pkgs.coreutils}/bin/mkdir -p ${snapshotMount}
|
||||
${pkgs.libguestfs-with-appliance}/bin/guestmount -a ${snapshotFile} -m /dev/sda1 --ro ${snapshotMount}
|
||||
'';
|
||||
|
||||
afterEverything = pkgs.writeShellScriptBin "afterEverything" ''
|
||||
set +e
|
||||
${pkgs.coreutils}/bin/sleep 10
|
||||
${pkgs.libguestfs-with-appliance}/bin/guestunmount ${snapshotMount} && ${pkgs.coreutils}/bin/sleep 1
|
||||
${pkgs.coreutils}/bin/rm -rf ${snapshotMount}
|
||||
${pkgs.libvirt}/bin/virsh blockcommit ${cfg.domainName} vdb --active --verbose --pivot
|
||||
${pkgs.coreutils}/bin/rm -f ${snapshotFile}
|
||||
'';
|
||||
|
||||
borgmaticConfig = pkgs.writeTextFile {
|
||||
name = "borgmatic-config";
|
||||
text = ''
|
||||
source_directories:
|
||||
- ${snapshotMount}
|
||||
repositories:
|
||||
- path: ${cfg.repoLocation}
|
||||
label: ${cfg.domainName}
|
||||
keep_daily: 7
|
||||
keep_weekly: 4
|
||||
keep_monthly: 6
|
||||
unknown_unencrypted_repo_access_is_ok: true
|
||||
before_everything:
|
||||
- ${beforeEverything}/bin/beforeEverything
|
||||
after_everything:
|
||||
- ${afterEverything}/bin/afterEverything
|
||||
'';
|
||||
};
|
||||
in
|
||||
{
|
||||
options.custom.backups = {
|
||||
enable = lib.mkOption {
|
||||
default = false;
|
||||
type = lib.types.bool;
|
||||
description = ''
|
||||
Whether to enable backups of persistent data on this machine.
|
||||
'';
|
||||
};
|
||||
|
||||
repoLocation = lib.mkOption {
|
||||
default = "${config.custom.dataDisk.mountPoint}/backups/thecloud-data.borg";
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
Location of the Borg repository to back up to.
|
||||
'';
|
||||
};
|
||||
|
||||
domainName = lib.mkOption {
|
||||
default = "thecloud";
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
The name of the Libvirt domain with the data disk attached.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
environment.systemPackages = with pkgs; [ libguestfs-with-appliance borgbackup ];
|
||||
# Converted from:
|
||||
# https://github.com/borgmatic-collective/borgmatic/tree/84823dfb912db650936e3492f6ead7e0e0d32a0f/sample/systemd
|
||||
systemd.services.borgmatic = {
|
||||
description = "borgmatic backup";
|
||||
wants = [ "network-online.target" ];
|
||||
after = [ "network-online.target" ];
|
||||
unitConfig = {
|
||||
ConditionACPower = true;
|
||||
};
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
Nice = 19;
|
||||
CPUSchedulingPolicy = "batch";
|
||||
IOSchedulingClass = "best-effort";
|
||||
IOSchedulingPriority = 7;
|
||||
IOWeight = 100;
|
||||
Restart = "no";
|
||||
LogRateLimitIntervalSec = 0;
|
||||
};
|
||||
preStart = "${pkgs.coreutils}/bin/sleep 1m";
|
||||
script = "${pkgs.systemd}/bin/systemd-inhibit --who=\"borgmatic\" --what=\"sleep:shutdown\" --why=\"Prevent interrupting scheduled backup\" ${pkgs.borgmatic}/bin/borgmatic --verbosity -2 --syslog-verbosity 1";
|
||||
};
|
||||
|
||||
environment.etc."borgmatic/config.yaml" = {
|
||||
source = borgmaticConfig;
|
||||
};
|
||||
|
||||
systemd.timers.borgmatic = {
|
||||
description = "Run borgmatic backup";
|
||||
wantedBy = [ "timers.target" ];
|
||||
timerConfig = {
|
||||
OnCalendar = "*-*-* 3:00:00";
|
||||
Persistent = true;
|
||||
RandomizedDelaySec = "3h";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,3 +1,3 @@
|
|||
{
|
||||
imports = [ ./terraform-database.nix ./data-disk.nix ./ssh-certificates.nix ./k3s ./disko.nix ];
|
||||
imports = [ ./terraform-database.nix ./data-disk.nix ./ssh-certificates.nix ./k3s ./disko.nix ./backups.nix ];
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue