Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nixos/jellyfin: add data dir options #233617

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
138 changes: 78 additions & 60 deletions nixos/modules/services/misc/jellyfin.nix
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,22 @@ in
description = lib.mdDoc "Group under which jellyfin runs.";
};

dataDir = mkOption {
type = types.path;
default = "/var/lib/jellyfin";
description = lib.mdDoc ''
Jellyfin data directory.
'';
};

cacheDir = mkOption {
type = types.path;
default = "/var/cache/jellyfin";
description = lib.mdDoc ''
Jellyfin cache data directory.
Comment on lines +38 to +46
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The service name is duplicated with the path and the description is rather none descriptive.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's ok to keep these explicitly set here with the hardcoded 'jellyfin' in the name. We don't want the defaults to accidentally change as that will break existing setups. Most other services I see (eg postgresql) use the repeated names rather than abstracting it out to another variable

'';
};

openFirewall = mkOption {
type = types.bool;
default = false;
Expand All @@ -44,66 +60,68 @@ in
};

config = mkIf cfg.enable {
systemd.services.jellyfin = {
description = "Jellyfin Media Server";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];

# This is mostly follows: https://github.com/jellyfin/jellyfin/blob/master/fedora/jellyfin.service
# Upstream also disable some hardenings when running in LXC, we do the same with the isContainer option
serviceConfig = rec {
Type = "simple";
User = cfg.user;
Group = cfg.group;
StateDirectory = "jellyfin";
StateDirectoryMode = "0700";
CacheDirectory = "jellyfin";
CacheDirectoryMode = "0700";
UMask = "0077";
WorkingDirectory = "/var/lib/jellyfin";
ExecStart = "${cfg.package}/bin/jellyfin --datadir '/var/lib/${StateDirectory}' --cachedir '/var/cache/${CacheDirectory}'";
Restart = "on-failure";
TimeoutSec = 15;
SuccessExitStatus = ["0" "143"];

# Security options:
NoNewPrivileges = true;
SystemCallArchitectures = "native";
# AF_NETLINK needed because Jellyfin monitors the network connection
RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" "AF_NETLINK" ];
RestrictNamespaces = !config.boot.isContainer;
RestrictRealtime = true;
RestrictSUIDSGID = true;
ProtectControlGroups = !config.boot.isContainer;
ProtectHostname = true;
ProtectKernelLogs = !config.boot.isContainer;
ProtectKernelModules = !config.boot.isContainer;
ProtectKernelTunables = !config.boot.isContainer;
LockPersonality = true;
PrivateTmp = !config.boot.isContainer;
# needed for hardware acceleration
PrivateDevices = false;
PrivateUsers = true;
RemoveIPC = true;

SystemCallFilter = [
"~@clock"
"~@aio"
"~@chown"
"~@cpu-emulation"
"~@debug"
"~@keyring"
"~@memlock"
"~@module"
"~@mount"
"~@obsolete"
"~@privileged"
"~@raw-io"
"~@reboot"
"~@setuid"
"~@swap"
];
SystemCallErrorNumber = "EPERM";
systemd = {
tmpfiles.rules = [
"d '${cfg.dataDir}' 0700 ${cfg.user} ${cfg.group} - -"
"d '${cfg.cacheDir}' 0700 ${cfg.user} ${cfg.group} - -"
];
services.jellyfin = {
description = "Jellyfin Media Server";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];

# This is mostly follows: https://github.com/jellyfin/jellyfin/blob/master/fedora/jellyfin.service
# Upstream also disable some hardenings when running in LXC, we do the same with the isContainer option
serviceConfig = rec {
Type = "simple";
User = cfg.user;
Group = cfg.group;
UMask = "0077";
WorkingDirectory = cfg.dataDir;
ExecStart = "${cfg.package}/bin/jellyfin --datadir '${cfg.dataDir}' --cachedir '${cfg.cacheDir}'";
Restart = "on-failure";
TimeoutSec = 15;
SuccessExitStatus = ["0" "143"];

# Security options:
NoNewPrivileges = true;
SystemCallArchitectures = "native";
# AF_NETLINK needed because Jellyfin monitors the network connection
RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" "AF_NETLINK" ];
RestrictNamespaces = !config.boot.isContainer;
RestrictRealtime = true;
RestrictSUIDSGID = true;
ProtectControlGroups = !config.boot.isContainer;
ProtectHostname = true;
ProtectKernelLogs = !config.boot.isContainer;
ProtectKernelModules = !config.boot.isContainer;
ProtectKernelTunables = !config.boot.isContainer;
LockPersonality = true;
PrivateTmp = !config.boot.isContainer;
# needed for hardware acceleration
PrivateDevices = false;
PrivateUsers = true;
RemoveIPC = true;

SystemCallFilter = [
"~@clock"
"~@aio"
"~@chown"
"~@cpu-emulation"
"~@debug"
"~@keyring"
"~@memlock"
"~@module"
"~@mount"
"~@obsolete"
"~@privileged"
"~@raw-io"
"~@reboot"
"~@setuid"
"~@swap"
];
Comment on lines +107 to +122
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"~@clock"
"~@aio"
"~@chown"
"~@cpu-emulation"
"~@debug"
"~@keyring"
"~@memlock"
"~@module"
"~@mount"
"~@obsolete"
"~@privileged"
"~@raw-io"
"~@reboot"
"~@setuid"
"~@swap"
];
"~@clock @aio @chown @cpu-emulation @debug @keyring @memlock @module @mount" @obsolete @privileged @raw-io @reboot @setuid @swap"
];

this should be the same but in one line of the service file instead of ~15

SystemCallErrorNumber = "EPERM";
};
};
};

Expand Down