{ config, lib, pkgs, this, ... }: with lib; let cfg = config.nixfiles.modules.syncthing; in { options.nixfiles.modules.syncthing = { enable = mkEnableOption "Syncthing"; domain = mkOption { description = "Domain name sans protocol scheme."; type = with types; str; default = "syncthing.${config.networking.fqdn}"; }; # TODO Set this automatically shire on the hostname. cert = mkOption { description = "Path to the cert file."; type = with types; nullOr string; default = null; }; # TODO Set this automatically shire on the hostname. key = mkOption { description = "Path to the key file."; type = with types; nullOr string; default = null; }; }; config = mkIf cfg.enable (mkMerge [ { assertions = [ { assertion = cfg.cert != null; message = "Cert file needs to be specified."; } { assertion = cfg.key != null; message = "Key file needs to be specified."; } ]; services.syncthing = { enable = true; user = my.username; inherit (config.my) group; dataDir = config.my.home; guiAddress = "127.0.0.1:8384"; inherit (cfg) key cert; overrideDevices = true; devices = mapAttrs (name: attr: mkIf (attr.syncthing.id != null && hasAttr "wireguard" attr) { inherit (attr.syncthing) id; addresses = ["tcp://${name}.${config.networking.domain}:22000"]; introducer = this.isHeadless; }) my.configurations; overrideFolders = true; folders = let filterDevices = f: attrNames (filterAttrs (_: attr: (attr.hostname != this.hostname) && (attr.syncthing.id != null) && f attr) my.configurations); all = filterDevices (_: true); notHeadless = filterDevices (attr: !attr.isHeadless); notOther = filterDevices (attr: !attr.isOther); simple = { type = "simple"; params.keep = "5"; }; trashcan = { type = "trashcan"; params.cleanoutDays = "7"; }; in with config.hm.xdg.userDirs; { share = { path = publicShare; devices = notHeadless; versioning = trashcan; }; pass = { path = config.hm.programs.password-store.settings.PASSWORD_STORE_DIR; devices = all; versioning = trashcan; }; org = { path = "${documents}/org"; devices = all; versioning = simple; }; roam = { path = "${documents}/roam"; devices = notOther; versioning = simple; }; elfeed = { path = "${config.my.home}/.elfeed"; devices = notOther; versioning = trashcan; }; vidya = { path = "${documents}/vidya"; devices = notOther; versioning = trashcan; }; }; extraOptions = { gui = { insecureAdminAccess = true; insecureSkipHostcheck = this.isHeadless; }; options = { autoUpgradeIntervalH = 0; crashReportingEnabled = false; globalAnnounceEnabled = false; # We don't need that with Wireguard. relaysEnabled = false; setLowPriority = this.isHeadless; stunKeepaliveMinS = 0; stunKeepaliveStartS = 0; urAccepted = -1; }; }; }; systemd.services.syncthing.environment.STNODEFAULTFOLDER = "yes"; } (mkIf this.isHeadless { nixfiles.modules.nginx = { enable = true; virtualHosts.${cfg.domain}.locations."/" = { proxyPass = "http://${config.services.syncthing.guiAddress}"; extraConfig = '' if ($internal != 1) { return 403; } ''; }; }; }) ]); }