1{
2 lib,
3 pkgs,
4 config,
5 ...
6}:
7let
8 cfg = config.services.zfs.autoReplication;
9in
10{
11 options = {
12 services.zfs.autoReplication = {
13 enable = lib.mkEnableOption "ZFS snapshot replication";
14
15 package = lib.mkPackageOption pkgs "zfs-replicate" { };
16
17 followDelete = lib.mkOption {
18 description = "Remove remote snapshots that don't have a local correspondent.";
19 default = true;
20 type = lib.types.bool;
21 };
22
23 host = lib.mkOption {
24 description = "Remote host where snapshots should be sent. `lz4` is expected to be installed on this host.";
25 example = "example.com";
26 type = lib.types.str;
27 };
28
29 identityFilePath = lib.mkOption {
30 description = "Path to SSH key used to login to host.";
31 example = "/home/username/.ssh/id_rsa";
32 type = lib.types.path;
33 };
34
35 localFilesystem = lib.mkOption {
36 description = "Local ZFS filesystem from which snapshots should be sent. Defaults to the attribute name.";
37 example = "pool/file/path";
38 type = lib.types.str;
39 };
40
41 remoteFilesystem = lib.mkOption {
42 description = "Remote ZFS filesystem where snapshots should be sent.";
43 example = "pool/file/path";
44 type = lib.types.str;
45 };
46
47 recursive = lib.mkOption {
48 description = "Recursively discover snapshots to send.";
49 default = true;
50 type = lib.types.bool;
51 };
52
53 username = lib.mkOption {
54 description = "Username used by SSH to login to remote host.";
55 example = "username";
56 type = lib.types.str;
57 };
58 };
59 };
60
61 config = lib.mkIf cfg.enable {
62 environment.systemPackages = [
63 pkgs.lz4
64 ];
65
66 systemd.services.zfs-replication = {
67 after = [
68 "zfs-snapshot-daily.service"
69 "zfs-snapshot-frequent.service"
70 "zfs-snapshot-hourly.service"
71 "zfs-snapshot-monthly.service"
72 "zfs-snapshot-weekly.service"
73 ];
74 description = "ZFS Snapshot Replication";
75 documentation = [
76 "https://github.com/alunduil/zfs-replicate"
77 ];
78 restartIfChanged = false;
79 serviceConfig.ExecStart =
80 let
81 args = lib.map lib.escapeShellArg (
82 [
83 "--verbose"
84 "--user"
85 cfg.username
86 "--identity-file"
87 cfg.identityFilePath
88 cfg.host
89 cfg.remoteFilesystem
90 cfg.localFilesystem
91 ]
92 ++ (lib.optional cfg.recursive "--recursive")
93 ++ (lib.optional cfg.followDelete "--follow-delete")
94 );
95 in
96 "${lib.getExe cfg.package} ${lib.concatStringsSep " " args}";
97 wantedBy = [
98 "zfs-snapshot-daily.service"
99 "zfs-snapshot-frequent.service"
100 "zfs-snapshot-hourly.service"
101 "zfs-snapshot-monthly.service"
102 "zfs-snapshot-weekly.service"
103 ];
104 };
105 };
106
107 meta = {
108 maintainers = with lib.maintainers; [ alunduil ];
109 };
110}