From c9d10437e5370de79e334653a232afd7dd7b378d Mon Sep 17 00:00:00 2001 From: lassulus Date: Thu, 23 Nov 2023 15:43:25 +0100 Subject: [PATCH] backups: add clanCore backup & clan borgbackup module --- checks/borgbackup/borg_test | 7 +++ checks/borgbackup/borg_test.pub | 1 + checks/borgbackup/default.nix | 36 +++++++++++++ checks/flake-module.nix | 1 + clanModules/borgbackup.nix | 73 ++++++++++++++++++++++++++ clanModules/flake-module.nix | 1 + nixosModules/clanCore/backups.nix | 55 +++++++++++++++++++ nixosModules/clanCore/flake-module.nix | 1 + 8 files changed, 175 insertions(+) create mode 100644 checks/borgbackup/borg_test create mode 100644 checks/borgbackup/borg_test.pub create mode 100644 checks/borgbackup/default.nix create mode 100644 clanModules/borgbackup.nix create mode 100644 nixosModules/clanCore/backups.nix diff --git a/checks/borgbackup/borg_test b/checks/borgbackup/borg_test new file mode 100644 index 000000000..e378c16ba --- /dev/null +++ b/checks/borgbackup/borg_test @@ -0,0 +1,7 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW +QyNTUxOQAAACASG8CFZy8vrqA2erivzgnNUCuOkiBngt5lXPOXai2EMAAAAJAOOON0Djjj +dAAAAAtzc2gtZWQyNTUxOQAAACASG8CFZy8vrqA2erivzgnNUCuOkiBngt5lXPOXai2EMA +AAAEDTjUOWSYeU3Xu+Ol1731b9rXeEVXSdrhVOraA+7/35JBIbwIVnLy+uoDZ6uK/OCc1Q +K46SIGeC3mVc85dqLYQwAAAADGxhc3NAaWduYXZpYQE= +-----END OPENSSH PRIVATE KEY----- diff --git a/checks/borgbackup/borg_test.pub b/checks/borgbackup/borg_test.pub new file mode 100644 index 000000000..c305404cd --- /dev/null +++ b/checks/borgbackup/borg_test.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBIbwIVnLy+uoDZ6uK/OCc1QK46SIGeC3mVc85dqLYQw lass@ignavia diff --git a/checks/borgbackup/default.nix b/checks/borgbackup/default.nix new file mode 100644 index 000000000..9bf7aa831 --- /dev/null +++ b/checks/borgbackup/default.nix @@ -0,0 +1,36 @@ +(import ../lib/container-test.nix) ({ ... }: { + name = "borgbackup"; + + nodes.machine = { self, ... }: { + imports = [ + self.clanModules.borgbackup + self.nixosModules.clanCore + { + services.openssh.enable = true; + services.borgbackup.repos.testrepo = { + authorizedKeys = [ + (builtins.readFile ./borg_test.pub) + ]; + }; + } + { + clanCore.machineName = "machine"; + clanCore.clanDir = ./.; + clanCore.state."/etc/state" = { }; + environment.etc.state.text = "hello world"; + clan.borgbackup = { + enable = true; + destinations.test = { + repo = "borg@localhost:."; + rsh = "ssh -i ${./borg_test} -o StrictHostKeyChecking=no"; + }; + }; + } + ]; + }; + testScript = '' + start_all() + machine.systemctl("start --wait borgbackup-job-test.service") + assert "machine-test" in machine.succeed("BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK=yes /run/current-system/sw/bin/borg-job-test list") + ''; +}) diff --git a/checks/flake-module.nix b/checks/flake-module.nix index 7f2e370fd..fe3b4576c 100644 --- a/checks/flake-module.nix +++ b/checks/flake-module.nix @@ -17,6 +17,7 @@ container = import ./container nixosTestArgs; deltachat = import ./deltachat nixosTestArgs; meshnamed = import ./meshnamed nixosTestArgs; + borgbackup = import ./borgbackup nixosTestArgs; }; schemaTests = pkgs.callPackages ./schemas.nix { inherit self; diff --git a/clanModules/borgbackup.nix b/clanModules/borgbackup.nix new file mode 100644 index 000000000..fa5550cd5 --- /dev/null +++ b/clanModules/borgbackup.nix @@ -0,0 +1,73 @@ +{ config, lib, ... }: +let + cfg = config.clan.borgbackup; +in +{ + options.clan.borgbackup = { + enable = lib.mkEnableOption "backups with borgbackup"; + destinations = lib.mkOption { + type = lib.types.attrsOf (lib.types.submodule ({ name, ... }: { + options = { + name = lib.mkOption { + type = lib.types.str; + default = name; + description = "the name of the backup job"; + }; + repo = lib.mkOption { + type = lib.types.str; + description = "the borgbackup repository to backup to"; + }; + rsh = lib.mkOption { + type = lib.types.str; + default = ""; + description = "the rsh to use for the backup"; + }; + + }; + })); + description = '' + destinations where the machine should be backuped to + ''; + }; + }; + config = lib.mkIf cfg.enable { + services.borgbackup.jobs = lib.mapAttrs + (_: dest: { + paths = map (state: state.folder) (lib.attrValues config.clanCore.state); + exclude = [ + "*.pyc" + ]; + repo = dest.repo; + environment.BORG_RSH = dest.rsh; + encryption.mode = "none"; + compression = "auto,zstd"; + startAt = "*-*-* 01:00:00"; + preHook = '' + set -x + ''; + + prune.keep = { + within = "1d"; # Keep all archives from the last day + daily = 7; + weekly = 4; + monthly = 0; + }; + }) + cfg.destinations; + + clanCore.backups.providers.borgbackup = { + list = '' + ${lib.concatMapStringsSep "\n" (dest: '' + echo listing backups for ${dest} + borg-job-${dest} list + '') cfg.destinations} + ''; + start = '' + ${lib.concatMapStringsSep "\n" (dest: '' + systemctl start borgbackup-job-${dest} + '') cfg.destinations} + ''; + + }; + }; +} diff --git a/clanModules/flake-module.nix b/clanModules/flake-module.nix index 5df749d5b..431cf319b 100644 --- a/clanModules/flake-module.nix +++ b/clanModules/flake-module.nix @@ -8,5 +8,6 @@ }; deltachat = ./deltachat.nix; xfce = ./xfce.nix; + borgbackup = ./borgbackup.nix; }; } diff --git a/nixosModules/clanCore/backups.nix b/nixosModules/clanCore/backups.nix new file mode 100644 index 000000000..3e905029a --- /dev/null +++ b/nixosModules/clanCore/backups.nix @@ -0,0 +1,55 @@ +{ lib, ... }: +{ + options.clanCore.state = lib.mkOption { + default = { }; + type = lib.types.attrsOf + (lib.types.submodule ({ name, ... }: { + options = { + folder = lib.mkOption { + type = lib.types.str; + default = name; + description = '' + Folder where state resides in + ''; + }; + }; + })); + }; + options.clanCore.backups = { + providers = lib.mkOption { + type = lib.types.attrsOf (lib.types.submodule ({ name, ... }: { + options = { + name = lib.mkOption { + type = lib.types.str; + default = name; + description = '' + Name of the backup provider + ''; + }; + list = lib.mkOption { + type = lib.types.str; + description = '' + script to list backups + ''; + }; + delete = lib.mkOption { + type = lib.types.str; + description = '' + script to delete a backup + ''; + }; + start = lib.mkOption { + type = lib.types.str; + description = '' + script to start a backup + ''; + }; + }; + })); + default = [ ]; + description = '' + Configured backup providers which are used by this machine + ''; + }; + }; +} diff --git a/nixosModules/clanCore/flake-module.nix b/nixosModules/clanCore/flake-module.nix index 7d29f7b97..60ea9f333 100644 --- a/nixosModules/clanCore/flake-module.nix +++ b/nixosModules/clanCore/flake-module.nix @@ -1,6 +1,7 @@ { self, inputs, lib, ... }: { flake.nixosModules.clanCore = { config, pkgs, options, ... }: { imports = [ + ./backups.nix ./clan-imports ./secrets ./zerotier