diff options
author | Katharina Fey <kookie@spacekookie.de> | 2020-02-03 10:05:30 +0100 |
---|---|---|
committer | Katharina Fey <kookie@spacekookie.de> | 2020-02-03 10:05:30 +0100 |
commit | c488527c95c874d3b8743c915173ad7bfb05d5af (patch) | |
tree | 2b874dc5606a9dff44096a5e8557f00dc52ac2b6 /home-manager/modules/services/unison.nix | |
parent | 899a451e08f7d6d2c8214d119c2a0316849a0ed4 (diff) | |
parent | 6cc4fd6ede4909226cb81d3475834251ed1b7210 (diff) |
Merge commit '6cc4fd6ede4909226cb81d3475834251ed1b7210'
Diffstat (limited to 'home-manager/modules/services/unison.nix')
-rw-r--r-- | home-manager/modules/services/unison.nix | 121 |
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" ]; }; + }); + }; +} |