{ config, inputs, lib, namespace, ... }: let inherit (lib) types mkEnableOption mkIf mapAttrs mapAttrs' listToAttrs map; inherit (lib.${namespace}) getAttrByNamespace mkOptionsWithNamespace resolveHostIP mkOpt mkOptAttrset mkListOpt mkPersistDir; inherit (config.networking) hostName; base = "${namespace}.services.storage.syncthing"; cfg = getAttrByNamespace config base; networkCfg = getAttrByNamespace config "${namespace}.services.networking"; in { options = with types; mkOptionsWithNamespace base { enable = mkEnableOption "Syncthing"; devices = mkOptAttrset str {} "A map of host names to their respective device IDs for Syncthing."; shares = mkOptAttrset (listOf str) {} "A map of folder names to the list of hostnames with which the folder is shared."; }; config = mkIf cfg.enable { services.syncthing = let inherit (config.sops) secrets; in { enable = true; dataDir = "/mnt/syncthing/"; user = "c4patino"; group = "syncthing"; cert = secrets."ssl/syncthing/cert".path; key = secrets."ssl/syncthing/key".path; settings = { devices = let mkDeviceConfig = host: id: { inherit id; addresses = ["tcp://${resolveHostIP networkCfg.devices host}:22000"]; autoAcceptFolders = true; }; in cfg.devices |> mapAttrs mkDeviceConfig; folders = let mkShare = folderName: sharedMachines: { name = folderName; value = { path = "/mnt/syncthing/${folderName}"; enable = builtins.elem hostName sharedMachines; devices = sharedMachines; }; }; in cfg.shares |> mapAttrs' mkShare; }; }; sops.secrets = let inherit (config.networking) hostName; sopsFolder = "${inputs.self}/secrets/sops"; in [ "ssl/syncthing/cert" "ssl/syncthing/key" ] |> map (name: { inherit name; value = { sopsFile = "${sopsFolder}/${hostName}.yaml"; }; }) |> listToAttrs; systemd.services.syncthing.environment.STNODEFAULTFOLDER = "true"; ${namespace}.services.storage.impermanence.folders = mkIf cfg.enable ( [ (mkPersistDir config "c4patino" "/mnt/syncthing") ] ++ (builtins.attrNames cfg.shares |> map (k: mkPersistDir config "c4patino" "/mnt/syncthing/${k}")) ); }; }