diff --git a/nixos/modules/services/torrent/transmission.nix b/nixos/modules/services/torrent/transmission.nix
-index 014a22bb5a8..6f6d5a05a2a 100644
+index 34a5219c959..779924a65a8 100644
--- a/nixos/modules/services/torrent/transmission.nix
+++ b/nixos/modules/services/torrent/transmission.nix
-@@ -12,10 +12,15 @@ let
+@@ -7,15 +7,20 @@ let
+ inherit (config.environment) etc;
+ apparmor = config.security.apparmor;
+ rootDir = "/run/transmission";
+- homeDir = "/var/lib/transmission";
+ settingsDir = ".config/transmission-daemon";
downloadsDir = "Downloads";
incompleteDir = ".incomplete";
watchDir = "watchdir";
- # TODO: switch to configGen.json once RFC0042 is implemented
- settingsFile = pkgs.writeText "settings.json" (builtins.toJSON cfg.settings);
+- settingsFile = pkgs.writeText "settings.json" (builtins.toJSON cfg.settings);
++ settingsFormat = pkgs.formats.json {};
++ settingsFile = settingsFormat.generate "settings.json" cfg.settings;
in
{
+ imports = [
+ (mkRenamedOptionModule ["services" "transmission" "port"]
+ ["services" "transmission" "settings" "rpc-port"])
-+ (mkRenamedOptionModule ["services" "transmission" "openFirewall"]
-+ ["services" "transmission" "openPeerPorts"])
++ (mkAliasOptionModule ["services" "transmission" "openFirewall"]
++ ["services" "transmission" "openPeerPorts"])
+ ];
options = {
services.transmission = {
enable = mkEnableOption ''the headless Transmission BitTorrent daemon.
-@@ -27,45 +32,140 @@ in
- Torrents are downloaded to ${homeDir}/${downloadsDir} by default and are
+@@ -24,48 +29,141 @@ in
+ transmission-remote, the WebUI (http://127.0.0.1:9091/ by default),
+ or other clients like stig or tremc.
+
+- Torrents are downloaded to ${homeDir}/${downloadsDir} by default and are
++ Torrents are downloaded to <xref linkend="opt-services.transmission.home"/>/${downloadsDir} by default and are
accessible to users in the "transmission" group'';
- settings = mkOption rec {
+ settings = mkOption {
description = ''
- Attribute set whose fields overwrites fields in
-+ Settings whose fields overwrites fields in
++ Settings whose options overwrite fields in
<literal>.config/transmission-daemon/settings.json</literal>
- (each time the service starts). String values must be quoted, integer and
- boolean values must not.
'';
+ default = {};
+ type = types.submodule {
-+ freeformType = with types;
-+ (attrsOf (nullOr (oneOf [str int bool]))) // {
-+ description = "setting option";
-+ };
++ freeformType = settingsFormat.type;
+ options.download-dir = mkOption {
+ type = types.path;
+ default = "${cfg.home}/${downloadsDir}";
+ default = "${cfg.home}/${incompleteDir}";
+ description = ''
+ When enabled with
-+ <link linkend="opt-services.transmission.settings.incomplete-dir-enabled">incomplete-dir-enabled</link>,
++ services.transmission.home
++ <xref linkend="opt-services.transmission.settings.incomplete-dir-enabled"/>,
+ new torrents will download the files to this directory.
+ When complete, the files will be moved to download-dir
-+ <link linkend="opt-services.transmission.settings.download-dir">download-dir</link>.
++ <xref linkend="opt-services.transmission.settings.download-dir"/>.
+ '';
+ };
+ options.incomplete-dir-enabled = mkOption {
+ default = 65535;
+ description = ''
+ The maximum peer port to listen to for incoming connections
-+ when <link linkend="opt-services.transmission.settings.peer-port-random-on-start">peer-port-random-on-start</link> is enabled.
++ when <xref linkend="opt-services.transmission.settings.peer-port-random-on-start"/> is enabled.
+ '';
+ };
+ options.peer-port-random-low = mkOption {
+ default = 65535;
+ description = ''
+ The minimal peer port to listen to for incoming connections
-+ when <link linkend="opt-services.transmission.settings.peer-port-random-on-start">peer-port-random-on-start</link> is enabled.
++ when <xref linkend="opt-services.transmission.settings.peer-port-random-on-start"/> is enabled.
+ '';
+ };
+ options.peer-port-random-on-start = mkOption {
+ default = false;
+ description = ''
+ Whether to run
-+ <link linkend="opt-services.transmission.settings.script-torrent-done-filename">script-torrent-done-filename</link>
++ <xref linkend="opt-services.transmission.settings.script-torrent-done-filename"/>
+ at torrent completion.
+ '';
+ };
+ type = types.bool;
+ default = false;
+ description = ''Whether to enable the
-+ <link linkend="opt-services.transmission.settings.watch-dir">watch-dir</link>.
++ <xref linkend="opt-services.transmission.settings.watch-dir"/>.
+ '';
+ };
+ options.trash-original-torrent-files = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''Whether to delete torrents added from the
-+ <link linkend="opt-services.transmission.settings.watch-dir">watch-dir</link>.
++ <xref linkend="opt-services.transmission.settings.watch-dir"/>.
+ '';
+ };
+ };
};
downloadDirPermissions = mkOption {
-@@ -81,17 +181,6 @@ in
- '';
- };
-
+@@ -74,31 +172,22 @@ in
+ example = "775";
+ description = ''
+ The permissions set by <literal>systemd.activationScripts.transmission-daemon</literal>
+- on the directories <link linkend="opt-services.transmission.settings">settings.download-dir</link>
+- and <link linkend="opt-services.transmission.settings">settings.incomplete-dir</link>.
++ on the directories <xref linkend="opt-services.transmission.settings.download-dir"/>
++ and <xref linkend="opt-services.transmission.settings.incomplete-dir"/>.
+ Note that you may also want to change
+- <link linkend="opt-services.transmission.settings">settings.umask</link>.
+- '';
+- };
+-
- port = mkOption {
- type = types.port;
- description = ''
- If instead you want to change the peer port,
- use <link linkend="opt-services.transmission.settings">settings.peer-port</link>
- or <link linkend="opt-services.transmission.settings">settings.peer-port-random-on-start</link>.
-- '';
-- };
--
++ <xref linkend="opt-services.transmission.settings.umask"/>.
+ '';
+ };
+
home = mkOption {
type = types.path;
- default = homeDir;
-@@ -125,7 +214,9 @@ in
+- default = homeDir;
++ default = "/var/lib/transmission";
+ description = ''
+ The directory where Transmission will create <literal>${settingsDir}</literal>.
+- as well as <literal>${downloadsDir}/</literal> unless <link linkend="opt-services.transmission.settings">settings.download-dir</link> is changed,
+- and <literal>${incompleteDir}/</literal> unless <link linkend="opt-services.transmission.settings">settings.incomplete-dir</link> is changed.
++ as well as <literal>${downloadsDir}/</literal> unless
++ <xref linkend="opt-services.transmission.settings.download-dir"/> is changed,
++ and <literal>${incompleteDir}/</literal> unless
++ <xref linkend="opt-services.transmission.settings.incomplete-dir"/> is changed.
+ '';
+ };
+
+@@ -119,19 +208,22 @@ in
+ description = ''
+ Path to a JSON file to be merged with the settings.
+ Useful to merge a file which is better kept out of the Nix store
+- because it contains sensible data like <link linkend="opt-services.transmission.settings">settings.rpc-password</link>.
++ because it contains sensible data like
++ <xref linkend="opt-services.transmission.settings.rpc-password"/>.
+ '';
+ default = "/dev/null";
example = "/var/lib/secrets/transmission/settings.json";
};
performanceNetParameters = mkEnableOption ''tweaking of kernel parameters
to open many more connections at the same time.
-@@ -152,36 +243,10 @@ in
+
+ Note that you may also want to increase
+- <link linkend="opt-services.transmission.settings">settings.peer-limit-global</link>.
++ <xref linkend="opt-services.transmission.settings.peer-limit-global"/>.
+ And be aware that these settings are quite aggressive
+ and might not suite your regular desktop use.
+ For instance, SSH sessions may time out more easily'';
+@@ -152,36 +244,10 @@ in
install -d -m '${cfg.downloadDirPermissions}' -o '${cfg.user}' -g '${cfg.group}' '${cfg.settings.download-dir}'
'' + optionalString cfg.settings.incomplete-dir-enabled ''
install -d -m '${cfg.downloadDirPermissions}' -o '${cfg.user}' -g '${cfg.group}' '${cfg.settings.incomplete-dir}'
-
systemd.services.transmission = {
description = "Transmission BitTorrent Service";
- after = [ "network.target" ] ++ optional apparmor "apparmor.service";
-@@ -226,11 +291,9 @@ in
+ after = [ "network.target" ] ++ optional apparmor.enable "apparmor.service";
+@@ -226,11 +292,9 @@ in
cfg.settings.download-dir
] ++
optional cfg.settings.incomplete-dir-enabled
BindReadOnlyPaths = [
# No confinement done of /nix/store here like in systemd-confinement.nix,
# an AppArmor profile is provided to get a confinement based upon paths and rights.
-@@ -238,8 +301,10 @@ in
- "/etc"
+@@ -239,8 +303,10 @@ in
+ "/run"
] ++
optional (cfg.settings.script-torrent-done-enabled &&
- cfg.settings.script-torrent-done-filename != "")
# The following options are only for optimizing:
# systemd-analyze security transmission
AmbientCapabilities = "";
-@@ -306,25 +371,28 @@ in
+@@ -307,25 +373,28 @@ in
};
});
boot.kernel.sysctl = mkMerge [
# Transmission uses a single UDP socket in order to implement multiple uTP sockets,
-@@ -419,7 +487,7 @@ in
- rw ${cfg.settings.incomplete-dir}/**,
- ''}
- ${optionalString cfg.settings.watch-dir-enabled ''
-- rw ${cfg.settings.watch-dir}/**,
-+ r${optionalString cfg.settings.trash-original-torrent-files "w"} ${cfg.settings.watch-dir}/**,
- ''}
- profile dirs {
- rw ${cfg.settings.download-dir}/**,
-@@ -427,12 +495,12 @@ in
- rw ${cfg.settings.incomplete-dir}/**,
- ''}
- ${optionalString cfg.settings.watch-dir-enabled ''
-- rw ${cfg.settings.watch-dir}/**,
-+ r${optionalString cfg.settings.trash-original-torrent-files "w"} ${cfg.settings.watch-dir}/**,
- ''}
- }
+@@ -340,21 +409,21 @@ in
+ # Increase the number of available source (local) TCP and UDP ports to 49151.
+ # Usual default is 32768 60999, ie. 28231 ports.
+ # Find out your current usage with: ss -s
+- "net.ipv4.ip_local_port_range" = "16384 65535";
++ "net.ipv4.ip_local_port_range" = mkDefault "16384 65535";
+ # Timeout faster generic TCP states.
+ # Usual default is 600.
+ # Find out your current usage with: watch -n 1 netstat -nptuo
+- "net.netfilter.nf_conntrack_generic_timeout" = 60;
++ "net.netfilter.nf_conntrack_generic_timeout" = mkDefault 60;
+ # Timeout faster established but inactive connections.
+ # Usual default is 432000.
+- "net.netfilter.nf_conntrack_tcp_timeout_established" = 600;
++ "net.netfilter.nf_conntrack_tcp_timeout_established" = mkDefault 600;
+ # Clear immediately TCP states after timeout.
+ # Usual default is 120.
+- "net.netfilter.nf_conntrack_tcp_timeout_time_wait" = 1;
++ "net.netfilter.nf_conntrack_tcp_timeout_time_wait" = mkDefault 1;
+ # Increase the number of trackable connections.
+ # Usual default is 262144.
+ # Find out your current usage with: conntrack -C
+- "net.netfilter.nf_conntrack_max" = 1048576;
++ "net.netfilter.nf_conntrack_max" = mkDefault 1048576;
+ })
+ ];
+
+@@ -370,7 +439,7 @@ in
+ rw ${cfg.settings.incomplete-dir}/**,
+ ''}
+ ${optionalString cfg.settings.watch-dir-enabled ''
+- rw ${cfg.settings.watch-dir}/**,
++ r${optionalString cfg.settings.trash-original-torrent-files "w"} ${cfg.settings.watch-dir}/**,
+ ''}
+ profile dirs {
+ rw ${cfg.settings.download-dir}/**,
+@@ -378,12 +447,12 @@ in
+ rw ${cfg.settings.incomplete-dir}/**,
+ ''}
+ ${optionalString cfg.settings.watch-dir-enabled ''
+- rw ${cfg.settings.watch-dir}/**,
++ r${optionalString cfg.settings.trash-original-torrent-files "w"} ${cfg.settings.watch-dir}/**,
+ ''}
+ }
- ${optionalString (cfg.settings.script-torrent-done-enabled &&
-- cfg.settings.script-torrent-done-filename != "") ''
-+ cfg.settings.script-torrent-done-filename != null) ''
- # Stack transmission_directories profile on top of
- # any existing profile for script-torrent-done-filename
- # FIXME: to be tested as I'm not sure it works well with NoNewPrivileges=
+ ${optionalString (cfg.settings.script-torrent-done-enabled &&
+- cfg.settings.script-torrent-done-filename != "") ''
++ cfg.settings.script-torrent-done-filename != null) ''
+ # Stack transmission_directories profile on top of
+ # any existing profile for script-torrent-done-filename
+ # FIXME: to be tested as I'm not sure it works well with NoNewPrivileges=