nixos/ytdl-sub: init module

Defelo a4175381 db166529

Changed files
+158
nixos
doc
manual
release-notes
modules
+2
nixos/doc/manual/release-notes/rl-2505.section.md
···
- [Zenoh](https://zenoh.io/), a pub/sub/query protocol with low overhead. The Zenoh router daemon is available as [services.zenohd](options.html#opt-services.zenohd.enable)
+
- [ytdl-sub](https://github.com/jmbannon/ytdl-sub), a tool that downloads media via yt-dlp and prepares it for your favorite media player, including Kodi, Jellyfin, Plex, Emby, and modern music players. Available as [services.ytdl-sub](options.html#opt-services.ytdl-sub.instances).
+
- [MaryTTS](https://github.com/marytts/marytts), an open-source, multilingual text-to-speech synthesis system written in pure Java. Available as [services.marytts](options.html#opt-services.marytts).
- [networking.modemmanager](options.html#opt-networking.modemmanager) has been split out of [networking.networkmanager](options.html#opt-networking.networkmanager). NetworkManager still enables ModemManager by default, but options exist now to run NetworkManager without ModemManager.
+1
nixos/modules/module-list.nix
···
./services/misc/workout-tracker.nix
./services/misc/whisparr.nix
./services/misc/xmrig.nix
+
./services/misc/ytdl-sub.nix
./services/misc/zoneminder.nix
./services/misc/zookeeper.nix
./services/monitoring/alerta.nix
+155
nixos/modules/services/misc/ytdl-sub.nix
···
+
{
+
config,
+
lib,
+
pkgs,
+
utils,
+
...
+
}:
+
+
let
+
cfg = config.services.ytdl-sub;
+
+
settingsFormat = pkgs.formats.yaml { };
+
in
+
{
+
meta.maintainers = with lib.maintainers; [ defelo ];
+
+
options.services.ytdl-sub = {
+
package = lib.mkPackageOption pkgs "ytdl-sub" { };
+
+
user = lib.mkOption {
+
type = lib.types.str;
+
default = "ytdl-sub";
+
description = "User account under which ytdl-sub runs.";
+
};
+
+
group = lib.mkOption {
+
type = lib.types.str;
+
default = "ytdl-sub";
+
description = "Group under which ytdl-sub runs.";
+
};
+
+
instances = lib.mkOption {
+
default = { };
+
description = "Configuration for ytdl-sub instances.";
+
type = lib.types.attrsOf (
+
lib.types.submodule (
+
{ name, ... }:
+
{
+
options = {
+
enable = lib.mkEnableOption "ytdl-sub instance";
+
+
schedule = lib.mkOption {
+
type = lib.types.nullOr lib.types.str;
+
description = "How often to run ytdl-sub. See {manpage}`systemd.time(7)` for the format.";
+
default = null;
+
example = "0/6:0";
+
};
+
+
config = lib.mkOption {
+
type = settingsFormat.type;
+
description = "Configuration for ytdl-sub. See <https://ytdl-sub.readthedocs.io/en/latest/config_reference/config_yaml.html> for more information.";
+
default = { };
+
example = {
+
presets."YouTube Playlist" = {
+
download = "{subscription_value}";
+
output_options = {
+
output_directory = "YouTube";
+
file_name = "{channel}/{playlist_title}/{playlist_index_padded}_{title}.{ext}";
+
maintain_download_archive = true;
+
};
+
};
+
};
+
};
+
+
subscriptions = lib.mkOption {
+
type = settingsFormat.type;
+
description = "Subscriptions for ytdl-sub. See <https://ytdl-sub.readthedocs.io/en/latest/config_reference/subscription_yaml.html> for more information.";
+
default = { };
+
example = {
+
"YouTube Playlist" = {
+
"Some Playlist" = "https://www.youtube.com/playlist?list=...";
+
};
+
};
+
};
+
};
+
+
config = {
+
config.configuration.working_directory = "/run/ytdl-sub/${utils.escapeSystemdPath name}";
+
};
+
}
+
)
+
);
+
};
+
};
+
+
config = lib.mkIf (cfg.instances != { }) {
+
systemd.services =
+
let
+
mkService =
+
name: instance:
+
let
+
configFile = settingsFormat.generate "config.yaml" instance.config;
+
subscriptionsFile = settingsFormat.generate "subscriptions.yaml" instance.subscriptions;
+
in
+
lib.nameValuePair "ytdl-sub-${utils.escapeSystemdPath name}" {
+
inherit (instance) enable;
+
+
wants = [ "network-online.target" ];
+
after = [ "network-online.target" ];
+
+
startAt = lib.optional (instance.schedule != null) instance.schedule;
+
+
serviceConfig = {
+
User = cfg.user;
+
Group = cfg.group;
+
+
RuntimeDirectory = "ytdl-sub/${utils.escapeSystemdPath name}";
+
StateDirectory = "ytdl-sub/${utils.escapeSystemdPath name}";
+
WorkingDirectory = "/var/lib/ytdl-sub/${utils.escapeSystemdPath name}";
+
+
ExecStart = "${lib.getExe cfg.package} --config ${configFile} sub ${subscriptionsFile}";
+
+
# Hardening
+
CapabilityBoundingSet = [ "" ];
+
DeviceAllow = [ "" ];
+
LockPersonality = true;
+
PrivateDevices = true;
+
PrivateTmp = true;
+
PrivateUsers = true;
+
ProcSubset = "pid";
+
ProtectClock = true;
+
ProtectControlGroups = true;
+
ProtectHome = true;
+
ProtectHostname = true;
+
ProtectKernelLogs = true;
+
ProtectKernelModules = true;
+
ProtectKernelTunables = true;
+
ProtectProc = "invisible";
+
ProtectSystem = "strict";
+
RestrictAddressFamilies = [
+
"AF_INET"
+
"AF_INET6"
+
"AF_UNIX"
+
];
+
RestrictNamespaces = true;
+
RestrictRealtime = true;
+
RestrictSUIDSGID = true;
+
SystemCallArchitectures = "native";
+
};
+
};
+
in
+
lib.mapAttrs' mkService cfg.instances;
+
+
users.users = lib.mkIf (cfg.user == "ytdl-sub") {
+
ytdl-sub = {
+
isSystemUser = true;
+
group = cfg.group;
+
};
+
};
+
+
users.groups = lib.mkIf (cfg.group == "ytdl-sub") {
+
ytdl-sub = { };
+
};
+
};
+
}