aboutsummaryrefslogtreecommitdiff
path: root/home-manager/modules/services/unison.nix
diff options
context:
space:
mode:
authorKatharina Fey <kookie@spacekookie.de>2020-02-03 10:05:30 +0100
committerKatharina Fey <kookie@spacekookie.de>2020-02-03 10:05:30 +0100
commitc488527c95c874d3b8743c915173ad7bfb05d5af (patch)
tree2b874dc5606a9dff44096a5e8557f00dc52ac2b6 /home-manager/modules/services/unison.nix
parent899a451e08f7d6d2c8214d119c2a0316849a0ed4 (diff)
parent6cc4fd6ede4909226cb81d3475834251ed1b7210 (diff)
Merge commit '6cc4fd6ede4909226cb81d3475834251ed1b7210'
Diffstat (limited to 'home-manager/modules/services/unison.nix')
-rw-r--r--home-manager/modules/services/unison.nix121
1 files changed, 121 insertions, 0 deletions
diff --git a/home-manager/modules/services/unison.nix b/home-manager/modules/services/unison.nix
new file mode 100644
index 00000000000..93c59e8fd62
--- /dev/null
+++ b/home-manager/modules/services/unison.nix
@@ -0,0 +1,121 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+ cfg = config.services.unison;
+
+ pairOf = t:
+ let list = types.addCheck (types.listOf t) (l: length l == 2);
+ in list // { description = list.description + " of length 2"; };
+
+ pairOptions = {
+ options = {
+ stateDirectory = mkOption {
+ type = types.path;
+ default = "${config.xdg.dataHome}/unison";
+ defaultText = "$XDG_DATA_HOME/unison";
+ description = ''
+ Unison state directory to use.
+ '';
+ };
+
+ commandOptions = mkOption rec {
+ type = with types; attrsOf str;
+ apply = mergeAttrs default;
+ default = {
+ repeat = "watch";
+ sshcmd = "${pkgs.openssh}/bin/ssh";
+ ui = "text";
+ auto = "true";
+ batch = "true";
+ log = "false"; # don't log to file, handled by systemd
+ };
+ description = ''
+ Additional command line options as a dictionary to pass to the
+ <literal>unison</literal> program.
+ </para><para>
+ See
+ <citerefentry>
+ <refentrytitle>unison</refentrytitle>
+ <manvolnum>1</manvolnum>
+ </citerefentry>
+ for a list of available options.
+ '';
+ };
+
+ roots = mkOption {
+ type = pairOf types.str;
+ example = literalExample ''
+ [
+ "/home/user/documents"
+ "ssh://remote/documents"
+ ]
+ '';
+ description = ''
+ Pair of roots to synchronise.
+ '';
+ };
+ };
+ };
+
+ serialiseArg = key: val: "-${key}=${escapeShellArg val}";
+
+ serialiseArgs = args: concatStringsSep " " (mapAttrsToList serialiseArg args);
+
+ makeDefs = gen:
+ mapAttrs'
+ (name: pairCfg: nameValuePair "unison-pair-${name}" (gen name pairCfg))
+ cfg.pairs;
+
+in {
+ meta.maintainers = with maintainers; [ pacien ];
+
+ options.services.unison = {
+ enable = mkEnableOption "Unison synchronisation";
+
+ pairs = mkOption {
+ type = with types; attrsOf (submodule pairOptions);
+ default = { };
+ example = literalExample ''
+ {
+ roots = [
+ "/home/user/documents"
+ "ssh://remote/documents"
+ ];
+ }
+ '';
+ description = ''
+ Unison root pairs to keep synchronised.
+ '';
+ };
+ };
+
+ config = mkIf cfg.enable {
+ systemd.user.services = makeDefs (name: pairCfg: {
+ Unit = {
+ Description = "Unison pair sync (${name})";
+ # Retry forever, useful in case of network disruption.
+ StartLimitIntervalSec = 0;
+ };
+
+ Service = {
+ Restart = "always";
+ RestartSec = 60;
+
+ CPUSchedulingPolicy = "idle";
+ IOSchedulingClass = "idle";
+
+ Environment = [ "UNISON='${toString pairCfg.stateDirectory}'" ];
+ ExecStart = ''
+ ${pkgs.unison}/bin/unison \
+ ${serialiseArgs pairCfg.commandOptions} \
+ ${strings.concatMapStringsSep " " escapeShellArg pairCfg.roots}
+ '';
+ };
+
+ Install = { WantedBy = [ "default.target" ]; };
+ });
+ };
+}