forked from clan/clan-core
init: syncthing module
Assumes one `introducer` peer, which can AutoShare configured folders, with peers that know the `deviceID` of the introducer.
This commit is contained in:
parent
7f68da2715
commit
ff3b8f1db0
@ -18,6 +18,7 @@
|
|||||||
deltachat = import ./deltachat nixosTestArgs;
|
deltachat = import ./deltachat nixosTestArgs;
|
||||||
meshnamed = import ./meshnamed nixosTestArgs;
|
meshnamed = import ./meshnamed nixosTestArgs;
|
||||||
borgbackup = import ./borgbackup nixosTestArgs;
|
borgbackup = import ./borgbackup nixosTestArgs;
|
||||||
|
syncthing = import ./syncthing nixosTestArgs;
|
||||||
};
|
};
|
||||||
schemaTests = pkgs.callPackages ./schemas.nix {
|
schemaTests = pkgs.callPackages ./schemas.nix {
|
||||||
inherit self;
|
inherit self;
|
||||||
|
108
checks/syncthing/default.nix
Normal file
108
checks/syncthing/default.nix
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
(import ../lib/test-base.nix) (
|
||||||
|
# Using nixos-test, because our own test system doesn't support the necessary
|
||||||
|
# features for systemd.
|
||||||
|
{ lib, ... }:
|
||||||
|
{
|
||||||
|
name = "syncthing";
|
||||||
|
|
||||||
|
nodes.introducer =
|
||||||
|
{ self, ... }:
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
self.clanModules.syncthing
|
||||||
|
self.nixosModules.clanCore
|
||||||
|
{
|
||||||
|
clanCore.machineName = "introducer";
|
||||||
|
clanCore.clanDir = ./.;
|
||||||
|
environment.etc = {
|
||||||
|
"syncthing.pam".source = ./introducer/introducer_test_cert;
|
||||||
|
"syncthing.key".source = ./introducer/introducer_test_key;
|
||||||
|
"syncthing.api".source = ./introducer/introducer_test_api;
|
||||||
|
};
|
||||||
|
clanCore.secrets.syncthing.secrets."syncthing.api".path = "/etc/syncthing.api";
|
||||||
|
services.syncthing.cert = "/etc/syncthing.pam";
|
||||||
|
services.syncthing.key = "/etc/syncthing.key";
|
||||||
|
# Doesn't test zerotier!
|
||||||
|
services.syncthing.openDefaultPorts = true;
|
||||||
|
services.syncthing.settings.folders = {
|
||||||
|
"Shared" = {
|
||||||
|
enable = true;
|
||||||
|
path = "~/Shared";
|
||||||
|
versioning = {
|
||||||
|
type = "trashcan";
|
||||||
|
params = {
|
||||||
|
cleanoutDays = "30";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
clan.syncthing.autoAcceptDevices = true;
|
||||||
|
clan.syncthing.autoShares = [ "Shared" ];
|
||||||
|
# For faster Tests
|
||||||
|
systemd.timers.syncthing-auto-accept.timerConfig = {
|
||||||
|
OnActiveSec = 1;
|
||||||
|
OnUnitActiveSec = 1;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
nodes.peer1 =
|
||||||
|
{ self, ... }:
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
self.clanModules.syncthing
|
||||||
|
self.nixosModules.clanCore
|
||||||
|
{
|
||||||
|
clanCore.machineName = "peer1";
|
||||||
|
clanCore.clanDir = ./.;
|
||||||
|
clan.syncthing.introducer = lib.strings.removeSuffix "\n" (
|
||||||
|
builtins.readFile ./introducer/introducer_device_id
|
||||||
|
);
|
||||||
|
environment.etc = {
|
||||||
|
"syncthing.pam".source = ./peer_1/peer_1_test_cert;
|
||||||
|
"syncthing.key".source = ./peer_1/peer_1_test_key;
|
||||||
|
};
|
||||||
|
services.syncthing.openDefaultPorts = true;
|
||||||
|
services.syncthing.cert = "/etc/syncthing.pam";
|
||||||
|
services.syncthing.key = "/etc/syncthing.key";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
nodes.peer2 =
|
||||||
|
{ self, ... }:
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
self.clanModules.syncthing
|
||||||
|
self.nixosModules.clanCore
|
||||||
|
{
|
||||||
|
clanCore.machineName = "peer2";
|
||||||
|
clanCore.clanDir = ./.;
|
||||||
|
clan.syncthing.introducer = lib.strings.removeSuffix "\n" (
|
||||||
|
builtins.readFile ./introducer/introducer_device_id
|
||||||
|
);
|
||||||
|
environment.etc = {
|
||||||
|
"syncthing.pam".source = ./peer_2/peer_2_test_cert;
|
||||||
|
"syncthing.key".source = ./peer_2/peer_2_test_key;
|
||||||
|
};
|
||||||
|
services.syncthing.openDefaultPorts = true;
|
||||||
|
services.syncthing.cert = "/etc/syncthing.pam";
|
||||||
|
services.syncthing.key = "/etc/syncthing.key";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
testScript = ''
|
||||||
|
start_all()
|
||||||
|
introducer.wait_for_unit("syncthing")
|
||||||
|
peer1.wait_for_unit("syncthing")
|
||||||
|
peer2.wait_for_unit("syncthing")
|
||||||
|
peer1.wait_for_file("/home/user/Shared")
|
||||||
|
peer2.wait_for_file("/home/user/Shared")
|
||||||
|
introducer.shutdown()
|
||||||
|
peer1.execute("echo hello > /home/user/Shared/hello")
|
||||||
|
peer2.wait_for_file("/home/user/Shared/hello")
|
||||||
|
out = peer2.succeed("cat /home/user/Shared/hello")
|
||||||
|
print(out)
|
||||||
|
assert "hello" in out
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
)
|
1
checks/syncthing/introducer/introducer_device_id
Normal file
1
checks/syncthing/introducer/introducer_device_id
Normal file
@ -0,0 +1 @@
|
|||||||
|
RN4ZZIJ-5AOJVWT-JD5IAAZ-SWVDTHU-B4RWCXE-AEM3SRG-QBM2KC5-JTGUNQT
|
1
checks/syncthing/introducer/introducer_test_api
Normal file
1
checks/syncthing/introducer/introducer_test_api
Normal file
@ -0,0 +1 @@
|
|||||||
|
fKwzSQK43LWMnjVK2TDjpTkziY364dvP
|
14
checks/syncthing/introducer/introducer_test_cert
Normal file
14
checks/syncthing/introducer/introducer_test_cert
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIICHDCCAaOgAwIBAgIJAJDWPRNYN7/7MAoGCCqGSM49BAMCMEoxEjAQBgNVBAoT
|
||||||
|
CVN5bmN0aGluZzEgMB4GA1UECxMXQXV0b21hdGljYWxseSBHZW5lcmF0ZWQxEjAQ
|
||||||
|
BgNVBAMTCXN5bmN0aGluZzAeFw0yMzEyMDUwMDAwMDBaFw00MzExMzAwMDAwMDBa
|
||||||
|
MEoxEjAQBgNVBAoTCVN5bmN0aGluZzEgMB4GA1UECxMXQXV0b21hdGljYWxseSBH
|
||||||
|
ZW5lcmF0ZWQxEjAQBgNVBAMTCXN5bmN0aGluZzB2MBAGByqGSM49AgEGBSuBBAAi
|
||||||
|
A2IABEzIpSQGUVVlrSndNjiwkgZ045eH26agwT5RTN44bGRe8SJqBWC7HP3V7u1C
|
||||||
|
6ZQZALSDoDUG5Oi89wGrFnxU48mYFSJFlZAVzyZoqfxVMof3vnk3uFDPo47HA4ex
|
||||||
|
8fi6yaNVMFMwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr
|
||||||
|
BgEFBQcDAjAMBgNVHRMBAf8EAjAAMBQGA1UdEQQNMAuCCXN5bmN0aGluZzAKBggq
|
||||||
|
hkjOPQQDAgNnADBkAjB+d84wmaQuv3c94ctxV0sMh23xeTR1cPNcE8wbPQYxHmbO
|
||||||
|
HbJ3IWo5HF3di63pVgECMBUfzpmFo8dshYR2/76Ovh573Svzk2+NKEMrqRyoNVFr
|
||||||
|
JNQFhCtHbFT1rYfqYWgJBQ==
|
||||||
|
-----END CERTIFICATE-----
|
6
checks/syncthing/introducer/introducer_test_key
Normal file
6
checks/syncthing/introducer/introducer_test_key
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
-----BEGIN EC PRIVATE KEY-----
|
||||||
|
MIGkAgEBBDBvqJxL4s7JFy0y6Ulg7C9C0m3N9VZlW328uMJrwznGuCdRHa/VD4qY
|
||||||
|
IcjtwJisdaqgBwYFK4EEACKhZANiAARMyKUkBlFVZa0p3TY4sJIGdOOXh9umoME+
|
||||||
|
UUzeOGxkXvEiagVguxz91e7tQumUGQC0g6A1BuTovPcBqxZ8VOPJmBUiRZWQFc8m
|
||||||
|
aKn8VTKH9755N7hQz6OOxwOHsfH4usk=
|
||||||
|
-----END EC PRIVATE KEY-----
|
14
checks/syncthing/peer_1/peer_1_test_cert
Normal file
14
checks/syncthing/peer_1/peer_1_test_cert
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIICHTCCAaKgAwIBAgIIT2gZuvqVFP0wCgYIKoZIzj0EAwIwSjESMBAGA1UEChMJ
|
||||||
|
U3luY3RoaW5nMSAwHgYDVQQLExdBdXRvbWF0aWNhbGx5IEdlbmVyYXRlZDESMBAG
|
||||||
|
A1UEAxMJc3luY3RoaW5nMB4XDTIzMTIwNjAwMDAwMFoXDTQzMTIwMTAwMDAwMFow
|
||||||
|
SjESMBAGA1UEChMJU3luY3RoaW5nMSAwHgYDVQQLExdBdXRvbWF0aWNhbGx5IEdl
|
||||||
|
bmVyYXRlZDESMBAGA1UEAxMJc3luY3RoaW5nMHYwEAYHKoZIzj0CAQYFK4EEACID
|
||||||
|
YgAEBAr1CsciwCa0vi7eC6xxuSGijY3txbjtsyFanec/fge4oJBD3rVpaLKFETb3
|
||||||
|
TvHHsuvblzElcP483MEVq6FMUoxwuL9CzTtpJrRhtwSmAs8AHLFu8irVn8sZjgkL
|
||||||
|
sXMho1UwUzAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsG
|
||||||
|
AQUFBwMCMAwGA1UdEwEB/wQCMAAwFAYDVR0RBA0wC4IJc3luY3RoaW5nMAoGCCqG
|
||||||
|
SM49BAMCA2kAMGYCMQDbrtLgfcyMMIkNQn+PJe9DHYAqj8C47LQcWuIY/nekhOu0
|
||||||
|
aUfKctEAwyBtI60Y5zcCMQCEdgD/6CNBh7Qqq3z3CKPhlrpxHtCO5tNw17k0jfdH
|
||||||
|
haCwJInHZvZgclHk4EtFpTw=
|
||||||
|
-----END CERTIFICATE-----
|
6
checks/syncthing/peer_1/peer_1_test_key
Normal file
6
checks/syncthing/peer_1/peer_1_test_key
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
-----BEGIN EC PRIVATE KEY-----
|
||||||
|
MIGkAgEBBDA14Nqo17Xs/xRLGH2KLuyzjKp4eW9iWFobVNM93RZZbECT++W3XcQc
|
||||||
|
cEc5WVtiPmWgBwYFK4EEACKhZANiAAQECvUKxyLAJrS+Lt4LrHG5IaKNje3FuO2z
|
||||||
|
IVqd5z9+B7igkEPetWlosoURNvdO8cey69uXMSVw/jzcwRWroUxSjHC4v0LNO2km
|
||||||
|
tGG3BKYCzwAcsW7yKtWfyxmOCQuxcyE=
|
||||||
|
-----END EC PRIVATE KEY-----
|
14
checks/syncthing/peer_2/peer_2_test_cert
Normal file
14
checks/syncthing/peer_2/peer_2_test_cert
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIICHjCCAaOgAwIBAgIJAKbMWefkf1rVMAoGCCqGSM49BAMCMEoxEjAQBgNVBAoT
|
||||||
|
CVN5bmN0aGluZzEgMB4GA1UECxMXQXV0b21hdGljYWxseSBHZW5lcmF0ZWQxEjAQ
|
||||||
|
BgNVBAMTCXN5bmN0aGluZzAeFw0yMzEyMDYwMDAwMDBaFw00MzEyMDEwMDAwMDBa
|
||||||
|
MEoxEjAQBgNVBAoTCVN5bmN0aGluZzEgMB4GA1UECxMXQXV0b21hdGljYWxseSBH
|
||||||
|
ZW5lcmF0ZWQxEjAQBgNVBAMTCXN5bmN0aGluZzB2MBAGByqGSM49AgEGBSuBBAAi
|
||||||
|
A2IABFZTMt4RfsfBue0va7QuNdjfXMI4HfZzJCEcG+b9MtV7FlDmwMKX5fgGykD9
|
||||||
|
FBbC7yiza3+xCobdMb5bakz1qYJ7nUFCv1mwSDo2eNM+/XE+rJmlre8NwkwGmvzl
|
||||||
|
h1uhyqNVMFMwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr
|
||||||
|
BgEFBQcDAjAMBgNVHRMBAf8EAjAAMBQGA1UdEQQNMAuCCXN5bmN0aGluZzAKBggq
|
||||||
|
hkjOPQQDAgNpADBmAjEAwzhsroN6R4/quWeXj6dO5gt5CfSTLkLee6vrcuIP5i1U
|
||||||
|
rZvJ3OKQVmmGG6IWYe7iAjEAyuq3X2wznaqiw2YK3IDI4qVeYWpCUap0fwRNq7/x
|
||||||
|
4dC4k+BOzHcuJOwNBIY/bEuK
|
||||||
|
-----END CERTIFICATE-----
|
6
checks/syncthing/peer_2/peer_2_test_key
Normal file
6
checks/syncthing/peer_2/peer_2_test_key
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
-----BEGIN EC PRIVATE KEY-----
|
||||||
|
MIGkAgEBBDCXHGpvumKjjDRxB6SsjZOb7duw3w+rdlGQCJTIvRThLjD6zwjnyImi
|
||||||
|
7c3PD5nWtLqgBwYFK4EEACKhZANiAARWUzLeEX7HwbntL2u0LjXY31zCOB32cyQh
|
||||||
|
HBvm/TLVexZQ5sDCl+X4BspA/RQWwu8os2t/sQqG3TG+W2pM9amCe51BQr9ZsEg6
|
||||||
|
NnjTPv1xPqyZpa3vDcJMBpr85Ydboco=
|
||||||
|
-----END EC PRIVATE KEY-----
|
@ -9,5 +9,6 @@
|
|||||||
deltachat = ./deltachat.nix;
|
deltachat = ./deltachat.nix;
|
||||||
xfce = ./xfce.nix;
|
xfce = ./xfce.nix;
|
||||||
borgbackup = ./borgbackup.nix;
|
borgbackup = ./borgbackup.nix;
|
||||||
|
syncthing = ./syncthing.nix;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
206
clanModules/syncthing.nix
Normal file
206
clanModules/syncthing.nix
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
{ config
|
||||||
|
, pkgs
|
||||||
|
, lib
|
||||||
|
, ...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
options.clan.syncthing = {
|
||||||
|
id = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.str;
|
||||||
|
example = "BABNJY4-G2ICDLF-QQEG7DD-N3OBNGF-BCCOFK6-MV3K7QJ-2WUZHXS-7DTW4AS";
|
||||||
|
default = config.clanCore.secrets.syncthing.facts."syncthing.pub".value or null;
|
||||||
|
};
|
||||||
|
introducer = lib.mkOption {
|
||||||
|
description = ''
|
||||||
|
The introducer for the machine.
|
||||||
|
'';
|
||||||
|
type = lib.types.nullOr lib.types.str;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
autoAcceptDevices = lib.mkOption {
|
||||||
|
description = ''
|
||||||
|
Auto accept incoming device requests.
|
||||||
|
Should only be used on the introducer.
|
||||||
|
'';
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
autoShares = lib.mkOption {
|
||||||
|
description = ''
|
||||||
|
Auto share the following Folders by their ID's with introduced devices.
|
||||||
|
Should only be used on the introducer.
|
||||||
|
'';
|
||||||
|
type = lib.types.listOf lib.types.str;
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
{
|
||||||
|
# Syncthing ports: 8384 for remote access to GUI
|
||||||
|
# 22000 TCP and/or UDP for sync traffic
|
||||||
|
# 21027/UDP for discovery
|
||||||
|
# source: https://docs.syncthing.net/users/firewall.html
|
||||||
|
networking.firewall.interfaces."zt+".allowedTCPPorts = [
|
||||||
|
8384
|
||||||
|
22000
|
||||||
|
];
|
||||||
|
# local ui TODO: mkDefault ?
|
||||||
|
networking.firewall.allowedTCPPorts = [ 8384 ];
|
||||||
|
networking.firewall.interfaces."zt+".allowedUDPPorts = [
|
||||||
|
22000
|
||||||
|
21027
|
||||||
|
];
|
||||||
|
|
||||||
|
assertions = [
|
||||||
|
{
|
||||||
|
assertion =
|
||||||
|
lib.all (attr: builtins.hasAttr attr config.services.syncthing.settings.folders)
|
||||||
|
config.clan.syncthing.autoShares;
|
||||||
|
message = ''
|
||||||
|
Syncthing: If you want to AutoShare a folder, you need to have it configured on the sharing device.
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
services.syncthing = {
|
||||||
|
enable = true;
|
||||||
|
configDir = "/var/lib/syncthing";
|
||||||
|
|
||||||
|
overrideFolders = true;
|
||||||
|
overrideDevices = true;
|
||||||
|
|
||||||
|
dataDir = lib.mkDefault "/home/user/";
|
||||||
|
|
||||||
|
key =
|
||||||
|
lib.mkDefault
|
||||||
|
config.clanCore.secrets.syncthing.secrets."syncthing.key".path or null;
|
||||||
|
cert =
|
||||||
|
lib.mkDefault
|
||||||
|
config.clanCore.secrets.syncthing.secrets."syncthing.cert".path or null;
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
options = {
|
||||||
|
urAccepted = -1;
|
||||||
|
# TODO:
|
||||||
|
# allowedNetworks = [];
|
||||||
|
};
|
||||||
|
devices =
|
||||||
|
{ }
|
||||||
|
// (
|
||||||
|
if (config.clan.syncthing.introducer == null) then
|
||||||
|
{ }
|
||||||
|
else
|
||||||
|
{
|
||||||
|
"${config.clan.syncthing.introducer}" = {
|
||||||
|
name = "introducer";
|
||||||
|
id = config.clan.syncthing.introducer;
|
||||||
|
introducer = true;
|
||||||
|
autoAcceptFolders = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
systemd.services.syncthing-auto-accept =
|
||||||
|
let
|
||||||
|
baseAddress = "127.0.0.1:8384";
|
||||||
|
getPendingDevices = "/rest/cluster/pending/devices";
|
||||||
|
postNewDevice = "/rest/config/devices";
|
||||||
|
SharedFolderById = "/rest/config/folders/";
|
||||||
|
apiKey = config.clanCore.secrets.syncthing.secrets."syncthing.api".path or null;
|
||||||
|
in
|
||||||
|
lib.mkIf config.clan.syncthing.autoAcceptDevices {
|
||||||
|
description = "Syncthing auto accept devices";
|
||||||
|
requisite = [ "syncthing.service" ];
|
||||||
|
after = [ "syncthing.service" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
|
||||||
|
script = ''
|
||||||
|
set -x
|
||||||
|
# query pending deviceID's
|
||||||
|
APIKEY=$(cat ${apiKey})
|
||||||
|
PENDING=$(${
|
||||||
|
lib.getExe pkgs.curl
|
||||||
|
} -X GET -H "X-API-Key: $APIKEY" ${baseAddress}${getPendingDevices})
|
||||||
|
PENDING=$(echo $PENDING | ${lib.getExe pkgs.jq} keys[])
|
||||||
|
|
||||||
|
# accept pending deviceID's
|
||||||
|
for ID in $PENDING;do
|
||||||
|
${
|
||||||
|
lib.getExe pkgs.curl
|
||||||
|
} -X POST -d "{\"deviceId\": $ID}" -H "Content-Type: application/json" -H "X-API-Key: $APIKEY" ${baseAddress}${postNewDevice}
|
||||||
|
|
||||||
|
# get all shared folders by their ID
|
||||||
|
for folder in ${builtins.toString config.clan.syncthing.autoShares}; do
|
||||||
|
SHARED_IDS=$(${
|
||||||
|
lib.getExe pkgs.curl
|
||||||
|
} -X GET -H "X-API-Key: $APIKEY" ${baseAddress}${SharedFolderById}"$folder" | ${
|
||||||
|
lib.getExe pkgs.jq
|
||||||
|
} ."devices")
|
||||||
|
PATCHED_IDS=$(echo $SHARED_IDS | ${
|
||||||
|
lib.getExe pkgs.jq
|
||||||
|
} ".+= [{\"deviceID\": $ID, \"introducedBy\": \"\", \"encryptionPassword\": \"\"}]")
|
||||||
|
${
|
||||||
|
lib.getExe pkgs.curl
|
||||||
|
} -X PATCH -d "{\"devices\": $PATCHED_IDS}" -H "X-API-Key: $APIKEY" ${baseAddress}${SharedFolderById}"$folder"
|
||||||
|
done
|
||||||
|
done
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.timers.syncthing-auto-accept =
|
||||||
|
lib.mkIf config.clan.syncthing.autoAcceptDevices
|
||||||
|
{
|
||||||
|
description = "Syncthing Auto Accept";
|
||||||
|
|
||||||
|
wantedBy = [ "syncthing-auto-accept.service" ];
|
||||||
|
|
||||||
|
timerConfig = {
|
||||||
|
OnActiveSec = lib.mkDefault 60;
|
||||||
|
OnUnitActiveSec = lib.mkDefault 60;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.syncthing-init-api-key =
|
||||||
|
let
|
||||||
|
apiKey = config.clanCore.secrets.syncthing.secrets."syncthing.api".path or null;
|
||||||
|
in
|
||||||
|
lib.mkIf config.clan.syncthing.autoAcceptDevices {
|
||||||
|
description = "Set the api key";
|
||||||
|
after = [ "syncthing-init.service" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
script = ''
|
||||||
|
# set -x
|
||||||
|
set -efu pipefail
|
||||||
|
|
||||||
|
APIKEY=$(cat ${apiKey})
|
||||||
|
${
|
||||||
|
lib.getExe pkgs.gnused
|
||||||
|
} -i "s/<apikey>.*<\/apikey>/<apikey>$APIKEY<\/apikey>/" /var/lib/syncthing/config.xml
|
||||||
|
# sudo systemctl restart syncthing.service
|
||||||
|
systemctl restart syncthing.service
|
||||||
|
'';
|
||||||
|
serviceConfig = {
|
||||||
|
WorkingDirectory = "/var/lib/syncthing";
|
||||||
|
BindReadOnlyPaths = [ apiKey ];
|
||||||
|
Type = "oneshot";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
clanCore.secrets.syncthing = {
|
||||||
|
secrets."syncthing.key" = { };
|
||||||
|
secrets."syncthing.cert" = { };
|
||||||
|
secrets."syncthing.api" = { };
|
||||||
|
facts."syncthing.pub" = { };
|
||||||
|
generator.script = ''
|
||||||
|
${pkgs.syncthing}/bin/syncthing generate --config "$secrets"
|
||||||
|
mv "$secrets"/key.pem "$secrets"/syncthing.key
|
||||||
|
mv "$secrets"/cert.pem "$secrets"/syncthing.cert
|
||||||
|
cat "$secrets"/config.xml | ${pkgs.gnugrep}/bin/grep -oP '(?<=<device id=")[^"]+' | uniq > "$facts"/syncthing.pub
|
||||||
|
cat "$secrets"/config.xml | ${pkgs.gnugrep}/bin/grep -oP '<apikey>\K[^<]+' | uniq > "$secrets"/syncthing.api
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user