blob: af021777adb96bfcdb4acf81c5c37154c25efebc (
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
120
121
122
123
124
125
126
127
|
{ config, pkgs, lib, utils, flake, flakeInputs, ... }:
with lib;
let
copyBorg = let
workspace = flakeInputs.uv2nix.lib.workspace.loadWorkspace { workspaceRoot = ./.; };
pythonSet = flake.lib.pythonSet {
inherit pkgs;
python = pkgs.python312;
overlay = workspace.mkPyprojectOverlay {
sourcePreference = "wheel";
};
};
virtualEnv = pythonSet.mkVirtualEnv "copy_borg" workspace.deps.default;
in virtualEnv.overrideAttrs (oldAttrs: {
meta = (oldAttrs.meta or {}) // {
mainProgram = "copy_borg";
};
nativeBuildInputs = (oldAttrs.nativeBuildInputs or []) ++ [ pkgs.makeWrapper ];
postInstall = ''
${oldAttrs.postInstall or ""}
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}" {
restartIfChanged = false;
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;
};
}
|