aboutsummaryrefslogtreecommitdiff
path: root/modules/services/unison.nix
diff options
context:
space:
mode:
authorpacien <pacien.trangirard@pacien.net>2019-07-15 01:33:13 +0200
committerRobert Helgesson <robert@rycee.net>2019-11-29 23:49:00 +0100
commit94d183eaaa573b364b5eeba6b6845db9e50db291 (patch)
treeb54a6daccb047a6172d956a67e34e4904624af47 /modules/services/unison.nix
parent9d09738e4dd4b4a80f3a26e0e0fe14a06dd53ddc (diff)
unison: add module
Diffstat (limited to 'modules/services/unison.nix')
-rw-r--r--modules/services/unison.nix128
1 files changed, 128 insertions, 0 deletions
diff --git a/modules/services/unison.nix b/modules/services/unison.nix
new file mode 100644
index 00000000000..fc998e39a00
--- /dev/null
+++ b/modules/services/unison.nix
@@ -0,0 +1,128 @@
+{ 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" ];
+ };
+ });
+ };
+}