stockholm/krebs/3modules/syncthing.nix

191 lines
4.5 KiB
Nix
Raw Normal View History

2019-03-22 06:57:34 +00:00
{ config, pkgs, ... }: with import <stockholm/lib>;
let
kcfg = config.krebs.syncthing;
scfg = config.services.syncthing;
2019-03-22 06:57:34 +00:00
devices = mapAttrsToList (name: peer: {
name = name;
deviceID = peer.id;
addresses = peer.addresses;
}) kcfg.peers;
2019-03-22 06:57:34 +00:00
2019-04-18 08:14:18 +00:00
folders = mapAttrsToList ( _: folder: {
2019-04-07 16:21:18 +00:00
inherit (folder) path id type;
devices = map (peer: { deviceId = kcfg.peers.${peer}.id; }) folder.peers;
2019-03-22 06:57:34 +00:00
rescanIntervalS = folder.rescanInterval;
fsWatcherEnabled = folder.watch;
fsWatcherDelayS = folder.watchDelay;
ignoreDelete = folder.ignoreDelete;
ignorePerms = folder.ignorePerms;
}) kcfg.folders;
2019-03-22 06:57:34 +00:00
getApiKey = pkgs.writeDash "getAPIKey" ''
${pkgs.libxml2}/bin/xmllint \
--xpath 'string(configuration/gui/apikey)'\
${scfg.dataDir}/config.xml
2019-03-22 06:57:34 +00:00
'';
updateConfig = pkgs.writeDash "merge-syncthing-config" ''
set -efu
2019-06-21 23:36:50 +00:00
# XXX this assumes the GUI address to be "IPv4 address and port"
host=${shell.escape (elemAt (splitString ":" scfg.guiAddress) 0)}
port=${shell.escape (elemAt (splitString ":" scfg.guiAddress) 1)}
2019-03-23 15:04:22 +00:00
# wait for service to restart
2019-06-21 23:36:50 +00:00
${pkgs.untilport}/bin/untilport "$host" "$port"
2019-03-22 06:57:34 +00:00
API_KEY=$(${getApiKey})
2019-06-21 23:36:50 +00:00
_curl() {
${pkgs.curl}/bin/curl \
-Ss \
-H "X-API-Key: $API_KEY" \
"http://$host:$port/rest""$@"
}
old_config=$(_curl /system/config)
patch=${shell.escape (toJSON {
inherit devices folders;
})}
new_config=$(${pkgs.jq}/bin/jq -en \
--argjson old_config "$old_config" \
--argjson patch "$patch" \
'
$old_config * $patch
'
)
echo $new_config | _curl /system/config -d @-
_curl /system/restart -X POST
2019-03-22 06:57:34 +00:00
'';
in
{
options.krebs.syncthing = {
enable = mkEnableOption "syncthing-init";
id = mkOption {
type = types.str;
default = config.krebs.build.host.name;
};
cert = mkOption {
type = types.nullOr types.absolute-pathname;
default = null;
};
key = mkOption {
type = types.nullOr types.absolute-pathname;
default = null;
};
peers = mkOption {
default = {};
type = types.attrsOf (types.submodule ({
options = {
# TODO make into addr + port submodule
addresses = mkOption {
type = types.listOf types.str;
default = [];
};
#TODO check
id = mkOption {
type = types.str;
};
};
}));
};
folders = mkOption {
2019-04-18 08:14:18 +00:00
default = {};
type = types.attrsOf (types.submodule ({ config, ... }: {
2019-03-22 06:57:34 +00:00
options = {
path = mkOption {
type = types.absolute-pathname;
2019-04-18 08:14:18 +00:00
default = config._module.args.name;
2019-03-22 06:57:34 +00:00
};
2019-04-07 16:21:18 +00:00
id = mkOption {
type = types.str;
2019-04-18 08:14:18 +00:00
default = config._module.args.name;
2019-04-07 16:21:18 +00:00
};
2019-03-22 06:57:34 +00:00
peers = mkOption {
type = types.listOf types.str;
default = [];
};
rescanInterval = mkOption {
type = types.int;
default = 3600;
2019-03-22 06:57:34 +00:00
};
type = mkOption {
type = types.enum [ "sendreceive" "sendonly" "receiveonly" ];
default = "sendreceive";
};
watch = mkOption {
type = types.bool;
default = true;
};
watchDelay = mkOption {
type = types.int;
default = 10;
};
ignoreDelete = mkOption {
type = types.bool;
default = false;
};
ignorePerms = mkOption {
type = types.bool;
default = true;
};
2019-03-22 06:57:34 +00:00
};
}));
};
};
config = mkIf kcfg.enable {
2019-03-22 06:57:34 +00:00
systemd.services.syncthing = mkIf (kcfg.cert != null || kcfg.key != null) {
2019-03-22 06:57:34 +00:00
preStart = ''
${optionalString (kcfg.cert != null) ''
cp ${toString kcfg.cert} ${scfg.dataDir}/cert.pem
chown ${scfg.user}:${scfg.group} ${scfg.dataDir}/cert.pem
chmod 400 ${scfg.dataDir}/cert.pem
2019-04-09 14:52:17 +00:00
''}
${optionalString (kcfg.key != null) ''
cp ${toString kcfg.key} ${scfg.dataDir}/key.pem
chown ${scfg.user}:${scfg.group} ${scfg.dataDir}/key.pem
chmod 400 ${scfg.dataDir}/key.pem
2019-04-09 14:52:17 +00:00
''}
2019-03-22 06:57:34 +00:00
'';
};
systemd.services.syncthing-init = {
after = [ "syncthing.service" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
User = scfg.user;
2019-03-22 06:57:34 +00:00
RemainAfterExit = true;
Type = "oneshot";
ExecStart = updateConfig;
};
};
};
}