home-manager/modules/services/unison.nix

130 lines
3.3 KiB
Nix
Raw Normal View History

2019-07-14 23:33:13 +00:00
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.unison;
pairOf = t:
2020-02-01 23:39:17 +00:00
let list = types.addCheck (types.listOf t) (l: length l == 2);
in list // { description = list.description + " of length 2"; };
2019-07-14 23:33:13 +00:00
pairOptions = {
options = {
stateDirectory = mkOption {
type = types.path;
default = "${config.xdg.dataHome}/unison";
defaultText = "$XDG_DATA_HOME/unison";
description = lib.mdDoc ''
2019-07-14 23:33:13 +00:00
Unison state directory to use.
'';
};
commandOptions = mkOption rec {
type = with types; attrsOf (either str (listOf str));
2019-07-14 23:33:13 +00:00
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 = lib.mdDoc ''
2019-07-14 23:33:13 +00:00
Additional command line options as a dictionary to pass to the
`unison` program.
Use a list of strings to declare the same option multiple times.
2019-07-14 23:33:13 +00:00
See
{manpage}`unison(1)`
2019-07-14 23:33:13 +00:00
for a list of available options.
'';
};
roots = mkOption {
type = pairOf types.str;
example = literalExpression ''
2019-07-14 23:33:13 +00:00
[
"/home/user/documents"
"ssh://remote/documents"
]
'';
description = lib.mdDoc ''
2019-07-14 23:33:13 +00:00
Pair of roots to synchronise.
'';
};
};
};
serialiseArg = key: val:
concatStringsSep " "
(forEach (toList val) (x: escapeShellArg "-${key}=${escape [ "=" ] x}"));
2019-07-14 23:33:13 +00:00
2020-02-01 23:39:17 +00:00
serialiseArgs = args: concatStringsSep " " (mapAttrsToList serialiseArg args);
2019-07-14 23:33:13 +00:00
makeDefs = gen:
mapAttrs'
2020-02-01 23:39:17 +00:00
(name: pairCfg: nameValuePair "unison-pair-${name}" (gen name pairCfg))
cfg.pairs;
2019-07-14 23:33:13 +00:00
2020-02-01 23:39:17 +00:00
in {
2019-07-14 23:33:13 +00:00
meta.maintainers = with maintainers; [ pacien ];
options.services.unison = {
enable = mkEnableOption (lib.mdDoc "Unison synchronisation");
2019-07-14 23:33:13 +00:00
pairs = mkOption {
type = with types; attrsOf (submodule pairOptions);
default = { };
example = literalExpression ''
2019-07-14 23:33:13 +00:00
{
"my-documents" = {
roots = [
"/home/user/documents"
"ssh://remote/documents"
];
};
2019-07-14 23:33:13 +00:00
}
'';
description = lib.mdDoc ''
2019-07-14 23:33:13 +00:00
Unison root pairs to keep synchronised.
'';
};
};
config = mkIf cfg.enable {
assertions = [
(lib.hm.assertions.assertPlatform "services.unison" pkgs
lib.platforms.linux)
];
2019-07-14 23:33:13 +00:00
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}
'';
};
2020-02-01 23:39:17 +00:00
Install = { WantedBy = [ "default.target" ]; };
2019-07-14 23:33:13 +00:00
});
};
}