{ config, lib, pkgs, ... }: with lib; let cfg = config.services.syncthing; defaultSyncthingArgs = [ "${pkgs.syncthing}/bin/syncthing" "-no-browser" "-no-restart" "-logflags=0" ]; syncthingArgs = defaultSyncthingArgs ++ cfg.extraOptions; in { meta.maintainers = [ maintainers.rycee ]; options = { services.syncthing = { enable = mkEnableOption "Syncthing continuous file synchronization"; extraOptions = mkOption { type = types.listOf types.str; default = [ ]; example = [ "--gui-apikey=apiKey" ]; description = '' Extra command-line arguments to pass to syncthing. ''; }; tray = mkOption { type = with types; either bool (submodule { options = { enable = mkOption { type = types.bool; default = false; description = "Whether to enable a syncthing tray service."; }; command = mkOption { type = types.str; default = "syncthingtray"; defaultText = literalExpression "syncthingtray"; example = literalExpression "qsyncthingtray"; description = "Syncthing tray command to use."; }; package = mkOption { type = types.package; default = pkgs.syncthingtray-minimal; defaultText = literalExpression "pkgs.syncthingtray-minimal"; example = literalExpression "pkgs.qsyncthingtray"; description = "Syncthing tray package to use."; }; }; }); default = { enable = false; }; description = "Syncthing tray service configuration."; }; }; }; config = mkMerge [ (mkIf cfg.enable { home.packages = [ (getOutput "man" pkgs.syncthing) ]; systemd.user.services = { syncthing = { Unit = { Description = "Syncthing - Open Source Continuous File Synchronization"; Documentation = "man:syncthing(1)"; After = [ "network.target" ]; }; Service = { ExecStart = escapeShellArgs syncthingArgs; Restart = "on-failure"; SuccessExitStatus = [ 3 4 ]; RestartForceExitStatus = [ 3 4 ]; # Sandboxing. LockPersonality = true; MemoryDenyWriteExecute = true; NoNewPrivileges = true; PrivateUsers = true; RestrictNamespaces = true; SystemCallArchitectures = "native"; SystemCallFilter = "@system-service"; }; Install = { WantedBy = [ "default.target" ]; }; }; }; launchd.agents.syncthing = { enable = true; config = { ProgramArguments = syncthingArgs; KeepAlive = { Crashed = true; SuccessfulExit = false; }; ProcessType = "Background"; }; }; }) (mkIf (isAttrs cfg.tray && cfg.tray.enable) { assertions = [ (hm.assertions.assertPlatform "services.syncthing.tray" pkgs platforms.linux) ]; systemd.user.services = { ${cfg.tray.package.pname} = { Unit = { Description = cfg.tray.package.pname; Requires = [ "tray.target" ]; After = [ "graphical-session-pre.target" "tray.target" ]; PartOf = [ "graphical-session.target" ]; }; Service = { ExecStart = "${cfg.tray.package}/bin/${cfg.tray.command}"; }; Install = { WantedBy = [ "graphical-session.target" ]; }; }; }; }) # deprecated (mkIf (isBool cfg.tray && cfg.tray) { assertions = [ (hm.assertions.assertPlatform "services.syncthing.tray" pkgs platforms.linux) ]; systemd.user.services = { "syncthingtray" = { Unit = { Description = "syncthingtray"; Requires = [ "tray.target" ]; After = [ "graphical-session-pre.target" "tray.target" ]; PartOf = [ "graphical-session.target" ]; }; Service = { ExecStart = "${pkgs.syncthingtray-minimal}/bin/syncthingtray"; }; Install = { WantedBy = [ "graphical-session.target" ]; }; }; }; warnings = [ "Specifying 'services.syncthing.tray' as a boolean is deprecated, set 'services.syncthing.tray.enable' instead. See https://github.com/nix-community/home-manager/pull/1257." ]; }) ]; }