From 94d183eaaa573b364b5eeba6b6845db9e50db291 Mon Sep 17 00:00:00 2001 From: pacien Date: Mon, 15 Jul 2019 01:33:13 +0200 Subject: [PATCH] unison: add module --- modules/misc/news.nix | 8 +++ modules/modules.nix | 1 + modules/services/unison.nix | 128 ++++++++++++++++++++++++++++++++++++ 3 files changed, 137 insertions(+) create mode 100644 modules/services/unison.nix diff --git a/modules/misc/news.nix b/modules/misc/news.nix index a6a3d3eb..f1074fc1 100644 --- a/modules/misc/news.nix +++ b/modules/misc/news.nix @@ -1260,6 +1260,14 @@ in A new module is available: 'services.password-store-sync'. ''; } + + { + time = "2019-11-29T22:46:49+00:00"; + condition = hostPlatform.isLinux; + message = '' + A new module is available: 'services.unison'. + ''; + } ]; }; } diff --git a/modules/modules.nix b/modules/modules.nix index bfd864cc..f32a9d7c 100644 --- a/modules/modules.nix +++ b/modules/modules.nix @@ -142,6 +142,7 @@ let (loadModule ./services/taskwarrior-sync.nix { condition = hostPlatform.isLinux; }) (loadModule ./services/udiskie.nix { }) (loadModule ./services/unclutter.nix { }) + (loadModule ./services/unison.nix { condition = hostPlatform.isLinux; }) (loadModule ./services/window-managers/awesome.nix { }) (loadModule ./services/window-managers/i3.nix { }) (loadModule ./services/window-managers/xmonad.nix { }) diff --git a/modules/services/unison.nix b/modules/services/unison.nix new file mode 100644 index 00000000..fc998e39 --- /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 + unison program. + + See + + unison + 1 + + 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" ]; + }; + }); + }; +}