ookflix: refactors FIX COMMIT

This commit is contained in:
ooks-io 2024-12-02 18:55:06 +11:00
parent da77c223ff
commit c096dc295a
10 changed files with 154 additions and 138 deletions

View file

@ -1,11 +1,4 @@
{
lib,
config,
...
}: let
inherit (lib) elem mkIf;
inherit (config.ooknet.server) services;
in {
imports = [
./jellyfin.nix
./plex.nix
@ -14,21 +7,9 @@ in {
./sonarr.nix
./prowlarr.nix
./gluetun.nix
./transmission.nix
./qbittorrent.nix
./shared.nix
./options.nix
];
config = mkIf (elem "ookflix" services) {
ooknet.server.ookflix = {
gpuAcceleration.enable = true;
services = {
jellyfin.enable = true;
plex.enable = true;
jellyseer.enable = true;
tautulli.enable = true;
};
};
};
}

View file

@ -6,27 +6,24 @@
...
}: let
ookflixLib = import ./lib.nix {inherit self lib config;};
inherit (ookflixLib) mkServiceUser;
inherit (ookflixLib) mkServiceUser mkServiceSecret;
inherit (lib) mkIf;
inherit (ook.lib.container) mkContainerEnvironment mkContainerPort mkServiceSecret;
inherit (config.ooknet.server.ookflix.services) transmission gluetun;
inherit (ook.lib.container) mkContainerEnvironment mkContainerPort;
inherit (config.ooknet.server.ookflix.services) qbittorrent gluetun;
in {
config = mkIf gluetun.enable {
users = mkServiceUser gluetun.user.name;
age.secrets.vpn_env = mkServiceSecret "vpn_env" "gluetun";
age.secrets = mkServiceSecret "vpn_env" "gluetun";
virtualisation.oci-containers.containers = {
# vpn container
gluetun = mkIf {
gluetun = mkIf gluetun.enable {
image = "qmcgaw/gluetun:latest";
# should make this an option.
environmentFiles = [config.age.secrets.vpn_env.path];
ports = [
(mkContainerPort transmission.port)
(mkContainerPort qbittorrent.port)
];
environment = mkContainerEnvironment gluetun.user.id gluetun.group.id {
VPN_SERVICE_PROVIDER = gluetun.provider;
VPN_TYPE = "wireguard";
};
environment = mkContainerEnvironment gluetun.user.id gluetun.group.id;
extraOptions = [
# give network admin permissions
"--cap-add=NET_ADMIN"

View file

@ -23,7 +23,7 @@ in {
image = "lscr.io/linuxserver/jellyfin:latest";
autoStart = true;
hostname = "jellyfin";
ports = ["${jellyfin.port}:${jellyfin.port}"];
ports = [(mkContainerPort jellyfin.port)];
volumes = [
"${volumes.media.root}:/data"
"${jellyfin.stateDir}:/config"

View file

@ -9,6 +9,7 @@
inherit (lib.types) int path port str;
inherit (config.ooknet) server;
cfg = server.ookflix;
ookflixEnabled = elem "ookflix" server.services;
mkSubdomainOption = name: description: example:
mkOption {
@ -60,19 +61,25 @@
inherit description example;
};
mkVolumeOption = type: pathValue:
mkVolumeOption = rootPath: pathValue:
mkOption {
type = path;
default =
if type == "state"
if rootPath == "state"
then "${cfg.volumes.state.root}/${pathValue}"
else if type == "media"
else if rootPath == "data"
then "${cfg.volumes.data.root}/${pathValue}"
else if rootPath == "media"
then "${cfg.volumes.media.root}/${pathValue}"
else if type == "downloads"
then "${cfg.volumes.downloads.root}/${pathValue}"
else if type == "root"
else if rootPath == "torrents"
then "${cfg.volumes.torrents.root}/${pathValue}"
else if rootPath == "usenet"
then "${cfg.volumes.usenet.root}/${pathValue}"
else if rootPath == "usenet/complete"
then "${cfg.volumes.usenet.complete.root}/${pathValue}"
else if rootPath == "root"
then pathValue
else throw "Invalid VolumeOption type: ${type}. Must be one of 'state' 'media' 'downloads' 'root'";
else throw "Invalid VolumeOption rootPath: ${rootPath}. Must be one of 'state' 'data' 'media' 'torrents' 'usenet' 'usenet/complete' 'root'";
};
mkServiceOptions = name: {
@ -81,7 +88,7 @@
uid,
...
} @ args: {
enable = mkEnableOption "Enable ${name} container";
enable = mkEnableOption "Enable ${name} container" // {default = ookflixEnabled;};
port = mkPortOption args.port "Port for ${name} container." 80;
domain = mkSubdomainOption name "Domain for ${name} container." "${name}.mydomain.com";
stateDir = mkVolumeOption "state" name;
@ -93,7 +100,7 @@
uid,
...
} @ args: {
enable = mkEnableOption "Enable ${name} container";
enable = mkEnableOption "Enable ${name} container" // {default = ookflixEnabled;};
user = mkUserOption name args.uid;
group = mkGroupOption name args.gid;
};
@ -118,7 +125,7 @@
};
mkServiceSecret = name: service: {
${name} = {
file = "${self}/secrets/container/${name}.age";
file = "${self}/secrets/containers/${name}.age";
owner = cfg.services.${service}.user.name;
group = cfg.services.${service}.group.name;
};

View file

@ -6,16 +6,19 @@
}: let
ookflixLib = import ./lib.nix {inherit lib config self;};
inherit (ookflixLib) mkVolumeOption mkGroupOption mkServiceOptions mkBasicServiceOptions;
inherit (lib) mkOption mkEnableOption;
inherit (ookflixLib) mkVolumeOption mkGroupOption mkServiceOptions mkBasicServiceOptions mkPortOption;
inherit (lib) mkOption mkEnableOption elem;
inherit (config.ooknet.server) services;
inherit (lib.types) enum;
inherit (config.ooknet) server;
cfg = server.ookflix;
in {
options.ooknet.server.ookflix = {
enable = mkEnableOption "Enable ookflix a container based media server module";
enable =
mkEnableOption "Enable ookflix a container based media server module"
// {default = elem "ookflix" services;};
gpuAcceleration = {
enable = mkEnableOption "Enable GPU acceleration for video streamers";
enable =
mkEnableOption "Enable GPU acceleration for video streamers"
// {default = elem "ookflix" services;};
type = mkOption {
type = enum ["nvidia" "intel" "amd"];
default = config.ooknet.hardware.gpu.type;
@ -28,15 +31,26 @@ in {
volumes = {
state.root = mkVolumeOption "root" "/var/lib/ookflix";
data.root = mkVolumeOption "root" "/jellyfin";
downloads = {
root = mkVolumeOption "${cfg.content.root}/downloads";
tv = mkVolumeOption "downloads" "tv";
movies = mkVolumeOption "downloads" "movies";
books = mkVolumeOption "downloads" "books";
torrents = {
root = mkVolumeOption "data" "torrents";
tv = mkVolumeOption "torrents" "tv";
movies = mkVolumeOption "torrents" "movies";
books = mkVolumeOption "torrents" "books";
};
usenet = {
root = mkVolumeOption "data" "usenet";
incomplete = mkVolumeOption "usenet" "incomplete";
complete = {
root = mkVolumeOption "usenet" "complete";
tv = mkVolumeOption "usenet/complete" "tv";
movies = mkVolumeOption "usenet/complete" "movies";
books = mkVolumeOption "usenet/complete" "books";
};
};
media = {
root = mkVolumeOption "root" "${cfg.volumes.content.root}/media";
root = mkVolumeOption "data" "media";
movies = mkVolumeOption "media" "movies";
tv = mkVolumeOption "media" "tv";
books = mkVolumeOption "media" "books";
@ -74,11 +88,13 @@ in {
uid = 982;
gid = 987;
};
transmission = mkServiceOptions "transmission" {
port = 9091;
uid = 70;
gid = 70;
};
qbittorrent =
mkServiceOptions "qbittorrent" {
port = 8080;
uid = 377;
gid = 377;
}
// {torrentPort = mkPortOption 58080 "Torrenting Port for qbittorrent" 58080;};
jellyseer = mkServiceOptions "jellyseer" {
port = 5055;
uid = 345;

View file

@ -22,7 +22,6 @@ in {
hostname = "prowlarr";
ports = [(mkContainerPort prowlarr.port)];
volumes = ["${prowlarr.stateDir}:/config"];
extraOptions = ["--network" "host"];
labels = mkContainerLabel {
name = "prowlarr";
inherit (prowlarr) port domain;

View file

@ -0,0 +1,46 @@
{
config,
lib,
ook,
self,
...
}: let
ookflixLib = import ./lib.nix {inherit lib config self;};
inherit (ookflixLib) mkServiceUser mkServiceStateDir;
inherit (lib) mkIf;
inherit (ook.lib.container) mkContainerLabel mkContainerEnvironment;
inherit (config.ooknet.server.ookflix) groups volumes;
inherit (config.ooknet.server.ookflix.services) qbittorrent;
in {
config = mkIf qbittorrent.enable {
users = mkServiceUser qbittorrent.user.name;
systemd.tmpfiles = mkServiceStateDir "qbittorrent" qbittorrent.stateDir;
virtualisation.oci-containers.containers = {
# Torrent client
qbittorrent = {
image = "ghcr.io/hotio/qbittorrent";
dependsOn = ["gluetun"];
volumes = [
"${qbittorrent.stateDir}:/config"
"${volumes.torrents.root}:/data/torrents"
];
extraOptions = ["--network=container:gluetun"];
labels = mkContainerLabel {
name = "qbittorrent";
inherit (qbittorrent) port domain;
homepage = {
group = "downloads";
description = "torrent client";
};
};
environment =
mkContainerEnvironment qbittorrent.user.id groups.downloads.id
// {
UMASK = "002";
WEBUI_PORTS = "${toString qbittorrent.port}/tcp,${toString qbittorrent.port}/udp";
TORRENTING_PORT = "${toString qbittorrent.torrentPort}";
};
};
};
};
}

View file

@ -25,7 +25,6 @@ in {
"${radarr.stateDir}:/config"
"${volumes.data.root}:/data"
];
extraOptions = ["--network" "host"];
labels = mkContainerLabel {
name = "radarr";
inherit (radarr) port domain;
@ -34,7 +33,11 @@ in {
description = "media-server movies downloader";
};
};
environment = mkContainerEnvironment radarr.user.id groups.media.id;
environment =
mkContainerEnvironment radarr.user.id groups.media.id
// {
UMASK = "002";
};
};
};
};

View file

@ -7,59 +7,69 @@
inherit (config.ooknet.host) admin;
inherit (config.ooknet.server) ookflix;
inherit (config.ooknet.server.ookflix) volumes groups;
inherit (config.ooknet.server.ookflix.services) jellyfin plex sonarr radarr prowlarr transmission;
mediaDirPermissions = {
inherit (config.ooknet.server.ookflix.services) jellyfin plex sonarr radarr prowlarr qbittorrent;
dataDirPermissions = {
mode = "0775";
user = admin.name;
group = groups.media.name;
};
downloadDirPermissions = {
mode = "0770";
user = admin.name;
group = groups.downloads.name;
};
ifTheyExist = users: builtins.filter (user: builtins.hasAttr user config.users.users) users;
in {
config = mkIf ookflix.enable {
users.groups = {
${groups.media.name} = {
inherit (groups.media) name gid;
inherit (groups.media) name;
gid = groups.media.id;
members = ifTheyExist [
# need access to the media library
jellyfin.user.name
plex.user.name
# need access to the media library and the torrent/usenet library
sonarr.user.name
radarr.user.name
prowlarr.user.name
];
};
${groups.downloads.name} = {
inherit (groups.downloads) name gid;
members = ifTheyExist [
sonarr.user.name
radarr.user.name
prowlarr.user.name
transmission.user.name
# need access to the torrent library
qbittorrent.user.name
];
};
};
systemd.tmpfiles.settings = {
contentRoot = {
"${volumes.content.root}"."d" = {
mode = "0775";
user = "root";
group = "root";
};
};
mediaDirectories = {
"${volumes.media.root}"."d" = mediaDirPermissions;
"${volumes.media.tv}"."d" = mediaDirPermissions;
"${volumes.media.movies}"."d" = mediaDirPermissions;
};
downloadDirectories = {
"${volumes.downloads.root}"."d" = downloadDirPermissions;
"${volumes.downloads.complete}"."d" = downloadDirPermissions;
"${volumes.downloads.incomplete}"."d" = downloadDirPermissions;
"${volumes.downloads.watch}"."d" = downloadDirPermissions;
ookflixDataDirs = {
/*
set up the entire directory structure it should look something like this:
data
torrents
movies
books
tv
usenet
incomplete
complete
books
movies
tv
media
movies
books
tv
*/
"${volumes.data.root}"."d" = dataDirPermissions;
"${volumes.torrents.root}"."d" = dataDirPermissions;
"${volumes.torrents.movies}"."d" = dataDirPermissions;
"${volumes.torrents.tv}"."d" = dataDirPermissions;
"${volumes.torrents.books}"."d" = dataDirPermissions;
"${volumes.usenet.root}"."d" = dataDirPermissions;
"${volumes.usenet.incomplete}"."d" = dataDirPermissions;
"${volumes.usenet.complete.root}"."d" = dataDirPermissions;
"${volumes.usenet.complete.movies}"."d" = dataDirPermissions;
"${volumes.usenet.complete.tv}"."d" = dataDirPermissions;
"${volumes.usenet.complete.books}"."d" = dataDirPermissions;
"${volumes.media.root}"."d" = dataDirPermissions;
"${volumes.media.movies}"."d" = dataDirPermissions;
"${volumes.media.tv}"."d" = dataDirPermissions;
"${volumes.media.books}"."d" = dataDirPermissions;
};
};
};

View file

@ -1,43 +0,0 @@
{
config,
lib,
ook,
self,
...
}: let
ookflixLib = import ./lib.nix {inherit lib config self;};
inherit (ookflixLib) mkServiceUser mkServiceStateDir;
inherit (lib) mkIf;
inherit (ook.lib.container) mkContainerLabel mkContainerEnvironment mkContainerPort;
inherit (config.ooknet.server.ookflix) groups volumes;
inherit (config.ooknet.server.ookflix.services) transmission gluetun;
in {
config = mkIf transmission.enable {
users = mkServiceUser transmission.user.name;
systemd.tmpfiles = mkServiceStateDir "transmission" transmission.stateDir;
virtualisation.oci-containers.containers = {
# Torrent client
transmission = {
image = "lscr.io/linuxserver/transmission:latest";
environmentFiles = [config.age.secrets.transmission_env.path];
environment = mkContainerEnvironment transmission.user.id groups.downloads.id;
dependsOn = ["gluetun"];
networkMode = "service:gluetun"; # Use VPN container's network
volumes = [
"${transmission.stateDir}:/config"
"${volumes.downloads.root}:/downloads"
"${volumes.downloads.watch}:/watch"
];
extraOptions = ["--network=container:gluetun"];
labels = mkContainerLabel {
name = "transmission";
inherit (transmission) port domain;
homepage = {
group = "downloads";
description = "torrent client";
};
};
};
};
};
}