diff --git a/nixos/tests/syncthing/folders.nix b/nixos/tests/syncthing/folders.nix index 1a182da4c845..06ee16e1c3a6 100644 --- a/nixos/tests/syncthing/folders.nix +++ b/nixos/tests/syncthing/folders.nix @@ -1,148 +1,197 @@ { lib, pkgs, ... }: let - genNodeId = - name: - pkgs.runCommand "syncthing-test-certs-${name}" { } '' - mkdir -p $out - ${pkgs.syncthing}/bin/syncthing generate --home=$out - ${pkgs.libxml2}/bin/xmllint --xpath 'string(configuration/device/@id)' $out/config.xml > $out/id - ''; - idA = genNodeId "a"; - idB = genNodeId "b"; - idC = genNodeId "c"; - testPassword = "it's a secret"; -in -{ - name = "syncthing"; - meta.maintainers = with pkgs.lib.maintainers; [ zarelit ]; + nodeNames = [ + "a" + "b" + "c" + ]; + nodeDirs = lib.genAttrs nodeNames (n: ./test-nodes + "/${n}"); + nodeData = lib.mapAttrs (n: v: { + cert = "${v}/cert.pem"; + key = "${v}/key.pem"; + id = lib.fileContents (v + "/id"); + }) nodeDirs; - nodes = { - a = - { config, ... }: - { - environment.etc.bar-encryption-password.text = testPassword; - services.syncthing = { - enable = true; - openDefaultPorts = true; - cert = "${idA}/cert.pem"; - key = "${idA}/key.pem"; - guiAddress = "unix:///run/syncthing/syncthing.sock"; - settings = { - devices.b.id = lib.fileContents "${idB}/id"; - devices.c.id = lib.fileContents "${idC}/id"; - folders.foo = { - path = "/var/lib/syncthing/foo"; - devices = [ "b" ]; - }; - folders.bar = { - path = "/var/lib/syncthing/bar"; - devices = [ - { - name = "c"; - encryptionPasswordFile = "/etc/${config.environment.etc.bar-encryption-password.target}"; - } - ]; - }; - folders.baz = { - path = "/var/lib/syncthing/baz"; - devices = [ - "b" - "c" - ]; - ignorePatterns = [ ]; - }; - folders."foo bar" = { - path = "/var/lib/syncthing/foo-bar"; - devices = [ - "b" - ]; - }; - }; - }; - }; - b = - { config, ... }: - { - environment.etc.bar-encryption-password.text = testPassword; - services.syncthing = { - enable = true; - openDefaultPorts = true; - cert = "${idB}/cert.pem"; - key = "${idB}/key.pem"; - settings = { - devices.a.id = lib.fileContents "${idA}/id"; - devices.c.id = lib.fileContents "${idC}/id"; - folders.foo = { - path = "/var/lib/syncthing/foo"; - devices = [ "a" ]; - }; - folders.bar = { - path = "/var/lib/syncthing/bar"; - devices = [ - { - name = "c"; - encryptionPasswordFile = "/etc/${config.environment.etc.bar-encryption-password.target}"; - } - ]; - }; - folders.baz = { - path = "/var/lib/syncthing/baz"; - devices = [ - "a" - "c" - ]; - ignorePatterns = [ - "notB" - ]; - }; - # Test how we handle white spaces in folder IDs - folders."foo bar" = { - path = "/var/lib/syncthing/foo-bar"; - devices = [ - "a" - ]; - ignorePatterns = [ - "notB" - # Just test that an apostrophe doesn't break the curl config - # commands. See: https://github.com/NixOS/nixpkgs/issues/554744 - "apostrophe'" - ]; - }; - }; - }; - }; - c = { - services.syncthing = { - enable = true; - openDefaultPorts = true; - cert = "${idC}/cert.pem"; - key = "${idC}/key.pem"; - settings = { - devices.a.id = lib.fileContents "${idA}/id"; - devices.b.id = lib.fileContents "${idB}/id"; - folders.bar = { - path = "/var/lib/syncthing/bar"; - devices = [ - "a" - "b" - ]; - type = "receiveencrypted"; - }; - folders.baz = { - path = "/var/lib/syncthing/baz"; - devices = [ - "a" - "b" - ]; - ignorePatterns = [ - "notC" - ]; - }; - }; - }; + testPassword = "it's a secret"; + + commonNodeConfigModule = { + services.syncthing = { + enable = true; + openDefaultPorts = true; + settings.devices = lib.mapAttrs (n: v: { inherit (v) id; }) nodeData; }; }; + nodeConfigModules = { + a = { + services.syncthing = { + inherit (nodeData.a) cert key; + guiAddress = "unix:///run/syncthing/syncthing.sock"; + }; + }; + b = { + services.syncthing = { inherit (nodeData.b) cert key; }; + }; + c = { + services.syncthing = { inherit (nodeData.c) cert key; }; + }; + }; + + nodeFolderConfigModules = [ + # "foo" is a folder that is synchronised only between nodes a and b. + rec { + a = { + services.syncthing.settings.folders.foo = { + path = "/var/lib/syncthing/foo"; + devices = [ + "a" + "b" + ]; + }; + }; + + b = a; + + c = { }; + } + + # "bar" is synchronised between a and c, and between b and c, but c only + # gets an encrypted copy, and a and b never synchronise directly to each + # other. + rec { + a = + { config, ... }: + { + environment.etc.bar-encryption-password.text = testPassword; + + services.syncthing.settings.folders.bar = { + path = "/var/lib/syncthing/bar"; + devices = [ + { + name = "c"; + encryptionPasswordFile = "/etc/${config.environment.etc.bar-encryption-password.target}"; + } + ]; + }; + }; + + b = a; + + c = { + services.syncthing.settings.folders.bar = { + path = "/var/lib/syncthing/bar"; + devices = [ + "a" + "b" + ]; + type = "receiveencrypted"; + }; + }; + } + + # "baz" is synchronised between all three nodes, but has filters on b and c + # that mean they shouldn't receive certain files. + { + a = { + services.syncthing.settings.folders.baz = { + path = "/var/lib/syncthing/baz"; + devices = [ + "b" + "c" + ]; + ignorePatterns = [ ]; + }; + }; + + b = { + services.syncthing.settings.folders.baz = { + path = "/var/lib/syncthing/baz"; + devices = [ + "a" + "c" + ]; + ignorePatterns = [ + "notB" + # Just test that an apostrophe doesn't break the curl config + # commands. See: https://github.com/NixOS/nixpkgs/issues/554744 + "apostrophe'" + ]; + }; + }; + + c = { + services.syncthing.settings.folders.baz = { + path = "/var/lib/syncthing/baz"; + devices = [ + "a" + "b" + ]; + ignorePatterns = [ "notC" ]; + }; + }; + } + + # "foo bar" tests handling whitespace in folder IDs. + { + a = { + services.syncthing.settings.folders."foo bar" = { + path = "/var/lib/syncthing/foo-bar"; + devices = [ "b" ]; + }; + }; + + b = { + services.syncthing.settings.folders."foo bar" = { + path = "/var/lib/syncthing/foo-bar"; + devices = [ "a" ]; + ignorePatterns = [ "notB" ]; + }; + }; + + c = { }; + } + ]; +in +{ + name = "syncthing-folders"; + meta.maintainers = with pkgs.lib.maintainers; [ zarelit ]; + + # Run from the root of the nixpkgs repository with + # + # nix-build -A nixosTests.syncthing-folders.genNodeData && + # ./result/bin/genNodeData.sh + # + # This generates new keys, certificates, and overall Syncthing config, and + # updates the certificate and key files and the ID file extracted from the + # overall Syncthing config file. + passthru.genNodeData = pkgs.writeShellApplication { + name = "genNodeData.sh"; + runtimeInputs = with pkgs; [ + syncthing + libxml2 + ]; + text = '' + rm -r nixos/tests/syncthing/test-nodes + mkdir nixos/tests/syncthing/test-nodes + cd nixos/tests/syncthing/test-nodes + + for d in ${lib.escapeShellArgs nodeNames}; do + mkdir -- "$d" + syncthing generate --home="$d" + xmllint --xpath 'string(configuration/device/@id)' "$d"/config.xml >"$d"/id + rm -f -- "$d"/.syncthing.tmp.* "$d"/config.xml + done + ''; + }; + + nodes = lib.genAttrs nodeNames (n: { + imports = [ + commonNodeConfigModule + nodeConfigModules."${n}" + ] + ++ map (builtins.getAttr n) nodeFolderConfigModules; + }); + testScript = '' start_all() diff --git a/nixos/tests/syncthing/no-settings.nix b/nixos/tests/syncthing/no-settings.nix index ee79d389e92a..c389d95ac7fa 100644 --- a/nixos/tests/syncthing/no-settings.nix +++ b/nixos/tests/syncthing/no-settings.nix @@ -1,6 +1,6 @@ { lib, pkgs, ... }: { - name = "syncthing"; + name = "syncthing-no-settings"; meta.maintainers = with pkgs.lib.maintainers; [ chkno ]; nodes = { diff --git a/nixos/tests/syncthing/test-nodes/a/cert.pem b/nixos/tests/syncthing/test-nodes/a/cert.pem new file mode 100644 index 000000000000..e4a948a25727 --- /dev/null +++ b/nixos/tests/syncthing/test-nodes/a/cert.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBoDCCAVKgAwIBAgIJAJ7l/z0JF6aOMAUGAytlcDBKMRIwEAYDVQQKEwlTeW5j +dGhpbmcxIDAeBgNVBAsTF0F1dG9tYXRpY2FsbHkgR2VuZXJhdGVkMRIwEAYDVQQD +EwlzeW5jdGhpbmcwHhcNMjYwNDAyMDAwMDAwWhcNNDYwMzI4MDAwMDAwWjBKMRIw +EAYDVQQKEwlTeW5jdGhpbmcxIDAeBgNVBAsTF0F1dG9tYXRpY2FsbHkgR2VuZXJh +dGVkMRIwEAYDVQQDEwlzeW5jdGhpbmcwKjAFBgMrZXADIQBCsJ1O6QrxxFP/YKKj +WAjdZp07AiTIIC0/p/mHGbmyraNVMFMwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQW +MBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMBQGA1UdEQQNMAuC +CXN5bmN0aGluZzAFBgMrZXADQQBqGFXpwvEoAc7N6mT9evXI3++STiTE6Lu3Z2z3 +ecp5vU3fS5U+b0fO4BEUrNoaDdXurfOal6+LoydAnJcFamwN +-----END CERTIFICATE----- diff --git a/nixos/tests/syncthing/test-nodes/a/id b/nixos/tests/syncthing/test-nodes/a/id new file mode 100644 index 000000000000..97a37907b52c --- /dev/null +++ b/nixos/tests/syncthing/test-nodes/a/id @@ -0,0 +1 @@ +F2ACIUG-FML5RHY-ATV55ZN-5KGVUIV-RWFG3Y6-QPLTKZB-NWUZAGD-7QRCWAP diff --git a/nixos/tests/syncthing/test-nodes/a/key.pem b/nixos/tests/syncthing/test-nodes/a/key.pem new file mode 100644 index 000000000000..bb6111462cfc --- /dev/null +++ b/nixos/tests/syncthing/test-nodes/a/key.pem @@ -0,0 +1,3 @@ +-----BEGIN PRIVATE KEY----- +MC4CAQAwBQYDK2VwBCIEIE2ls259KcQgtizG7hwP3aBhlYBNuPJwSBG8d4uVBFOh +-----END PRIVATE KEY----- diff --git a/nixos/tests/syncthing/test-nodes/b/cert.pem b/nixos/tests/syncthing/test-nodes/b/cert.pem new file mode 100644 index 000000000000..a3fbcd34dc46 --- /dev/null +++ b/nixos/tests/syncthing/test-nodes/b/cert.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBnzCCAVGgAwIBAgIIKyLKAcqLWn4wBQYDK2VwMEoxEjAQBgNVBAoTCVN5bmN0 +aGluZzEgMB4GA1UECxMXQXV0b21hdGljYWxseSBHZW5lcmF0ZWQxEjAQBgNVBAMT +CXN5bmN0aGluZzAeFw0yNjA0MDIwMDAwMDBaFw00NjAzMjgwMDAwMDBaMEoxEjAQ +BgNVBAoTCVN5bmN0aGluZzEgMB4GA1UECxMXQXV0b21hdGljYWxseSBHZW5lcmF0 +ZWQxEjAQBgNVBAMTCXN5bmN0aGluZzAqMAUGAytlcAMhABoahydRmwpbCII6mz9i +E8FeGH7YdHqgMeAmLiFZu2wMo1UwUzAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYw +FAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwFAYDVR0RBA0wC4IJ +c3luY3RoaW5nMAUGAytlcANBADFVKB2vF16j0gc/h71x3vUi042FbmXTPk9kMb2O +9O0NnWSoMuOGPFDEoHWBFuUuixQ/3cw45zw+fea28m95gQo= +-----END CERTIFICATE----- diff --git a/nixos/tests/syncthing/test-nodes/b/id b/nixos/tests/syncthing/test-nodes/b/id new file mode 100644 index 000000000000..a96022726527 --- /dev/null +++ b/nixos/tests/syncthing/test-nodes/b/id @@ -0,0 +1 @@ +LOB4D2H-OYG64QZ-NDX43LJ-NYR4HQU-BRNXCNI-ERACWFP-OVURLBI-63MR5QP diff --git a/nixos/tests/syncthing/test-nodes/b/key.pem b/nixos/tests/syncthing/test-nodes/b/key.pem new file mode 100644 index 000000000000..4253bf0f9255 --- /dev/null +++ b/nixos/tests/syncthing/test-nodes/b/key.pem @@ -0,0 +1,3 @@ +-----BEGIN PRIVATE KEY----- +MC4CAQAwBQYDK2VwBCIEIJtOML1Tshk03rB41IX5ajEeem50CdWzHDimotheTyZi +-----END PRIVATE KEY----- diff --git a/nixos/tests/syncthing/test-nodes/c/cert.pem b/nixos/tests/syncthing/test-nodes/c/cert.pem new file mode 100644 index 000000000000..1561c4ac3465 --- /dev/null +++ b/nixos/tests/syncthing/test-nodes/c/cert.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBoDCCAVKgAwIBAgIJAIZk5+sv3EbTMAUGAytlcDBKMRIwEAYDVQQKEwlTeW5j +dGhpbmcxIDAeBgNVBAsTF0F1dG9tYXRpY2FsbHkgR2VuZXJhdGVkMRIwEAYDVQQD +EwlzeW5jdGhpbmcwHhcNMjYwNDAyMDAwMDAwWhcNNDYwMzI4MDAwMDAwWjBKMRIw +EAYDVQQKEwlTeW5jdGhpbmcxIDAeBgNVBAsTF0F1dG9tYXRpY2FsbHkgR2VuZXJh +dGVkMRIwEAYDVQQDEwlzeW5jdGhpbmcwKjAFBgMrZXADIQB0QK+PM7oLutgCKoIo +UOh8/XiSmGJWbkN175hALTIaYKNVMFMwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQW +MBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMBQGA1UdEQQNMAuC +CXN5bmN0aGluZzAFBgMrZXADQQAbedm895vhgYizMXc38IwhquYv2S4ORHZac0Bw +ZYKJKze7EhKzqvdxcU5uVIUaMPSGi86wtmmsiijfhY8rnD0E +-----END CERTIFICATE----- diff --git a/nixos/tests/syncthing/test-nodes/c/id b/nixos/tests/syncthing/test-nodes/c/id new file mode 100644 index 000000000000..492e50839af2 --- /dev/null +++ b/nixos/tests/syncthing/test-nodes/c/id @@ -0,0 +1 @@ +MPGAF2L-AUIF5DE-UCI3AMX-PTGF3ZI-XDS6UJI-YUU4ZWT-UUWY7X6-N2DAAQG diff --git a/nixos/tests/syncthing/test-nodes/c/key.pem b/nixos/tests/syncthing/test-nodes/c/key.pem new file mode 100644 index 000000000000..2577c5f60064 --- /dev/null +++ b/nixos/tests/syncthing/test-nodes/c/key.pem @@ -0,0 +1,3 @@ +-----BEGIN PRIVATE KEY----- +MC4CAQAwBQYDK2VwBCIEIMSmcIlXQTKkaMaOLh+zsgU1ULCvCz949E56OzQ1dsMK +-----END PRIVATE KEY-----