230 lines
6.7 KiB
Nix
230 lines
6.7 KiB
Nix
|
{ config, lib, pkgs, ... }:
|
||
|
let
|
||
|
inherit (lib.options) mkOption mkEnableOption mkPackageOption;
|
||
|
inherit (lib.modules) mkIf;
|
||
|
inherit (lib.types) str enum int path submodule nullOr bool;
|
||
|
|
||
|
cfg = config.services.ytdl-web;
|
||
|
in
|
||
|
{
|
||
|
options.services.ytdl-web = {
|
||
|
enable = mkEnableOption "ytdl-web";
|
||
|
package = mkPackageOption pkgs "ytdl-web" { };
|
||
|
|
||
|
user = mkOption {
|
||
|
type = str;
|
||
|
default = "ytdl-web";
|
||
|
description = ''
|
||
|
The user account ytdl-web will run under.
|
||
|
'';
|
||
|
};
|
||
|
|
||
|
group = mkOption {
|
||
|
type = str;
|
||
|
default = "ytdl-web";
|
||
|
description = ''
|
||
|
The group ytdl-web will run under.
|
||
|
'';
|
||
|
};
|
||
|
|
||
|
appEnvironment = mkOption {
|
||
|
type = enum [ "Development" "Staging" "Production" ];
|
||
|
default = "Production";
|
||
|
description = ''
|
||
|
The application environment mode.
|
||
|
'';
|
||
|
};
|
||
|
|
||
|
ytdlPackage = mkPackageOption pkgs "yt-dlp" { };
|
||
|
|
||
|
port = mkOption {
|
||
|
type = int;
|
||
|
default = 8080;
|
||
|
description = ''
|
||
|
The tcp port for the web server to listen on.
|
||
|
'';
|
||
|
};
|
||
|
|
||
|
listen = mkOption {
|
||
|
type = str;
|
||
|
default = "0.0.0.0";
|
||
|
example = "127.0.0.1";
|
||
|
description = ''
|
||
|
The address for the web server to listen on.
|
||
|
'';
|
||
|
};
|
||
|
|
||
|
openFirewall = mkOption {
|
||
|
type = bool;
|
||
|
default = false;
|
||
|
example = literalExpression "true";
|
||
|
description = ''
|
||
|
Open ports in the firewall for the ytdl-web server.
|
||
|
'';
|
||
|
};
|
||
|
|
||
|
basePath = mkOption {
|
||
|
type = str;
|
||
|
default = "/";
|
||
|
example = "/ytdl-web";
|
||
|
description = ''
|
||
|
The base path that the web application is hosted under.
|
||
|
Useful for reverse-proxies that proxy the app with a path prefix.
|
||
|
'';
|
||
|
};
|
||
|
|
||
|
cacheTTL = mkOption {
|
||
|
type = str;
|
||
|
default = "1h";
|
||
|
example = "2m";
|
||
|
description = ''
|
||
|
How long to keep cached metadata for.
|
||
|
|
||
|
A duration string is a possibly signed sequence of decimal numbers,
|
||
|
each with optional fraction and a unit suffix, such as "300ms", "-1.5h" or "2h45m".
|
||
|
Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
|
||
|
'';
|
||
|
};
|
||
|
|
||
|
cacheDir = mkOption {
|
||
|
type = path;
|
||
|
default = "/var/cache/ytdl-web";
|
||
|
example = "/tmp/ytdl-web";
|
||
|
description = ''
|
||
|
The directory containing the ytdl metadata cache.
|
||
|
'';
|
||
|
};
|
||
|
|
||
|
cookies = mkOption {
|
||
|
type = submodule {
|
||
|
options = {
|
||
|
enable = mkEnableOption "ytdl cookies";
|
||
|
|
||
|
file = mkOption {
|
||
|
type = nullOr path;
|
||
|
default = null;
|
||
|
example = "/etc/ytdl-web/cookies.txt";
|
||
|
description = ''
|
||
|
The file that contains the netscape formatted cookies.
|
||
|
'';
|
||
|
};
|
||
|
|
||
|
fromBrowser = mkOption {
|
||
|
description = ''
|
||
|
Settings for obtaining cookies from a local browser's cookie storage.
|
||
|
'';
|
||
|
|
||
|
type = submodule {
|
||
|
options = {
|
||
|
browser = mkOption {
|
||
|
type = nullOr (enum [ "brave" "chrome" "chromium" "edge" "firefox" "opera" "safari" "vivaldi" ]);
|
||
|
default = null;
|
||
|
description = ''
|
||
|
The name of the browser to load cookies from.
|
||
|
'';
|
||
|
};
|
||
|
|
||
|
keyring = mkOption {
|
||
|
type = nullOr (enum [ "basictext" "gnomekeyring" "kwallet" ]);
|
||
|
default = null;
|
||
|
description = ''
|
||
|
The name of the keyring to use to decrypt cookies when using the chromium browser.
|
||
|
'';
|
||
|
};
|
||
|
|
||
|
profile = mkOption {
|
||
|
type = nullOr str;
|
||
|
default = null;
|
||
|
description = ''
|
||
|
The name of the browser profile to load the cookies from.
|
||
|
'';
|
||
|
};
|
||
|
|
||
|
container = mkOption {
|
||
|
type = nullOr str;
|
||
|
default = null;
|
||
|
description = ''
|
||
|
The container name to load the cookies from when using the firefox browser.
|
||
|
'';
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
|
||
|
config = mkIf cfg.enable {
|
||
|
assertions = [
|
||
|
{
|
||
|
assertion = cfg.cookies.file != null && cfg.cookies.fromBrowser.browser != null;
|
||
|
message = "The `services.ytdl-web.cookies.file` and `services.ytdl-web.cookies.fromBrowser.browser` options are mutually exclusive.";
|
||
|
}
|
||
|
{
|
||
|
assertion = cfg.cookies.fromBrowser.browser != null &&
|
||
|
!(builtins.elem cfg.cookies.fromBrowser.browser [ "brave" "chrome" "chromium" "edge" "opera" "vivaldi" ]) &&
|
||
|
cfg.cookies.fromBrowser.keyring != null;
|
||
|
message = "The `services.ytdl-web.cookies.fromBrowser.keyring` only functions with a chromium-based browser.";
|
||
|
}
|
||
|
{
|
||
|
assertion = cfg.cookies.fromBrowser.browser != null &&
|
||
|
cfg.cookies.fromBrowser.browser != "firefox" &&
|
||
|
cfg.cookies.fromBrowser.container != null;
|
||
|
message = "The `services.ytdl-web.cookies.fromBrowser.container` only functions with the firefox browser.";
|
||
|
}
|
||
|
];
|
||
|
|
||
|
systemd.services.ytdl-web = {
|
||
|
description = "ytdl-web";
|
||
|
after = [ "networking.target" ];
|
||
|
wantedBy = [ "multi-user.target" ];
|
||
|
|
||
|
environment = {
|
||
|
YTDL_ENV = cfg.appEnvironment;
|
||
|
YTDL_BINARY_PATH = toString cfg.ytdlPackage;
|
||
|
YTDL_HTTP_PORT = toString cfg.port;
|
||
|
YTDL_HTTP_LISTEN = cfg.listen;
|
||
|
YTDL_HTTP_BASEPATH = cfg.basePath;
|
||
|
YTDL_CACHE_TTL = cfg.cacheTTL;
|
||
|
YTDL_CACHE_DIRPATH = cfg.cacheDir;
|
||
|
YTDL_COOKIES_ENABLED = if cfg.cookies.enable then "true" else "false";
|
||
|
YTDL_COOKIES_FILEPATH = cfg.cookies.file;
|
||
|
YTDL_COOKIES_FROMBROWSER_BROWSER = cfg.cookies.fromBrowser.browser;
|
||
|
YTDL_COOKIES_FROMBROWSER_KEYRING = cfg.cookies.fromBrowser.keyring;
|
||
|
YTDL_COOKIES_FROMBROWSER_PROFILE = cfg.cookies.fromBrowser.profile;
|
||
|
YTDL_COOKIES_FROMBROWSER_CONTAINER = cfg.cookies.fromBrowser.container;
|
||
|
};
|
||
|
|
||
|
serviceConfig = {
|
||
|
Type = "simple";
|
||
|
User = cfg.user;
|
||
|
Group = cfg.group;
|
||
|
ExecStart = "${lib.getExe cfg.package} serve";
|
||
|
Restart = "on-failure";
|
||
|
};
|
||
|
};
|
||
|
|
||
|
systemd.tmpfiles.rules = [
|
||
|
"d ${cfg.cacheDir} 0770 ${cfg.user} ${cfg.group} -"
|
||
|
];
|
||
|
|
||
|
networking.firewall = mkIf cfg.openFirewall {
|
||
|
allowedTCPPorts = [ cfg.port ];
|
||
|
};
|
||
|
|
||
|
users = {
|
||
|
users = mkIf (cfg.user == "ytdl-web") {
|
||
|
ytdl-web = {
|
||
|
isSystemUser = true;
|
||
|
group = cfg.group;
|
||
|
};
|
||
|
};
|
||
|
|
||
|
groups = mkIf (cfg.group == "ytdl-web") {
|
||
|
ytdl-web = { };
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
}
|