blob: 475edbd90344e92d4f5342cb3bef97829cc9d54b (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
{ config, pkgs, lib, utils, flakeInputs, ... }:
with lib;
let
copyBorg =
with pkgs.poetry2nix;
mkPoetryApplication {
projectDir = cleanPythonSources { src = ./.; };
overrides = overrides.withDefaults (self: super: {
pyprctl = super.pyprctl.overridePythonAttrs (oldAttrs: {
buildInputs = (oldAttrs.buildInputs or []) ++ [super.setuptools];
});
inherit (pkgs.python3Packages) python-unshare;
});
postInstall = ''
wrapProgram $out/bin/copy_borg \
--prefix PATH : ${makeBinPath (with pkgs; [util-linux borgbackup])}:${config.security.wrapperDir}
'';
};
copyService = name: opts: nameValuePair "copy-borg@${utils.escapeSystemdPath name}" {
serviceConfig = {
Type = "oneshot";
ExecStart = "${copyBorg}/bin/copy_borg --verbosity ${toString opts.verbosity} ${utils.escapeSystemdExecArgs [opts.from opts.to]}";
TimeoutStartSec = "8h";
# User = "borg";
# Group = "borg";
# StateDirectory = "borg";
RuntimeDirectory = "copy-borg";
Environment = [
"BORG_BASE_DIR=/var/lib/borg"
"BORG_CONFIG_DIR=/var/lib/borg/config"
"BORG_CACHE_DIR=/var/lib/borg/cache"
"BORG_SECURITY_DIR=/var/lib/borg/security"
"BORG_KEYS_DIR=/var/lib/borg/keys"
]
++ optional opts.unknownUnencryptedRepoAccessOk "BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK=yes"
++ optional opts.hostnameIsUnique "BORG_HOSTNAME_IS_UNIQUE=yes"
++ optional (!(isNull opts.sshConfig)) "BORG_RSH=\"${pkgs.openssh}/bin/ssh -F ${pkgs.writeText "config" opts.sshConfig}\""
++ optional (!(isNull opts.keyfile)) "BORG_KEY_FILE=${opts.keyfile}";
LogRateLimitIntervalSec = 0;
};
};
copyTimer = name: opts: nameValuePair "copy-borg@${utils.escapeSystemdPath name}" (recursiveUpdate {
wantedBy = [ "timers.target" ];
timerConfig = {
Unit = "copy-borg@${utils.escapeSystemdPath name}.service";
};
} opts.timerOptions);
cfg = config.services.copyborg;
in {
options = {
services.copyborg = mkOption {
type = types.attrsOf (types.submodule {
options = {
from = mkOption {
type = types.str;
description = "Copy from this repository";
};
to = mkOption {
type = types.str;
description = "Copy to this repository";
};
verbosity = mkOption {
type = types.int;
default = 3;
description = "Set verbosity";
};
sshConfig = mkOption {
type = with types; nullOr str;
default = null;
description = "SSH client configuration";
};
keyfile = mkOption {
type = with types; nullOr str;
default = null;
description = "Keyfile to pass to borg";
};
unknownUnencryptedRepoAccessOk = mkOption {
type = types.bool;
default = false;
description = "Set `BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK`?";
};
hostnameIsUnique = mkOption {
type = types.bool;
default = true;
description = "Set `BORG_HOSTNAME_IS_UNIQUE`?";
};
timerOptions = mkOption {
# type = types.submodule utils.systemdUtils.unitOptions.stage2TimerOptions;
type = types.attrs;
default = {
wantedBy = ["timers.target"];
};
description = "Systemd timer options";
};
};
});
default = {};
description = "Copy borg archives from one repository to another";
};
};
config = {
systemd.services = mapAttrs' copyService cfg;
systemd.timers = mapAttrs' copyTimer cfg;
};
}
|