1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6 cfg = config.services.syncthing;
7 defaultUser = "syncthing";
8in {
9 ###### interface
10 options = {
11 services.syncthing = {
12
13 enable = mkEnableOption ''
14 Syncthing - the self-hosted open-source alternative
15 to Dropbox and Bittorrent Sync. Initial interface will be
16 available on http://127.0.0.1:8384/.
17 '';
18
19 systemService = mkOption {
20 type = types.bool;
21 default = true;
22 description = "Auto launch Syncthing as a system service.";
23 };
24
25 user = mkOption {
26 type = types.string;
27 default = defaultUser;
28 description = ''
29 Syncthing will be run under this user (user will be created if it doesn't exist.
30 This can be your user name).
31 '';
32 };
33
34 group = mkOption {
35 type = types.string;
36 default = "nogroup";
37 description = ''
38 Syncthing will be run under this group (group will not be created if it doesn't exist.
39 This can be your user name).
40 '';
41 };
42
43 all_proxy = mkOption {
44 type = types.nullOr types.string;
45 default = null;
46 example = "socks5://address.com:1234";
47 description = ''
48 Overwrites all_proxy environment variable for the syncthing process to
49 the given value. This is normaly used to let relay client connect
50 through SOCKS5 proxy server.
51 '';
52 };
53
54 dataDir = mkOption {
55 type = types.path;
56 default = "/var/lib/syncthing";
57 description = ''
58 Path where the settings and keys will exist.
59 '';
60 };
61
62 openDefaultPorts = mkOption {
63 type = types.bool;
64 default = false;
65 example = literalExample "true";
66 description = ''
67 Open the default ports in the firewall:
68 - TCP 22000 for transfers
69 - UDP 21027 for discovery
70 If multiple users are running syncthing on this machine, you will need to manually open a set of ports for each instance and leave this disabled.
71 Alternatively, if are running only a single instance on this machine using the default ports, enable this.
72 '';
73 };
74
75 package = mkOption {
76 type = types.package;
77 default = pkgs.syncthing;
78 defaultText = "pkgs.syncthing";
79 example = literalExample "pkgs.syncthing";
80 description = ''
81 Syncthing package to use.
82 '';
83 };
84 };
85 };
86
87 imports = [
88 (mkRemovedOptionModule ["services" "syncthing" "useInotify"] ''
89 This option was removed because syncthing now has the inotify functionality included under the name "fswatcher".
90 It can be enabled on a per-folder basis through the webinterface.
91 '')
92 ];
93
94 ###### implementation
95
96 config = mkIf cfg.enable {
97
98 networking.firewall = mkIf cfg.openDefaultPorts {
99 allowedTCPPorts = [ 22000 ];
100 allowedUDPPorts = [ 21027 ];
101 };
102
103 systemd.packages = [ pkgs.syncthing ];
104
105 users = mkIf (cfg.user == defaultUser) {
106 users."${defaultUser}" =
107 { group = cfg.group;
108 home = cfg.dataDir;
109 createHome = true;
110 uid = config.ids.uids.syncthing;
111 description = "Syncthing daemon user";
112 };
113
114 groups."${defaultUser}".gid =
115 config.ids.gids.syncthing;
116 };
117
118 systemd.services = {
119 syncthing = mkIf cfg.systemService {
120 description = "Syncthing service";
121 after = [ "network.target" ];
122 environment = {
123 STNORESTART = "yes";
124 STNOUPGRADE = "yes";
125 inherit (cfg) all_proxy;
126 } // config.networking.proxy.envVars;
127 wantedBy = [ "multi-user.target" ];
128 serviceConfig = {
129 Restart = "on-failure";
130 SuccessExitStatus = "2 3 4";
131 RestartForceExitStatus="3 4";
132 User = cfg.user;
133 Group = cfg.group;
134 PermissionsStartOnly = true;
135 ExecStart = "${cfg.package}/bin/syncthing -no-browser -home=${cfg.dataDir}";
136 };
137 };
138
139 syncthing-resume = {
140 wantedBy = [ "suspend.target" ];
141 };
142 };
143 };
144}