207 lines
5.1 KiB
Nix
207 lines
5.1 KiB
Nix
{ config, pkgs, ... }: with import <stockholm/lib>;
|
|
|
|
let
|
|
|
|
kcfg = config.krebs.syncthing;
|
|
scfg = config.services.syncthing;
|
|
|
|
devices = mapAttrsToList (name: peer: {
|
|
name = name;
|
|
deviceID = peer.id;
|
|
addresses = peer.addresses;
|
|
}) kcfg.peers;
|
|
|
|
folders = mapAttrsToList ( _: folder: {
|
|
inherit (folder) path id type;
|
|
devices = map (peer: { deviceId = kcfg.peers.${peer}.id; }) folder.peers;
|
|
rescanIntervalS = folder.rescanInterval;
|
|
fsWatcherEnabled = folder.watch;
|
|
fsWatcherDelayS = folder.watchDelay;
|
|
ignoreDelete = folder.ignoreDelete;
|
|
ignorePerms = folder.ignorePerms;
|
|
}) kcfg.folders;
|
|
|
|
getApiKey = pkgs.writeDash "getAPIKey" ''
|
|
${pkgs.libxml2}/bin/xmllint \
|
|
--xpath 'string(configuration/gui/apikey)'\
|
|
${scfg.configDir}/config.xml
|
|
'';
|
|
|
|
updateConfig = pkgs.writeDash "merge-syncthing-config" ''
|
|
set -efu
|
|
|
|
# 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)}
|
|
|
|
# wait for service to restart
|
|
${pkgs.untilport}/bin/untilport "$host" "$port"
|
|
|
|
API_KEY=$(${getApiKey})
|
|
|
|
_curl() {
|
|
${pkgs.curl}/bin/curl \
|
|
-Ss \
|
|
-H "X-API-Key: $API_KEY" \
|
|
"http://$host:$port/rest""$@"
|
|
}
|
|
|
|
old_config=$(_curl /system/config)
|
|
new_config=${shell.escape (toJSON {
|
|
inherit devices folders;
|
|
})}
|
|
new_config=$(${pkgs.jq}/bin/jq -en \
|
|
--argjson old_config "$old_config" \
|
|
--argjson new_config "$new_config" \
|
|
'
|
|
$old_config * $new_config
|
|
${optionalString (!kcfg.overridePeers) ''
|
|
* { devices: $old_config.devices }
|
|
''}
|
|
${optionalString (!kcfg.overrideFolders) ''
|
|
* { folders: $old_config.folders }
|
|
''}
|
|
'
|
|
)
|
|
echo $new_config | _curl /system/config -d @-
|
|
_curl /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;
|
|
};
|
|
|
|
overridePeers = mkOption {
|
|
type = types.bool;
|
|
default = true;
|
|
description = ''
|
|
Whether to delete the peers which are not configured via the peers option
|
|
'';
|
|
};
|
|
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;
|
|
};
|
|
|
|
};
|
|
}));
|
|
};
|
|
|
|
overrideFolders = mkOption {
|
|
type = types.bool;
|
|
default = true;
|
|
description = ''
|
|
Whether to delete the folders which are not configured via the peers option
|
|
'';
|
|
};
|
|
folders = mkOption {
|
|
default = {};
|
|
type = types.attrsOf (types.submodule ({ config, ... }: {
|
|
options = {
|
|
|
|
path = mkOption {
|
|
type = types.absolute-pathname;
|
|
default = config._module.args.name;
|
|
};
|
|
|
|
id = mkOption {
|
|
type = types.str;
|
|
default = config._module.args.name;
|
|
};
|
|
|
|
peers = mkOption {
|
|
type = types.listOf types.str;
|
|
default = [];
|
|
};
|
|
|
|
rescanInterval = mkOption {
|
|
type = types.int;
|
|
default = 3600;
|
|
};
|
|
|
|
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;
|
|
};
|
|
|
|
};
|
|
}));
|
|
};
|
|
};
|
|
|
|
config = mkIf kcfg.enable {
|
|
|
|
systemd.services.syncthing = mkIf (kcfg.cert != null || kcfg.key != null) {
|
|
serviceConfig.PermissionsStartOnly = mkDefault true;
|
|
preStart = ''
|
|
${optionalString (kcfg.cert != null) ''
|
|
cp ${toString kcfg.cert} ${scfg.configDir}/cert.pem
|
|
chown ${scfg.user}:${scfg.group} ${scfg.configDir}/cert.pem
|
|
chmod 400 ${scfg.configDir}/cert.pem
|
|
''}
|
|
${optionalString (kcfg.key != null) ''
|
|
cp ${toString kcfg.key} ${scfg.configDir}/key.pem
|
|
chown ${scfg.user}:${scfg.group} ${scfg.configDir}/key.pem
|
|
chmod 400 ${scfg.configDir}/key.pem
|
|
''}
|
|
'';
|
|
};
|
|
|
|
systemd.services.syncthing-init = {
|
|
after = [ "syncthing.service" ];
|
|
wantedBy = [ "multi-user.target" ];
|
|
|
|
serviceConfig = {
|
|
User = scfg.user;
|
|
RemainAfterExit = true;
|
|
Type = "oneshot";
|
|
ExecStart = updateConfig;
|
|
};
|
|
};
|
|
};
|
|
}
|