diff options
| -rw-r--r-- | hosts/vidhar/borg/default.nix | 61 | ||||
| -rw-r--r-- | modules/borgsnap/borgsnap/borgsnap/__main__.py (renamed from hosts/vidhar/borg/borgsnap/borgsnap/__main__.py) | 1 | ||||
| -rw-r--r-- | modules/borgsnap/borgsnap/setup.py (renamed from hosts/vidhar/borg/borgsnap/setup.py) | 0 | ||||
| -rw-r--r-- | modules/borgsnap/default.nix | 106 | ||||
| -rw-r--r-- | modules/zfssnap/default.nix | 18 | ||||
| -rw-r--r-- | modules/zfssnap/zfssnap/zfssnap/__main__.py | 3 |
6 files changed, 135 insertions, 54 deletions
diff --git a/hosts/vidhar/borg/default.nix b/hosts/vidhar/borg/default.nix index fe62c956..8d0b46ef 100644 --- a/hosts/vidhar/borg/default.nix +++ b/hosts/vidhar/borg/default.nix | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | with lib; | 3 | with lib; |
| 4 | 4 | ||
| 5 | let | 5 | let |
| 6 | sshConfig = pkgs.writeText "config" '' | 6 | sshConfig = '' |
| 7 | Include /etc/ssh/ssh_config | 7 | Include /etc/ssh/ssh_config |
| 8 | 8 | ||
| 9 | ControlMaster auto | 9 | ControlMaster auto |
| @@ -33,7 +33,7 @@ let | |||
| 33 | # StateDirectory = "borg"; | 33 | # StateDirectory = "borg"; |
| 34 | RuntimeDirectory = "copy-borg"; | 34 | RuntimeDirectory = "copy-borg"; |
| 35 | Environment = [ | 35 | Environment = [ |
| 36 | "BORG_RSH=\"${pkgs.openssh}/bin/ssh -F ${sshConfig}\"" | 36 | "BORG_RSH=\"${pkgs.openssh}/bin/ssh -F ${pkgs.writeText "config" sshConfig}\"" |
| 37 | "BORG_BASE_DIR=/var/lib/borg" | 37 | "BORG_BASE_DIR=/var/lib/borg" |
| 38 | "BORG_CONFIG_DIR=/var/lib/borg/config" | 38 | "BORG_CONFIG_DIR=/var/lib/borg/config" |
| 39 | "BORG_CACHE_DIR=/var/lib/borg/cache" | 39 | "BORG_CACHE_DIR=/var/lib/borg/cache" |
| @@ -74,63 +74,20 @@ let | |||
| 74 | copy | 74 | copy |
| 75 | 75 | ||
| 76 | wrapProgram $out/bin/copy \ | 76 | wrapProgram $out/bin/copy \ |
| 77 | --prefix PATH : ${makeBinPath (with pkgs; [config.boot.zfs.package util-linux borgbackup])}:${config.security.wrapperDir} | ||
| 78 | ''; | ||
| 79 | }); | ||
| 80 | |||
| 81 | borgsnap = flakeInputs.mach-nix.lib.${config.nixpkgs.system}.buildPythonPackage rec { | ||
| 82 | pname = "borgsnap"; | ||
| 83 | src = ./borgsnap; | ||
| 84 | version = "0.0.0"; | ||
| 85 | ignoreDataOutdated = true; | ||
| 86 | |||
| 87 | requirements = '' | ||
| 88 | atomicwrites | ||
| 89 | pyprctl | ||
| 90 | python-unshare | ||
| 91 | python-dateutil | ||
| 92 | ''; | ||
| 93 | postInstall = '' | ||
| 94 | wrapProgram $out/bin/borgsnap \ | ||
| 95 | --prefix PATH : ${makeBinPath (with pkgs; [util-linux borgbackup])}:${config.security.wrapperDir} | 77 | --prefix PATH : ${makeBinPath (with pkgs; [util-linux borgbackup])}:${config.security.wrapperDir} |
| 96 | ''; | 78 | ''; |
| 97 | 79 | }); | |
| 98 | providers.python-unshare = "nixpkgs"; | ||
| 99 | overridesPre = [ | ||
| 100 | (self: super: { python-unshare = super.python-unshare.overrideAttrs (oldAttrs: { name = "python-unshare-0.2.1"; version = "0.2.1"; }); }) | ||
| 101 | ]; | ||
| 102 | |||
| 103 | _.tomli.buildInputs.add = with pkgs."python3Packages"; [ flit-core ]; | ||
| 104 | }; | ||
| 105 | in { | 80 | in { |
| 106 | config = { | 81 | config = { |
| 107 | services.zfssnap.config.exec = { | 82 | services.borgsnap = { |
| 108 | check = "${borgsnap}/bin/borgsnap -vv --target yggdrasil.borgbase:repo --archive-prefix yggdrasil.vidhar. check --cache-file /run/zfssnap-prune/archives-cache.json"; | 83 | enable = true; |
| 109 | cmd = "${borgsnap}/bin/borgsnap -vv --target yggdrasil.borgbase:repo --archive-prefix yggdrasil.vidhar. create"; | ||
| 110 | 84 | ||
| 111 | halfweekly = "8"; | 85 | target = "yggdrasil.borgbase:repo"; |
| 112 | monthly = "-1"; | 86 | inherit sshConfig; |
| 87 | keyfile = config.sops.secrets."yggdrasil.borgkey".path; | ||
| 113 | }; | 88 | }; |
| 114 | 89 | ||
| 115 | systemd.services = { | 90 | systemd.services = listToAttrs (map copyService [{ repo = "/srv/backup/borg/jotnar"; repoEscaped = "srv-backup-borg-jotnar"; }]); |
| 116 | "zfssnap-prune" = { | ||
| 117 | serviceConfig = { | ||
| 118 | Environment = [ | ||
| 119 | "BORG_RSH=\"${pkgs.openssh}/bin/ssh -F ${sshConfig}\"" | ||
| 120 | "BORG_BASE_DIR=/var/lib/borg" | ||
| 121 | "BORG_CONFIG_DIR=/var/lib/borg/config" | ||
| 122 | "BORG_CACHE_DIR=/var/lib/borg/cache" | ||
| 123 | "BORG_SECURITY_DIR=/var/lib/borg/security" | ||
| 124 | "BORG_KEYS_DIR=/var/lib/borg/keys" | ||
| 125 | "BORG_KEY_FILE=${config.sops.secrets."yggdrasil.borgkey".path}" | ||
| 126 | "BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK=yes" | ||
| 127 | "BORG_HOSTNAME_IS_UNIQUE=yes" | ||
| 128 | ]; | ||
| 129 | RuntimeDirectory = "zfssnap-prune"; | ||
| 130 | }; | ||
| 131 | }; | ||
| 132 | } // listToAttrs (map copyService [{ repo = "/srv/backup/borg/jotnar"; repoEscaped = "srv-backup-borg-jotnar"; }]); | ||
| 133 | |||
| 134 | 91 | ||
| 135 | services.borgbackup.repos.jotnar = { | 92 | services.borgbackup.repos.jotnar = { |
| 136 | path = "/srv/backup/borg/jotnar"; | 93 | path = "/srv/backup/borg/jotnar"; |
diff --git a/hosts/vidhar/borg/borgsnap/borgsnap/__main__.py b/modules/borgsnap/borgsnap/borgsnap/__main__.py index 15bf50c8..4b50cf80 100644 --- a/hosts/vidhar/borg/borgsnap/borgsnap/__main__.py +++ b/modules/borgsnap/borgsnap/borgsnap/__main__.py | |||
| @@ -357,6 +357,7 @@ def main(): | |||
| 357 | sys.excepthook = log_exceptions | 357 | sys.excepthook = log_exceptions |
| 358 | 358 | ||
| 359 | parser = argparse.ArgumentParser(prog='borgsnap') | 359 | parser = argparse.ArgumentParser(prog='borgsnap') |
| 360 | parser.add_argument('--verbosity', dest='log_level', action='append') | ||
| 360 | parser.add_argument('--verbose', '-v', dest='log_level', action='append_const', const=-1) | 361 | parser.add_argument('--verbose', '-v', dest='log_level', action='append_const', const=-1) |
| 361 | parser.add_argument('--quiet', '-q', dest='log_level', action='append_const', const=1) | 362 | parser.add_argument('--quiet', '-q', dest='log_level', action='append_const', const=1) |
| 362 | parser.add_argument('--target', metavar='REPO', default='yggdrasil.borgbase:repo') | 363 | parser.add_argument('--target', metavar='REPO', default='yggdrasil.borgbase:repo') |
diff --git a/hosts/vidhar/borg/borgsnap/setup.py b/modules/borgsnap/borgsnap/setup.py index 76356bfc..76356bfc 100644 --- a/hosts/vidhar/borg/borgsnap/setup.py +++ b/modules/borgsnap/borgsnap/setup.py | |||
diff --git a/modules/borgsnap/default.nix b/modules/borgsnap/default.nix new file mode 100644 index 00000000..f4c0eec4 --- /dev/null +++ b/modules/borgsnap/default.nix | |||
| @@ -0,0 +1,106 @@ | |||
| 1 | { config, pkgs, lib, flakeInputs, hostName, ... }: | ||
| 2 | |||
| 3 | with lib; | ||
| 4 | |||
| 5 | let | ||
| 6 | borgsnap = flakeInputs.mach-nix.lib.${config.nixpkgs.system}.buildPythonPackage rec { | ||
| 7 | pname = "borgsnap"; | ||
| 8 | src = ./borgsnap; | ||
| 9 | version = "0.0.0"; | ||
| 10 | ignoreDataOutdated = true; | ||
| 11 | |||
| 12 | requirements = '' | ||
| 13 | atomicwrites | ||
| 14 | pyprctl | ||
| 15 | python-unshare | ||
| 16 | python-dateutil | ||
| 17 | ''; | ||
| 18 | postInstall = '' | ||
| 19 | wrapProgram $out/bin/borgsnap \ | ||
| 20 | --prefix PATH : ${makeBinPath (with pkgs; [config.boot.zfs.package util-linux borgbackup])}:${config.security.wrapperDir} | ||
| 21 | ''; | ||
| 22 | |||
| 23 | providers.python-unshare = "nixpkgs"; | ||
| 24 | overridesPre = [ | ||
| 25 | (self: super: { python-unshare = super.python-unshare.overrideAttrs (oldAttrs: { name = "python-unshare-0.2.1"; version = "0.2.1"; }); }) | ||
| 26 | ]; | ||
| 27 | |||
| 28 | _.tomli.buildInputs.add = with pkgs."python3Packages"; [ flit-core ]; | ||
| 29 | }; | ||
| 30 | |||
| 31 | cfg = config.services.borgsnap; | ||
| 32 | in { | ||
| 33 | options = { | ||
| 34 | services.borgsnap = { | ||
| 35 | enable = mkEnableOption "borgsnap service"; | ||
| 36 | |||
| 37 | target = mkOption { | ||
| 38 | type = types.str; | ||
| 39 | }; | ||
| 40 | |||
| 41 | archive-prefix = mkOption { | ||
| 42 | type = types.str; | ||
| 43 | default = "yggdrasil.${hostName}."; | ||
| 44 | }; | ||
| 45 | |||
| 46 | extraConfig = mkOption { | ||
| 47 | type = with types; attrsOf str; | ||
| 48 | default = { | ||
| 49 | halfweekly = "8"; | ||
| 50 | monthly = "-1"; | ||
| 51 | }; | ||
| 52 | }; | ||
| 53 | |||
| 54 | verbosity = mkOption { | ||
| 55 | type = types.int; | ||
| 56 | default = config.services.zfssnap.verbosity; | ||
| 57 | }; | ||
| 58 | |||
| 59 | sshConfig = mkOption { | ||
| 60 | type = with types; nullOr str; | ||
| 61 | default = null; | ||
| 62 | }; | ||
| 63 | |||
| 64 | keyfile = mkOption { | ||
| 65 | type = with types; nullOr str; | ||
| 66 | default = null; | ||
| 67 | }; | ||
| 68 | |||
| 69 | extraCreateArgs = mkOption { | ||
| 70 | type = with types; listOf str; | ||
| 71 | default = []; | ||
| 72 | }; | ||
| 73 | extraCheckArgs = mkOption { | ||
| 74 | type = with types; listOf str; | ||
| 75 | default = []; | ||
| 76 | }; | ||
| 77 | }; | ||
| 78 | }; | ||
| 79 | |||
| 80 | config = mkIf cfg.enable { | ||
| 81 | warnings = mkIf (!config.services.zfssnap.enable) [ | ||
| 82 | "borgsnap will do nothing if zfssnap is not enabled" | ||
| 83 | ]; | ||
| 84 | |||
| 85 | services.zfssnap.config.exec = { | ||
| 86 | check = "${borgsnap}/bin/borgsnap --verbosity=${toString cfg.verbosity} --target ${escapeShellArg cfg.target} --archive-prefix ${escapeShellArg cfg.archive-prefix} check --cache-file /run/zfssnap-prune/archives-cache.json ${escapeShellArgs cfg.extraCheckArgs}"; | ||
| 87 | cmd = "${borgsnap}/bin/borgsnap --verbosity=${toString cfg.verbosity} --target ${escapeShellArg cfg.target} --archive-prefix ${escapeShellArg cfg.archive-prefix} create ${escapeShellArgs cfg.extraCreateArgs}"; | ||
| 88 | } // cfg.extraConfig; | ||
| 89 | |||
| 90 | systemd.services."zfssnap-prune" = { | ||
| 91 | serviceConfig = { | ||
| 92 | Environment = [ | ||
| 93 | "BORG_BASE_DIR=/var/lib/borg" | ||
| 94 | "BORG_CONFIG_DIR=/var/lib/borg/config" | ||
| 95 | "BORG_CACHE_DIR=/var/lib/borg/cache" | ||
| 96 | "BORG_SECURITY_DIR=/var/lib/borg/security" | ||
| 97 | "BORG_KEYS_DIR=/var/lib/borg/keys" | ||
| 98 | "BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK=yes" | ||
| 99 | "BORG_HOSTNAME_IS_UNIQUE=yes" | ||
| 100 | ] ++ optional (!(isNull cfg.sshConfig)) "BORG_RSH=\"${pkgs.openssh}/bin/ssh -F ${pkgs.writeText "config" cfg.sshConfig}\"" | ||
| 101 | ++ optional (!(isNull cfg.keyfile)) "BORG_KEY_FILE=${cfg.keyfile}"; | ||
| 102 | RuntimeDirectory = "zfssnap-prune"; | ||
| 103 | }; | ||
| 104 | }; | ||
| 105 | }; | ||
| 106 | } | ||
diff --git a/modules/zfssnap/default.nix b/modules/zfssnap/default.nix index f46cd510..f6f32852 100644 --- a/modules/zfssnap/default.nix +++ b/modules/zfssnap/default.nix | |||
| @@ -48,6 +48,20 @@ in { | |||
| 48 | type = types.str; | 48 | type = types.str; |
| 49 | default = "*-*-* *:00/5:00"; | 49 | default = "*-*-* *:00/5:00"; |
| 50 | }; | 50 | }; |
| 51 | |||
| 52 | verbosity = mkOption { | ||
| 53 | type = types.int; | ||
| 54 | default = 2; | ||
| 55 | }; | ||
| 56 | |||
| 57 | extraPruneArgs = mkOption { | ||
| 58 | type = with types; listOf str; | ||
| 59 | default = []; | ||
| 60 | }; | ||
| 61 | extraAutosnapArgs = mkOption { | ||
| 62 | type = with types; listOf str; | ||
| 63 | default = []; | ||
| 64 | }; | ||
| 51 | }; | 65 | }; |
| 52 | }; | 66 | }; |
| 53 | 67 | ||
| @@ -59,7 +73,7 @@ in { | |||
| 59 | before = [ "zfssnap-prune.service" ]; | 73 | before = [ "zfssnap-prune.service" ]; |
| 60 | serviceConfig = { | 74 | serviceConfig = { |
| 61 | Type = "oneshot"; | 75 | Type = "oneshot"; |
| 62 | ExecStart = "${zfssnap}/bin/zfssnap -vv"; | 76 | ExecStart = "${zfssnap}/bin/zfssnap --verbosity=${toString cfg.verbosity} autosnap ${escapeShellArgs cfg.extraAutosnapArgs}"; |
| 63 | 77 | ||
| 64 | LogRateLimitIntervalSec = 0; | 78 | LogRateLimitIntervalSec = 0; |
| 65 | }; | 79 | }; |
| @@ -72,7 +86,7 @@ in { | |||
| 72 | ExecStart = let | 86 | ExecStart = let |
| 73 | mkSectionName = name: strings.escape [ "[" "]" ] (strings.toUpper name); | 87 | mkSectionName = name: strings.escape [ "[" "]" ] (strings.toUpper name); |
| 74 | zfssnapConfig = generators.toINI { inherit mkSectionName; } cfg.config; | 88 | zfssnapConfig = generators.toINI { inherit mkSectionName; } cfg.config; |
| 75 | in "${zfssnap}/bin/zfssnap -vv prune --config=${pkgs.writeText "zfssnap.ini" zfssnapConfig}"; | 89 | in "${zfssnap}/bin/zfssnap --verbosity=${toString cfg.verbosity} prune --config=${pkgs.writeText "zfssnap.ini" zfssnapConfig} ${escapeShellArgs cfg.extraPruneArgs}"; |
| 76 | 90 | ||
| 77 | LogRateLimitIntervalSec = 0; | 91 | LogRateLimitIntervalSec = 0; |
| 78 | }; | 92 | }; |
diff --git a/modules/zfssnap/zfssnap/zfssnap/__main__.py b/modules/zfssnap/zfssnap/zfssnap/__main__.py index 9d07401b..59478c71 100644 --- a/modules/zfssnap/zfssnap/zfssnap/__main__.py +++ b/modules/zfssnap/zfssnap/zfssnap/__main__.py | |||
| @@ -375,10 +375,13 @@ def main(): | |||
| 375 | sys.excepthook = log_exceptions | 375 | sys.excepthook = log_exceptions |
| 376 | 376 | ||
| 377 | parser = argparse.ArgumentParser(prog='zfssnap') | 377 | parser = argparse.ArgumentParser(prog='zfssnap') |
| 378 | parser.add_argument('--verbosity', dest='log_level', action='append') | ||
| 378 | parser.add_argument('--verbose', '-v', dest='log_level', action='append_const', const=-1) | 379 | parser.add_argument('--verbose', '-v', dest='log_level', action='append_const', const=-1) |
| 379 | parser.add_argument('--quiet', '-q', dest='log_level', action='append_const', const=1) | 380 | parser.add_argument('--quiet', '-q', dest='log_level', action='append_const', const=1) |
| 380 | subparsers = parser.add_subparsers() | 381 | subparsers = parser.add_subparsers() |
| 381 | parser.set_defaults(cmd=autosnap) | 382 | parser.set_defaults(cmd=autosnap) |
| 383 | autosnap_parser = subparsers.add_parser('autosnap') | ||
| 384 | autosnap_parser.set_defaults(cmd=autosnap) | ||
| 382 | rename_parser = subparsers.add_parser('rename') | 385 | rename_parser = subparsers.add_parser('rename') |
| 383 | rename_parser.add_argument('snapshots', nargs='+') | 386 | rename_parser.add_argument('snapshots', nargs='+') |
| 384 | rename_parser.add_argument('--destroy', action='store_true', default=False) | 387 | rename_parser.add_argument('--destroy', action='store_true', default=False) |
