2019-03-22 06:57:34 +00:00
|
|
|
{ config, pkgs, ... }: with import <stockholm/lib>;
|
|
|
|
|
|
|
|
let
|
|
|
|
|
|
|
|
cfg = config.krebs.syncthing;
|
|
|
|
|
|
|
|
devices = mapAttrsToList (name: peer: {
|
|
|
|
name = name;
|
|
|
|
deviceID = peer.id;
|
|
|
|
addresses = peer.addresses;
|
|
|
|
}) cfg.peers;
|
|
|
|
|
2019-04-18 08:14:18 +00:00
|
|
|
folders = mapAttrsToList ( _: folder: {
|
2019-04-07 16:21:18 +00:00
|
|
|
inherit (folder) path id type;
|
2019-03-22 06:57:34 +00:00
|
|
|
devices = map (peer: { deviceId = cfg.peers.${peer}.id; }) folder.peers;
|
|
|
|
rescanIntervalS = folder.rescanInterval;
|
2019-03-23 15:04:01 +00:00
|
|
|
fsWatcherEnabled = folder.watch;
|
|
|
|
fsWatcherDelayS = folder.watchDelay;
|
|
|
|
ignorePerms = folder.ignorePerms;
|
2019-03-22 06:57:34 +00:00
|
|
|
}) cfg.folders;
|
|
|
|
|
|
|
|
getApiKey = pkgs.writeDash "getAPIKey" ''
|
|
|
|
${pkgs.libxml2}/bin/xmllint \
|
|
|
|
--xpath 'string(configuration/gui/apikey)'\
|
2019-05-29 13:18:24 +00:00
|
|
|
${config.services.syncthing.configDir}/config.xml
|
2019-03-22 06:57:34 +00:00
|
|
|
'';
|
|
|
|
|
|
|
|
updateConfig = pkgs.writeDash "merge-syncthing-config" ''
|
|
|
|
set -efu
|
2019-03-23 15:04:22 +00:00
|
|
|
# wait for service to restart
|
|
|
|
${pkgs.untilport}/bin/untilport localhost 8384
|
2019-03-22 06:57:34 +00:00
|
|
|
API_KEY=$(${getApiKey})
|
|
|
|
CFG=$(${pkgs.curl}/bin/curl -Ss -H "X-API-Key: $API_KEY" localhost:8384/rest/system/config)
|
2019-05-29 13:18:24 +00:00
|
|
|
echo "$CFG" | ${pkgs.jq}/bin/jq -s '.[] as $in | $in * {
|
|
|
|
"devices": (${builtins.toJSON devices}${optionalString (! cfg.overridePeers) " + $in.devices"}),
|
|
|
|
"folders": (${builtins.toJSON folders}${optionalString (! cfg.overrideFolders) " + $in.folders"})
|
2019-03-22 06:57:34 +00:00
|
|
|
}' | ${pkgs.curl}/bin/curl -Ss -H "X-API-Key: $API_KEY" localhost:8384/rest/system/config -d @-
|
|
|
|
${pkgs.curl}/bin/curl -Ss -H "X-API-Key: $API_KEY" localhost:8384/rest/system/restart -X POST
|
|
|
|
'';
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
{
|
|
|
|
options.krebs.syncthing = {
|
|
|
|
|
|
|
|
enable = mkEnableOption "syncthing-init";
|
|
|
|
|
|
|
|
cert = mkOption {
|
|
|
|
type = types.nullOr types.absolute-pathname;
|
|
|
|
default = null;
|
|
|
|
};
|
|
|
|
|
|
|
|
key = mkOption {
|
|
|
|
type = types.nullOr types.absolute-pathname;
|
|
|
|
default = null;
|
|
|
|
};
|
|
|
|
|
2019-05-29 13:18:24 +00:00
|
|
|
overridePeers = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = true;
|
|
|
|
description = ''
|
|
|
|
Whether to delete the peers which are not configured via the peers option
|
|
|
|
'';
|
|
|
|
};
|
2019-03-22 06:57:34 +00:00
|
|
|
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;
|
|
|
|
};
|
|
|
|
|
|
|
|
};
|
|
|
|
}));
|
|
|
|
};
|
|
|
|
|
2019-05-29 13:18:24 +00:00
|
|
|
overrideFolders = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = true;
|
|
|
|
description = ''
|
|
|
|
Whether to delete the folders which are not configured via the peers option
|
|
|
|
'';
|
|
|
|
};
|
2019-03-22 06:57:34 +00:00
|
|
|
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;
|
2019-03-23 15:04:50 +00:00
|
|
|
default = 3600;
|
2019-03-22 06:57:34 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
type = mkOption {
|
|
|
|
type = types.enum [ "sendreceive" "sendonly" "receiveonly" ];
|
|
|
|
default = "sendreceive";
|
|
|
|
};
|
|
|
|
|
2019-03-23 15:04:01 +00:00
|
|
|
watch = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = true;
|
|
|
|
};
|
|
|
|
|
|
|
|
watchDelay = mkOption {
|
|
|
|
type = types.int;
|
|
|
|
default = 10;
|
|
|
|
};
|
|
|
|
|
|
|
|
ignorePerms = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = true;
|
|
|
|
};
|
|
|
|
|
2019-03-22 06:57:34 +00:00
|
|
|
};
|
|
|
|
}));
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
config = (mkIf cfg.enable) {
|
|
|
|
|
|
|
|
systemd.services.syncthing = mkIf (cfg.cert != null || cfg.key != null) {
|
|
|
|
preStart = ''
|
2019-04-09 14:52:17 +00:00
|
|
|
${optionalString (cfg.cert != null) ''
|
2019-05-29 13:18:24 +00:00
|
|
|
cp ${toString cfg.cert} ${config.services.syncthing.configDir}/cert.pem
|
|
|
|
chown ${config.services.syncthing.user}:${config.services.syncthing.group} ${config.services.syncthing.configDir}/cert.pem
|
|
|
|
chmod 400 ${config.services.syncthing.configDir}/cert.pem
|
2019-04-09 14:52:17 +00:00
|
|
|
''}
|
|
|
|
${optionalString (cfg.key != null) ''
|
2019-05-29 13:18:24 +00:00
|
|
|
cp ${toString cfg.key} ${config.services.syncthing.configDir}/key.pem
|
|
|
|
chown ${config.services.syncthing.user}:${config.services.syncthing.group} ${config.services.syncthing.configDir}/key.pem
|
|
|
|
chmod 400 ${config.services.syncthing.configDir}/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 = config.services.syncthing.user;
|
|
|
|
RemainAfterExit = true;
|
|
|
|
Type = "oneshot";
|
|
|
|
ExecStart = updateConfig;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|