summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregor Kleen <gkleen@yggdrasil.li>2022-11-01 22:43:25 +0100
committerGregor Kleen <gkleen@yggdrasil.li>2022-11-01 22:43:25 +0100
commit7448d3431fcfc05f9b7991e337b02083300a99db (patch)
tree0664ebc0f666ef404881ac7287198ff44c0ba9e0
parent234eab10a84e7ffb8bbc32f5e2f94495d3c9aedd (diff)
downloadnixos-7448d3431fcfc05f9b7991e337b02083300a99db.tar
nixos-7448d3431fcfc05f9b7991e337b02083300a99db.tar.gz
nixos-7448d3431fcfc05f9b7991e337b02083300a99db.tar.bz2
nixos-7448d3431fcfc05f9b7991e337b02083300a99db.tar.xz
nixos-7448d3431fcfc05f9b7991e337b02083300a99db.zip
...
-rw-r--r--hosts/vidhar/borg/default.nix61
-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.nix106
-rw-r--r--modules/zfssnap/default.nix18
-rw-r--r--modules/zfssnap/zfssnap/zfssnap/__main__.py3
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 @@
3with lib; 3with lib;
4 4
5let 5let
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 };
105in { 80in {
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
3with lib;
4
5let
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;
32in {
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)