Skip to content

Commit

Permalink
nixos/transmission: format with nixfmt-rfc-style
Browse files Browse the repository at this point in the history
  • Loading branch information
diniamo committed Oct 29, 2024
1 parent 89320d7 commit 76fb46f
Showing 1 changed file with 128 additions and 64 deletions.
192 changes: 128 additions & 64 deletions nixos/modules/services/torrent/transmission.nix
Original file line number Diff line number Diff line change
@@ -1,10 +1,28 @@
{ config, lib, pkgs, options, ... }:
{
config,
lib,
pkgs,
options,
...
}:

let
inherit (lib) mkRenamedOptionModule mkAliasOptionModuleMD mkEnableOption
mkOption types literalExpression mkPackageOption mkIf
optionalString optional mkDefault escapeShellArgs optionalAttrs
mkMerge;
inherit (lib)
mkRenamedOptionModule
mkAliasOptionModuleMD
mkEnableOption
mkOption
types
literalExpression
mkPackageOption
mkIf
optionalString
optional
mkDefault
escapeShellArgs
optionalAttrs
mkMerge
;

cfg = config.services.transmission;
opt = options.services.transmission;
Expand All @@ -15,15 +33,36 @@ let
downloadsDir = "Downloads";
incompleteDir = ".incomplete";
watchDir = "watchdir";
settingsFormat = pkgs.formats.json {};
settingsFormat = pkgs.formats.json { };
settingsFile = settingsFormat.generate "settings.json" cfg.settings;
in
{
imports = [
(mkRenamedOptionModule ["services" "transmission" "port"]
["services" "transmission" "settings" "rpc-port"])
(mkAliasOptionModuleMD ["services" "transmission" "openFirewall"]
["services" "transmission" "openPeerPorts"])
(mkRenamedOptionModule
[
"services"
"transmission"
"port"
]
[
"services"
"transmission"
"settings"
"rpc-port"
]
)
(mkAliasOptionModuleMD
[
"services"
"transmission"
"openFirewall"
]
[
"services"
"transmission"
"openPeerPorts"
]
)
];
options = {
services.transmission = {
Expand All @@ -49,7 +88,7 @@ in
See [Transmission's Wiki](https://github.com/transmission/transmission/wiki/Editing-Configuration-Files)
for documentation of settings not explicitly covered by this module.
'';
default = {};
default = { };
type = types.submodule {
freeformType = settingsFormat.type;
options = {
Expand Down Expand Up @@ -162,15 +201,17 @@ in
watch-dir-enabled = mkOption {
type = types.bool;
default = false;
description = ''Whether to enable the
[](#opt-services.transmission.settings.watch-dir).
description = ''
Whether to enable the
[](#opt-services.transmission.settings.watch-dir).
'';
};
trash-original-torrent-files = mkOption {
type = types.bool;
default = false;
description = ''Whether to delete torrents added from the
[](#opt-services.transmission.settings.watch-dir).
description = ''
Whether to delete torrents added from the
[](#opt-services.transmission.settings.watch-dir).
'';
};
};
Expand Down Expand Up @@ -245,7 +286,7 @@ in

extraFlags = mkOption {
type = types.listOf types.str;
default = [];
default = [ ];
example = [ "--log-debug" ];
description = ''
Extra flags passed to the transmission command in the service definition.
Expand Down Expand Up @@ -321,18 +362,23 @@ in

serviceConfig = {
# Use "+" because credentialsFile may not be accessible to User= or Group=.
ExecStartPre = [("+" + pkgs.writeShellScript "transmission-prestart" ''
set -eu${lib.optionalString (cfg.settings.message-level >= 3) "x"}
${pkgs.jq}/bin/jq --slurp add ${settingsFile} '${cfg.credentialsFile}' |
install -D -m 600 -o '${cfg.user}' -g '${cfg.group}' /dev/stdin \
'${cfg.home}/${settingsDir}/settings.json'
'')];
ExecStart="${cfg.package}/bin/transmission-daemon -f -g ${cfg.home}/${settingsDir} ${escapeShellArgs cfg.extraFlags}";
ExecStartPre = [
(
"+"
+ pkgs.writeShellScript "transmission-prestart" ''
set -eu${lib.optionalString (cfg.settings.message-level >= 3) "x"}
${pkgs.jq}/bin/jq --slurp add ${settingsFile} '${cfg.credentialsFile}' |
install -D -m 600 -o '${cfg.user}' -g '${cfg.group}' /dev/stdin \
'${cfg.home}/${settingsDir}/settings.json'
''
)
];
ExecStart = "${cfg.package}/bin/transmission-daemon -f -g ${cfg.home}/${settingsDir} ${escapeShellArgs cfg.extraFlags}";
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
User = cfg.user;
Group = cfg.group;
# Create rootDir in the host's mount namespace.
RuntimeDirectory = [(baseNameOf rootDir)];
RuntimeDirectory = [ (baseNameOf rootDir) ];
RuntimeDirectoryMode = "755";
# This is for BindPaths= and BindReadOnlyPaths=
# to allow traversal of directories they create in RootDirectory=.
Expand All @@ -350,27 +396,30 @@ in
RootDirectoryStartOnly = true;
MountAPIVFS = true;
BindPaths =
[ "${cfg.home}/${settingsDir}"
[
"${cfg.home}/${settingsDir}"
cfg.settings.download-dir
# Transmission may need to read in the host's /run (eg. /run/systemd/resolve)
# or write in its private /run (eg. /run/host).
"/run"
] ++
optional cfg.settings.incomplete-dir-enabled
cfg.settings.incomplete-dir ++
optional (cfg.settings.watch-dir-enabled && cfg.settings.trash-original-torrent-files)
cfg.settings.watch-dir;
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.
builtins.storeDir
"/etc"
] ++
optional (cfg.settings.script-torrent-done-enabled &&
cfg.settings.script-torrent-done-filename != null)
cfg.settings.script-torrent-done-filename ++
optional (cfg.settings.watch-dir-enabled && !cfg.settings.trash-original-torrent-files)
cfg.settings.watch-dir;
]
++ optional cfg.settings.incomplete-dir-enabled cfg.settings.incomplete-dir
++ optional (
cfg.settings.watch-dir-enabled && cfg.settings.trash-original-torrent-files
) cfg.settings.watch-dir;
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.
builtins.storeDir
"/etc"
]
++ optional (
cfg.settings.script-torrent-done-enabled && cfg.settings.script-torrent-done-filename != null
) cfg.settings.script-torrent-done-filename
++ optional (
cfg.settings.watch-dir-enabled && !cfg.settings.trash-original-torrent-files
) cfg.settings.watch-dir;
StateDirectory = [
"transmission"
"transmission/${settingsDir}"
Expand Down Expand Up @@ -409,7 +458,11 @@ in
RemoveIPC = true;
# AF_UNIX may become usable one day:
# https://github.com/transmission/transmission/issues/441
RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ];
RestrictAddressFamilies = [
"AF_UNIX"
"AF_INET"
"AF_INET6"
];
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
Expand All @@ -418,7 +471,13 @@ in
# Groups in @system-service which do not contain a syscall
# listed by perf stat -e 'syscalls:sys_enter_*' transmission-daemon -f
# in tests, and seem likely not necessary for transmission-daemon.
"~@aio" "~@chown" "~@keyring" "~@memlock" "~@resources" "~@setuid" "~@timer"
"~@aio"
"~@chown"
"~@keyring"
"~@memlock"
"~@resources"
"~@setuid"
"~@timer"
# In the @privileged group, but reached when querying infos through RPC (eg. with stig).
"quotactl"
];
Expand Down Expand Up @@ -446,21 +505,24 @@ in

networking.firewall = mkMerge [
(mkIf cfg.openPeerPorts (
if cfg.settings.peer-port-random-on-start
then
{ allowedTCPPortRanges =
[ { from = cfg.settings.peer-port-random-low;
to = cfg.settings.peer-port-random-high;
}
];
allowedUDPPortRanges =
[ { from = cfg.settings.peer-port-random-low;
to = cfg.settings.peer-port-random-high;
}
];
if cfg.settings.peer-port-random-on-start then
{
allowedTCPPortRanges = [
{
from = cfg.settings.peer-port-random-low;
to = cfg.settings.peer-port-random-high;
}
];
allowedUDPPortRanges = [
{
from = cfg.settings.peer-port-random-low;
to = cfg.settings.peer-port-random-high;
}
];
}
else
{ allowedTCPPorts = [ cfg.settings.peer-port ];
{
allowedTCPPorts = [ cfg.settings.peer-port ];
allowedUDPPorts = [ cfg.settings.peer-port ];
}
))
Expand Down Expand Up @@ -522,14 +584,16 @@ in
''}
}
${optionalString (cfg.settings.script-torrent-done-enabled &&
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=
# https://gitlab.com/apparmor/apparmor/-/wikis/AppArmorStacking#seccomp-and-no_new_privs
px ${cfg.settings.script-torrent-done-filename} -> &@{dirs},
''}
${optionalString
(cfg.settings.script-torrent-done-enabled && 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=
# https://gitlab.com/apparmor/apparmor/-/wikis/AppArmorStacking#seccomp-and-no_new_privs
px ${cfg.settings.script-torrent-done-filename} -> &@{dirs},
''
}
${optionalString (cfg.webHome != null) ''
r ${cfg.webHome}/**,
Expand Down

0 comments on commit 76fb46f

Please sign in to comment.