resilio service: replaces btsync service, which is no longer supported upstream.
This commit is contained in:
parent
2bd5c13af5
commit
919b39bb7c
|
@ -294,6 +294,7 @@
|
||||||
jackett = 276;
|
jackett = 276;
|
||||||
aria2 = 277;
|
aria2 = 277;
|
||||||
clickhouse = 278;
|
clickhouse = 278;
|
||||||
|
rslsync = 279;
|
||||||
|
|
||||||
# When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
|
# When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
|
||||||
|
|
||||||
|
@ -557,6 +558,7 @@
|
||||||
jackett = 276;
|
jackett = 276;
|
||||||
aria2 = 277;
|
aria2 = 277;
|
||||||
clickhouse = 278;
|
clickhouse = 278;
|
||||||
|
rslsync = 279;
|
||||||
|
|
||||||
# When adding a gid, make sure it doesn't match an existing
|
# When adding a gid, make sure it doesn't match an existing
|
||||||
# uid. Users and groups with the same name should have equal
|
# uid. Users and groups with the same name should have equal
|
||||||
|
|
|
@ -485,6 +485,7 @@
|
||||||
./services/networking/radvd.nix
|
./services/networking/radvd.nix
|
||||||
./services/networking/rdnssd.nix
|
./services/networking/rdnssd.nix
|
||||||
./services/networking/redsocks.nix
|
./services/networking/redsocks.nix
|
||||||
|
./services/networking/resilio.nix
|
||||||
./services/networking/rpcbind.nix
|
./services/networking/rpcbind.nix
|
||||||
./services/networking/sabnzbd.nix
|
./services/networking/sabnzbd.nix
|
||||||
./services/networking/searx.nix
|
./services/networking/searx.nix
|
||||||
|
|
315
nixos/modules/services/networking/resilio.nix
Normal file
315
nixos/modules/services/networking/resilio.nix
Normal file
|
@ -0,0 +1,315 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.resilio;
|
||||||
|
|
||||||
|
resilioSync = pkgs.resilio;
|
||||||
|
|
||||||
|
listenAddr = cfg.httpListenAddr + ":" + (toString cfg.httpListenPort);
|
||||||
|
|
||||||
|
boolStr = x: if x then "true" else "false";
|
||||||
|
optionalEmptyStr = b: v: optionalString (b != "") v;
|
||||||
|
|
||||||
|
webUIConfig = optionalString cfg.enableWebUI
|
||||||
|
''
|
||||||
|
"webui":
|
||||||
|
{
|
||||||
|
${optionalEmptyStr cfg.httpLogin "\"login\": \"${cfg.httpLogin}\","}
|
||||||
|
${optionalEmptyStr cfg.httpPass "\"password\": \"${cfg.httpPass}\","}
|
||||||
|
${optionalEmptyStr cfg.apiKey "\"api_key\": \"${cfg.apiKey}\","}
|
||||||
|
${optionalEmptyStr cfg.directoryRoot "\"directory_root\": \"${cfg.directoryRoot}\","}
|
||||||
|
"listen": "${listenAddr}"
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
|
||||||
|
knownHosts = e:
|
||||||
|
optionalString (e ? "knownHosts")
|
||||||
|
(concatStringsSep "," (map (v: "\"${v}\"") e."knownHosts"));
|
||||||
|
|
||||||
|
sharedFoldersRecord =
|
||||||
|
concatStringsSep "," (map (entry:
|
||||||
|
let helper = attr: v:
|
||||||
|
if (entry ? attr) then boolStr entry.attr else boolStr v;
|
||||||
|
in
|
||||||
|
''
|
||||||
|
{
|
||||||
|
"secret": "${entry.secret}",
|
||||||
|
"dir": "${entry.directory}",
|
||||||
|
|
||||||
|
"use_relay_server": ${helper "useRelayServer" true},
|
||||||
|
"use_tracker": ${helper "useTracker" true},
|
||||||
|
"use_dht": ${helper "useDHT" false},
|
||||||
|
|
||||||
|
"search_lan": ${helper "searchLAN" true},
|
||||||
|
"use_sync_trash": ${helper "useSyncTrash" true},
|
||||||
|
|
||||||
|
"known_hosts": [${knownHosts entry}]
|
||||||
|
}
|
||||||
|
'') cfg.sharedFolders);
|
||||||
|
|
||||||
|
sharedFoldersConfig = optionalString (cfg.sharedFolders != [])
|
||||||
|
''
|
||||||
|
"shared_folders":
|
||||||
|
[
|
||||||
|
${sharedFoldersRecord}
|
||||||
|
]
|
||||||
|
'';
|
||||||
|
|
||||||
|
configFile = pkgs.writeText "config.json"
|
||||||
|
''
|
||||||
|
{
|
||||||
|
"device_name": "${cfg.deviceName}",
|
||||||
|
"storage_path": "${cfg.storagePath}",
|
||||||
|
"listening_port": ${toString cfg.listeningPort},
|
||||||
|
"use_gui": false,
|
||||||
|
|
||||||
|
"check_for_updates": ${boolStr cfg.checkForUpdates},
|
||||||
|
"use_upnp": ${boolStr cfg.useUpnp},
|
||||||
|
"download_limit": ${toString cfg.downloadLimit},
|
||||||
|
"upload_limit": ${toString cfg.uploadLimit},
|
||||||
|
"lan_encrypt_data": ${boolStr cfg.encryptLAN},
|
||||||
|
|
||||||
|
${webUIConfig}
|
||||||
|
${sharedFoldersConfig}
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
services.resilio = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
If enabled, start the Resilio Sync daemon. Once enabled, you can
|
||||||
|
interact with the service through the Web UI, or configure it in your
|
||||||
|
NixOS configuration. Enabling the <literal>resilio</literal> service
|
||||||
|
also installs a systemd user unit which can be used to start
|
||||||
|
user-specific copies of the daemon. Once installed, you can use
|
||||||
|
<literal>systemctl --user start resilio</literal> as your user to start
|
||||||
|
the daemon using the configuration file located at
|
||||||
|
<literal>$HOME/.config/resilio-sync/config.json</literal>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
deviceName = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
example = "Voltron";
|
||||||
|
description = ''
|
||||||
|
Name of the Resilio Sync device.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
listeningPort = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = 0;
|
||||||
|
example = 44444;
|
||||||
|
description = ''
|
||||||
|
Listening port. Defaults to 0 which randomizes the port.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
checkForUpdates = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = ''
|
||||||
|
Determines whether to check for updates and alert the user
|
||||||
|
about them in the UI.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
useUpnp = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = ''
|
||||||
|
Use Universal Plug-n-Play (UPnP)
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
downloadLimit = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = 0;
|
||||||
|
example = 1024;
|
||||||
|
description = ''
|
||||||
|
Download speed limit. 0 is unlimited (default).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
uploadLimit = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = 0;
|
||||||
|
example = 1024;
|
||||||
|
description = ''
|
||||||
|
Upload speed limit. 0 is unlimited (default).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
httpListenAddr = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "0.0.0.0";
|
||||||
|
example = "1.2.3.4";
|
||||||
|
description = ''
|
||||||
|
HTTP address to bind to.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
httpListenPort = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = 9000;
|
||||||
|
description = ''
|
||||||
|
HTTP port to bind on.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
httpLogin = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
example = "allyourbase";
|
||||||
|
default = "";
|
||||||
|
description = ''
|
||||||
|
HTTP web login username.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
httpPass = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
example = "arebelongtous";
|
||||||
|
default = "";
|
||||||
|
description = ''
|
||||||
|
HTTP web login password.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
encryptLAN = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "Encrypt LAN data.";
|
||||||
|
};
|
||||||
|
|
||||||
|
enableWebUI = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Enable Web UI for administration. Bound to the specified
|
||||||
|
<literal>httpListenAddress</literal> and
|
||||||
|
<literal>httpListenPort</literal>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
storagePath = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
default = "/var/lib/resilio-sync/";
|
||||||
|
description = ''
|
||||||
|
Where BitTorrent Sync will store it's database files (containing
|
||||||
|
things like username info and licenses). Generally, you should not
|
||||||
|
need to ever change this.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
apiKey = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "";
|
||||||
|
description = "API key, which enables the developer API.";
|
||||||
|
};
|
||||||
|
|
||||||
|
directoryRoot = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "";
|
||||||
|
example = "/media";
|
||||||
|
description = "Default directory to add folders in the web UI.";
|
||||||
|
};
|
||||||
|
|
||||||
|
sharedFolders = mkOption {
|
||||||
|
default = [];
|
||||||
|
example =
|
||||||
|
[ { secret = "AHMYFPCQAHBM7LQPFXQ7WV6Y42IGUXJ5Y";
|
||||||
|
directory = "/home/user/sync_test";
|
||||||
|
useRelayServer = true;
|
||||||
|
useTracker = true;
|
||||||
|
useDHT = false;
|
||||||
|
searchLAN = true;
|
||||||
|
useSyncTrash = true;
|
||||||
|
knownHosts =
|
||||||
|
[ "192.168.1.2:4444"
|
||||||
|
"192.168.1.3:4444"
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
description = ''
|
||||||
|
Shared folder list. If enabled, web UI must be
|
||||||
|
disabled. Secrets can be generated using <literal>rslsync
|
||||||
|
--generate-secret</literal>. Note that this secret will be
|
||||||
|
put inside the Nix store, so it is realistically not very
|
||||||
|
secret.
|
||||||
|
|
||||||
|
If you would like to be able to modify the contents of this
|
||||||
|
directories, it is recommended that you make your user a
|
||||||
|
member of the <literal>resilio</literal> group.
|
||||||
|
|
||||||
|
Directories in this list should be in the
|
||||||
|
<literal>resilio</literal> group, and that group must have
|
||||||
|
write access to the directory. It is also recommended that
|
||||||
|
<literal>chmod g+s</literal> is applied to the directory
|
||||||
|
so that any sub directories created will also belong to
|
||||||
|
the <literal>resilio</literal> group. Also,
|
||||||
|
<literal>setfacl -d -m group:resilio:rwx</literal> and
|
||||||
|
<literal>setfacl -m group:resilio:rwx</literal> should also
|
||||||
|
be applied so that the sub directories are writable by
|
||||||
|
the group.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
assertions =
|
||||||
|
[ { assertion = cfg.deviceName != "";
|
||||||
|
message = "Device name cannot be empty.";
|
||||||
|
}
|
||||||
|
{ assertion = cfg.enableWebUI -> cfg.sharedFolders == [];
|
||||||
|
message = "If using shared folders, the web UI cannot be enabled.";
|
||||||
|
}
|
||||||
|
{ assertion = cfg.apiKey != "" -> cfg.enableWebUI;
|
||||||
|
message = "If you're using an API key, you must enable the web server.";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
services.resilio.package = mkOptionDefault pkgs.resilio;
|
||||||
|
|
||||||
|
users.extraUsers.rslsync = {
|
||||||
|
description = "Resilio Sync Service user";
|
||||||
|
home = cfg.storagePath;
|
||||||
|
createHome = true;
|
||||||
|
uid = config.ids.uids.rslsync;
|
||||||
|
group = "rslsync";
|
||||||
|
};
|
||||||
|
|
||||||
|
users.extraGroups = [ { name = "rslsync"; } ];
|
||||||
|
|
||||||
|
systemd.services.resilio = with pkgs; {
|
||||||
|
description = "Resilio Sync Service";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
after = [ "network.target" "local-fs.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
Restart = "on-abort";
|
||||||
|
UMask = "0002";
|
||||||
|
User = "rslsync";
|
||||||
|
ExecStart =
|
||||||
|
"${resilioSync}/bin/rslsync --nodaemon --config ${configFile}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.user.services.resilio = with pkgs; {
|
||||||
|
description = "Resilio Sync user service";
|
||||||
|
after = [ "network.target" "local-fs.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
Restart = "on-abort";
|
||||||
|
ExecStart =
|
||||||
|
"${resilioSync}/bin/rslsync --nodaemon --config %h/.config/resilio-sync/config.json";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.systemPackages = [ cfg.package ];
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in a new issue