116 lines
4 KiB
Nix
116 lines
4 KiB
Nix
{
|
|
pkgs,
|
|
lib,
|
|
config,
|
|
...
|
|
}:
|
|
let
|
|
cfg = config.services.syncthing;
|
|
service = "syncthing";
|
|
secretsDir = "/etc/secrets/${service}";
|
|
password = {
|
|
path = "syncthing/${config.frogeye.name}";
|
|
selector = "@";
|
|
generator = ''(t="$(mktemp -d)" && ${lib.getExe pkgs.syncthing} generate --home="$t" &> /dev/null && cat "$t"/{cert,key}.pem && rm -rf "$t")'';
|
|
};
|
|
|
|
capitalizeFirstLetter =
|
|
str:
|
|
(lib.strings.toUpper (builtins.substring 0 1 str))
|
|
+ (builtins.substring 1 (builtins.stringLength str) str);
|
|
|
|
nixosDevices = builtins.map (system: system.config.frogeye) (
|
|
builtins.attrValues config.frogeye.toplevel.nixosConfigurations
|
|
);
|
|
allDevices = nixosDevices;
|
|
syncingDevices = builtins.filter (device: device.syncthing.id != null) allDevices;
|
|
peerDevices = builtins.filter (device: device.name != config.frogeye.name) syncingDevices;
|
|
|
|
# Can't use the module's folders enable option, as it still requests things somehow
|
|
allFolders = builtins.attrValues config.frogeye.folders;
|
|
syncedFolders = builtins.filter (folder: folder.syncthing.enable) allFolders;
|
|
|
|
folderShouldSyncWith =
|
|
folder: device:
|
|
(lib.hasAttrByPath [ folder.name ] device.folders)
|
|
&& device.folders.${folder.name}.syncthing.enable;
|
|
folderDeviceEntry = folder: device: { deviceID = device.syncthing.id; };
|
|
|
|
enable = (builtins.length syncedFolders) > 0;
|
|
in
|
|
{
|
|
config = {
|
|
services.${service} = {
|
|
inherit enable;
|
|
openDefaultPorts = true;
|
|
configDir = "/var/lib/${service}";
|
|
databaseDir = "/var/cache/${service}";
|
|
dataDir = cfg.databaseDir; # Don't really care
|
|
|
|
key = "${secretsDir}/key.pem";
|
|
cert = "${secretsDir}/cert.pem";
|
|
|
|
settings = {
|
|
devices = builtins.listToAttrs (
|
|
builtins.map (device: {
|
|
inherit (device) name;
|
|
value = device.syncthing;
|
|
}) syncingDevices
|
|
);
|
|
folders = builtins.listToAttrs (
|
|
builtins.map (folder: {
|
|
inherit (folder) name;
|
|
value = {
|
|
label = "${capitalizeFirstLetter folder.user} ${folder.label}";
|
|
path = "${config.users.users.${folder.user}.home}/${folder.path}";
|
|
# Despite further in the code indicating this is possible, it is, actually not
|
|
# devices = builtins.map (folderDeviceEntry folder) (builtins.filter (folderShouldSyncWith folder) peerDevices);
|
|
devices = builtins.map (device: device.name) (
|
|
builtins.filter (folderShouldSyncWith folder) peerDevices
|
|
);
|
|
versioning =
|
|
if (config.frogeye.storageSize == "big" && folder.versionsMaxDays != null) then
|
|
{
|
|
type = "staggered";
|
|
params.maxAge = builtins.toString (folder.versionsMaxDays * 24 * 3600);
|
|
# TODO Increase cleanupIntervalS to 1 day or so
|
|
}
|
|
else
|
|
null;
|
|
rescanIntervalS = 10 * 3600; # Using watcher, should be good enough
|
|
copyRangeMethod = "all"; # Prevents duplication
|
|
copyOwnershipFromParent = true;
|
|
} // folder.syncthing;
|
|
}) syncedFolders
|
|
);
|
|
options = rec {
|
|
urAccepted = 3;
|
|
urSeen = urAccepted;
|
|
};
|
|
};
|
|
};
|
|
systemd.services.${service}.serviceConfig = {
|
|
ExecStartPre = [
|
|
"+${pkgs.writeShellScript "syncthing-create-folders" ''
|
|
install -Dm700 -o ${cfg.user} -g ${cfg.group} -d ${cfg.configDir}
|
|
install -Dm700 -o ${cfg.user} -g ${cfg.group} -d ${cfg.databaseDir}
|
|
''}"
|
|
];
|
|
PrivateUsers = lib.mkForce false;
|
|
AmbientCapabilities = [
|
|
"CAP_CHOWN"
|
|
"CAP_DAC_OVERRIDE"
|
|
"CAP_FOWNER"
|
|
];
|
|
};
|
|
vivarium.passwordFiles = {
|
|
${cfg.key}.password = password // {
|
|
transform = "${lib.getExe pkgs.openssl} pkey";
|
|
};
|
|
${cfg.cert}.password = password // {
|
|
transform = "${lib.getExe pkgs.openssl} x509";
|
|
};
|
|
};
|
|
};
|
|
}
|