nixos/syncthing: add option for ignore patterns

Syncthing can be configured to ignore certain files and
directories via ignore patterns. This PR adds a new nix option to
set these patterns declaratively.
This commit is contained in:
zorrobert
2025-10-05 12:34:21 +02:00
parent 957048c9dc
commit 7a223b2685
2 changed files with 82 additions and 1 deletions

View File

@@ -117,6 +117,7 @@ let
override = cfg.overrideFolders;
conf = folders;
baseAddress = curlAddressArgs "/rest/config/folders";
ignoreAddress = curlAddressArgs "/rest/db/ignores";
};
}
[
@@ -142,7 +143,8 @@ let
let
jsonPreSecretsFile = pkgs.writeTextFile {
name = "${conf_type}-${new_cfg.id}-conf-pre-secrets.json";
text = builtins.toJSON new_cfg;
# Remove the ignorePatterns attribute, it is handled separately
text = builtins.toJSON (builtins.removeAttrs new_cfg [ "ignorePatterns" ]);
};
injectSecretsJqCmd =
{
@@ -209,6 +211,13 @@ let
''
${injectSecretsJqCmd} ${jsonPreSecretsFile} | curl --json @- -X POST ${s.baseAddress}
''
/*
Check if we are configuring a folder which has ignore patterns.
If it does, write the ignore patterns to the rest API.
*/
+ lib.optionalString ((conf_type == "dirs") && (new_cfg.ignorePatterns != null)) ''
curl -d '{"ignore": ${builtins.toJSON new_cfg.ignorePatterns}}' -X POST ${s.ignoreAddress}?folder=${new_cfg.id}
''
))
(lib.concatStringsSep "\n")
]
@@ -649,6 +658,26 @@ in
Requires running Syncthing as a privileged user, or granting it additional capabilities (e.g. CAP_CHOWN on Linux).
'';
};
ignorePatterns = mkOption {
type = types.nullOr (types.listOf types.str);
default = null;
description = ''
Syncthing can be configured to ignore certain files in a folder using ignore patterns.
Enter them as a list of strings, one string per line.
See the Syncthing documentation for syntax: <https://docs.syncthing.net/users/ignoring.html>
Patterns set using the WebUI will be overridden if you define this option.
If you want to override the ignore patterns to be empty, use `ignorePatterns = []`.
Deleting the `ignorePatterns` option will not remove the patterns from Syncthing automatically
because patterns are only handled by the module if this option is defined. Either use
`ignorePatterns = []` before deleting the option or remove the patterns afterwards using the WebUI.
'';
example = [
"// This is a comment"
"*.part // Firefox downloads and other things"
"*.crdownload // Chrom(ium|e) downloads"
];
};
};
}
)

View File

@@ -42,6 +42,14 @@ in
}
];
};
folders.baz = {
path = "/var/lib/syncthing/baz";
devices = [
"b"
"c"
];
ignorePatterns = [ ];
};
};
};
};
@@ -70,6 +78,16 @@ in
}
];
};
folders.baz = {
path = "/var/lib/syncthing/baz";
devices = [
"a"
"c"
];
ignorePatterns = [
"notB"
];
};
};
};
};
@@ -90,6 +108,16 @@ in
];
type = "receiveencrypted";
};
folders.baz = {
path = "/var/lib/syncthing/baz";
devices = [
"a"
"b"
];
ignorePatterns = [
"notC"
];
};
};
};
};
@@ -131,5 +159,29 @@ in
# Bar on C is untrusted, check that content is not in cleartext
c.fail("grep -R plaincontent /var/lib/syncthing/bar")
# Test baz
a.wait_for_file("/var/lib/syncthing/baz")
b.wait_for_file("/var/lib/syncthing/baz")
c.wait_for_file("/var/lib/syncthing/baz")
# A creates the file notB, C should get it, B should ignore it
a.succeed("echo notB > /var/lib/syncthing/baz/notB")
a.succeed("echo controlA > /var/lib/syncthing/baz/controlA")
c.wait_for_file("/var/lib/syncthing/baz/notB")
c.wait_for_file("/var/lib/syncthing/baz/controlA")
b.wait_for_file("/var/lib/syncthing/baz/controlA")
# B creates the file notC, A should get it, C should ignore it
b.succeed("echo notC > /var/lib/syncthing/baz/notC")
b.succeed("echo controlB > /var/lib/syncthing/baz/controlB")
a.wait_for_file("/var/lib/syncthing/baz/notC")
a.wait_for_file("/var/lib/syncthing/baz/controlB")
c.wait_for_file("/var/lib/syncthing/baz/controlB")
# Check that files have been correctly ignored
b.fail("cat /var/lib/syncthing/baz/notB")
c.fail("cat /var/lib/syncthing/baz/notC")
'';
}