diff --git a/global/fs/zfs/default.nix b/global/fs/zfs/default.nix index 095f39d8..70520af2 100644 --- a/global/fs/zfs/default.nix +++ b/global/fs/zfs/default.nix @@ -6,6 +6,7 @@ in { imports = [ ./split.nix + ./replication.nix ]; # -o ashift=12 @@ -42,6 +43,24 @@ in { description = "UUID of store filesystem"; }; }; + + replication = { + enable = mkEnableOption "zfs replication to remote"; + remote = mkOption { + type = with types; str; + description = "remote host as replication destination"; + }; + datasets = mkOption { + type = with types; listOf str; + default = [ "persist" "service" "storage" ]; + description = "list of filesystems to perform replication for"; + }; + sendOptions = mkOption { + type = with types; str; + default = "w"; + description = "send options for all datasets"; + }; + }; }; config = mkIf (cfg.type == "zfs") { diff --git a/global/fs/zfs/replication.nix b/global/fs/zfs/replication.nix new file mode 100644 index 00000000..8f04cd63 --- /dev/null +++ b/global/fs/zfs/replication.nix @@ -0,0 +1,29 @@ +{ pkgs +, lib +, config +, ... }: with lib; let + cfg = config.global.fs.zfs.replication; +in mkIf cfg.enable { + services.syncoid = { + enable = mkDefault true; + interval = mkDefault "daily"; + sshKey = mkDefault "/var/lib/syncoid/.ssh/id_ed25519"; + commonArgs = [ + "--recursive" + "--compress=lz4" + "--mbuffer-size=128M" + ]; + localSourceAllow = options.services.syncoid.localSourceAllow.default ++ [ "mount" ]; + + commands = (lists.foldr (name: commands: commands // { + "${config.global.fs.store}/${name}" = { + inherit (cfg) sendOptions; + target = "${cfg.remote}/${name}"; + }; + }) { }) cfg.datasets; + }; + + users.users.syncoid.uid = 82; + users.groups.syncoid.gid = 82; + environment.persistence."/nix/persist/fhs".directories = [ "/var/lib/syncoid" ]; +}