at 17.09-beta 8.1 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 cfg = config.services.resilio; 7 8 resilioSync = pkgs.resilio-sync; 9 10 sharedFoldersRecord = map (entry: { 11 secret = entry.secret; 12 dir = entry.directory; 13 14 use_relay_server = entry.useRelayServer; 15 use_tracker = entry.useTracker; 16 use_dht = entry.useDHT; 17 18 search_lan = entry.searchLAN; 19 use_sync_trash = entry.useSyncTrash; 20 known_hosts = knownHosts; 21 }) cfg.sharedFolders; 22 23 configFile = pkgs.writeText "config.json" (builtins.toJSON ({ 24 device_name = cfg.deviceName; 25 storage_path = cfg.storagePath; 26 listening_port = cfg.listeningPort; 27 use_gui = false; 28 check_for_updates = cfg.checkForUpdates; 29 use_upnp = cfg.useUpnp; 30 download_limit = cfg.downloadLimit; 31 upload_limit = cfg.uploadLimit; 32 lan_encrypt_data = cfg.encryptLAN; 33 } // optionalAttrs cfg.enableWebUI { 34 webui = { listen = "${cfg.httpListenAddr}:${toString cfg.httpListenPort}"; } // 35 (optionalAttrs (cfg.httpLogin != "") { login = cfg.httpLogin; }) // 36 (optionalAttrs (cfg.httpPass != "") { password = cfg.httpPass; }) // 37 (optionalAttrs (cfg.apiKey != "") { api_key = cfg.apiKey; }) // 38 (optionalAttrs (cfg.directoryRoot != "") { directory_root = cfg.directoryRoot; }); 39 } // optionalAttrs (sharedFoldersRecord != []) { 40 shared_folders = sharedFoldersRecord; 41 })); 42 43in 44{ 45 options = { 46 services.resilio = { 47 enable = mkOption { 48 type = types.bool; 49 default = false; 50 description = '' 51 If enabled, start the Resilio Sync daemon. Once enabled, you can 52 interact with the service through the Web UI, or configure it in your 53 NixOS configuration. Enabling the <literal>resilio</literal> service 54 also installs a systemd user unit which can be used to start 55 user-specific copies of the daemon. Once installed, you can use 56 <literal>systemctl --user start resilio</literal> as your user to start 57 the daemon using the configuration file located at 58 <literal>$HOME/.config/resilio-sync/config.json</literal>. 59 ''; 60 }; 61 62 deviceName = mkOption { 63 type = types.str; 64 example = "Voltron"; 65 default = config.networking.hostName; 66 description = '' 67 Name of the Resilio Sync device. 68 ''; 69 }; 70 71 listeningPort = mkOption { 72 type = types.int; 73 default = 0; 74 example = 44444; 75 description = '' 76 Listening port. Defaults to 0 which randomizes the port. 77 ''; 78 }; 79 80 checkForUpdates = mkOption { 81 type = types.bool; 82 default = true; 83 description = '' 84 Determines whether to check for updates and alert the user 85 about them in the UI. 86 ''; 87 }; 88 89 useUpnp = mkOption { 90 type = types.bool; 91 default = true; 92 description = '' 93 Use Universal Plug-n-Play (UPnP) 94 ''; 95 }; 96 97 downloadLimit = mkOption { 98 type = types.int; 99 default = 0; 100 example = 1024; 101 description = '' 102 Download speed limit. 0 is unlimited (default). 103 ''; 104 }; 105 106 uploadLimit = mkOption { 107 type = types.int; 108 default = 0; 109 example = 1024; 110 description = '' 111 Upload speed limit. 0 is unlimited (default). 112 ''; 113 }; 114 115 httpListenAddr = mkOption { 116 type = types.str; 117 default = "0.0.0.0"; 118 example = "1.2.3.4"; 119 description = '' 120 HTTP address to bind to. 121 ''; 122 }; 123 124 httpListenPort = mkOption { 125 type = types.int; 126 default = 9000; 127 description = '' 128 HTTP port to bind on. 129 ''; 130 }; 131 132 httpLogin = mkOption { 133 type = types.str; 134 example = "allyourbase"; 135 default = ""; 136 description = '' 137 HTTP web login username. 138 ''; 139 }; 140 141 httpPass = mkOption { 142 type = types.str; 143 example = "arebelongtous"; 144 default = ""; 145 description = '' 146 HTTP web login password. 147 ''; 148 }; 149 150 encryptLAN = mkOption { 151 type = types.bool; 152 default = true; 153 description = "Encrypt LAN data."; 154 }; 155 156 enableWebUI = mkOption { 157 type = types.bool; 158 default = false; 159 description = '' 160 Enable Web UI for administration. Bound to the specified 161 <literal>httpListenAddress</literal> and 162 <literal>httpListenPort</literal>. 163 ''; 164 }; 165 166 storagePath = mkOption { 167 type = types.path; 168 default = "/var/lib/resilio-sync/"; 169 description = '' 170 Where BitTorrent Sync will store it's database files (containing 171 things like username info and licenses). Generally, you should not 172 need to ever change this. 173 ''; 174 }; 175 176 apiKey = mkOption { 177 type = types.str; 178 default = ""; 179 description = "API key, which enables the developer API."; 180 }; 181 182 directoryRoot = mkOption { 183 type = types.str; 184 default = ""; 185 example = "/media"; 186 description = "Default directory to add folders in the web UI."; 187 }; 188 189 sharedFolders = mkOption { 190 default = []; 191 example = 192 [ { secret = "AHMYFPCQAHBM7LQPFXQ7WV6Y42IGUXJ5Y"; 193 directory = "/home/user/sync_test"; 194 useRelayServer = true; 195 useTracker = true; 196 useDHT = false; 197 searchLAN = true; 198 useSyncTrash = true; 199 knownHosts = [ 200 "192.168.1.2:4444" 201 "192.168.1.3:4444" 202 ]; 203 } 204 ]; 205 description = '' 206 Shared folder list. If enabled, web UI must be 207 disabled. Secrets can be generated using <literal>rslsync 208 --generate-secret</literal>. Note that this secret will be 209 put inside the Nix store, so it is realistically not very 210 secret. 211 212 If you would like to be able to modify the contents of this 213 directories, it is recommended that you make your user a 214 member of the <literal>resilio</literal> group. 215 216 Directories in this list should be in the 217 <literal>resilio</literal> group, and that group must have 218 write access to the directory. It is also recommended that 219 <literal>chmod g+s</literal> is applied to the directory 220 so that any sub directories created will also belong to 221 the <literal>resilio</literal> group. Also, 222 <literal>setfacl -d -m group:resilio:rwx</literal> and 223 <literal>setfacl -m group:resilio:rwx</literal> should also 224 be applied so that the sub directories are writable by 225 the group. 226 ''; 227 }; 228 }; 229 }; 230 231 config = mkIf cfg.enable { 232 assertions = 233 [ { assertion = cfg.deviceName != ""; 234 message = "Device name cannot be empty."; 235 } 236 { assertion = cfg.enableWebUI -> cfg.sharedFolders == []; 237 message = "If using shared folders, the web UI cannot be enabled."; 238 } 239 { assertion = cfg.apiKey != "" -> cfg.enableWebUI; 240 message = "If you're using an API key, you must enable the web server."; 241 } 242 ]; 243 244 users.extraUsers.rslsync = { 245 description = "Resilio Sync Service user"; 246 home = cfg.storagePath; 247 createHome = true; 248 uid = config.ids.uids.rslsync; 249 group = "rslsync"; 250 }; 251 252 users.extraGroups = [ { name = "rslsync"; } ]; 253 254 systemd.services.resilio = with pkgs; { 255 description = "Resilio Sync Service"; 256 wantedBy = [ "multi-user.target" ]; 257 after = [ "network.target" "local-fs.target" ]; 258 serviceConfig = { 259 Restart = "on-abort"; 260 UMask = "0002"; 261 User = "rslsync"; 262 ExecStart = '' 263 ${resilioSync}/bin/rslsync --nodaemon --config ${configFile} 264 ''; 265 }; 266 }; 267 }; 268}