refactor(mediabox): library mounts

This commit is contained in:
arcnmx 2024-01-24 12:46:21 -08:00
parent 228e2cf788
commit 59c61d021e
20 changed files with 416 additions and 101 deletions

33
modules/nixos/deluge.nix Normal file
View file

@ -0,0 +1,33 @@
{
config,
lib,
...
}: let
inherit (lib.options) mkOption;
inherit (lib.modules) mkIf mkMerge;
cfg = config.services.deluge;
in {
options.services.deluge = with lib.types; {
downloadDir = mkOption {
type = path;
default = cfg.dataDir + "/Downloads";
};
completedDir = mkOption {
type = nullOr path;
default = null;
};
};
config = {
services.deluge = {
config = mkMerge [
{
download_location = cfg.downloadDir;
move_completed = cfg.completedDir != null;
}
(mkIf (cfg.completedDir != null) {
move_completed_path = cfg.completedDir;
})
];
};
};
}

14
modules/nixos/jackett.nix Normal file
View file

@ -0,0 +1,14 @@
{
lib,
...
}: let
inherit (lib.options) mkOption;
in {
options.services.jackett = with lib.types; {
port = mkOption {
type = port;
default = 9117;
readOnly = true;
};
};
}

View file

@ -24,7 +24,7 @@
}; };
config = { config = {
paths = let paths = let
paths = map (path: "${config.path}/media/${path}") config.subdirectories; paths = map (path: "${config.path}/${path}") config.subdirectories;
path = singleton config.path; path = singleton config.path;
in mkOptionDefault (if config.subdirectories != null then paths else path); in mkOptionDefault (if config.subdirectories != null then paths else path);
recursive = mkDefault true; recursive = mkDefault true;

14
modules/nixos/radarr.nix Normal file
View file

@ -0,0 +1,14 @@
{
lib,
...
}: let
inherit (lib.options) mkOption;
in {
options.services.radarr = with lib.types; {
port = mkOption {
type = port;
default = 7878;
readOnly = true;
};
};
}

14
modules/nixos/sonarr.nix Normal file
View file

@ -0,0 +1,14 @@
{
lib,
...
}: let
inherit (lib.options) mkOption;
in {
options.services.sonarr = with lib.types; {
port = mkOption {
type = port;
default = 8989;
readOnly = true;
};
};
}

38
nixos/access/bazarr.nix Normal file
View file

@ -0,0 +1,38 @@
{
config,
lib,
}: let
inherit (lib.modules) mkIf mkDefault mkOptionDefault;
cfg = config.services.bazarr;
access = config.services.nginx.access.bazarr;
proxyPass = mkDefault "https://${access.host}:${toString access.port}";
locations = {
"/" = {
inherit proxyPass;
};
};
in {
options.services.nginx.access.bazarr = with lib.types; {
host = mkOption {
type = str;
};
domain = mkOption {
type = str;
default = "bazarr.${config.networking.domain}";
};
port = mkOption {
type = port;
};
};
config.services.nginx = {
access.bazarr = mkIf cfg.enable {
host = mkOptionDefault "localhost";
port = mkOptionDefault cfg.listenPort;
};
virtualHosts = {
${access.domain} = {
inherit locations;
};
};
};
}

38
nixos/access/jackett.nix Normal file
View file

@ -0,0 +1,38 @@
{
config,
lib,
}: let
inherit (lib.modules) mkIf mkDefault mkOptionDefault;
cfg = config.services.jackett;
access = config.services.nginx.access.jackett;
proxyPass = mkDefault "https://${access.host}:${toString access.port}";
locations = {
"/" = {
inherit proxyPass;
};
};
in {
options.services.nginx.access.jackett = with lib.types; {
host = mkOption {
type = str;
};
domain = mkOption {
type = str;
default = "jackett.${config.networking.domain}";
};
port = mkOption {
type = port;
default = cfg.port;
};
};
config.services.nginx = {
access.jackett = mkIf cfg.enable {
host = mkOptionDefault "localhost";
};
virtualHosts = {
${access.domain} = {
inherit locations;
};
};
};
}

View file

@ -18,7 +18,7 @@ let
"/" = { "/" = {
inherit proxyPass; inherit proxyPass;
}; };
"=/ca.pem" = { "=/ca.pem" = mkIf cfg.server.unencrypted.enable {
alias = "${cfg.server.unencrypted.package.ca}"; alias = "${cfg.server.unencrypted.package.ca}";
}; };
}; };

38
nixos/access/ombi.nix Normal file
View file

@ -0,0 +1,38 @@
{
config,
lib,
}: let
inherit (lib.modules) mkIf mkDefault mkOptionDefault;
cfg = config.services.ombi;
access = config.services.nginx.access.ombi;
proxyPass = mkDefault "https://${access.host}:${toString access.port}";
locations = {
"/" = {
inherit proxyPass;
};
};
in {
options.services.nginx.access.ombi = with lib.types; {
host = mkOption {
type = str;
};
domain = mkOption {
type = str;
default = "ombi.${config.networking.domain}";
};
port = mkOption {
type = port;
};
};
config.services.nginx = {
access.ombi = mkIf cfg.enable {
host = mkOptionDefault "localhost";
port = mkOptionDefault cfg.port;
};
virtualHosts = {
${access.domain} = {
inherit locations;
};
};
};
}

38
nixos/access/radarr.nix Normal file
View file

@ -0,0 +1,38 @@
{
config,
lib,
}: let
inherit (lib.modules) mkIf mkDefault mkOptionDefault;
cfg = config.services.radarr;
access = config.services.nginx.access.radarr;
proxyPass = mkDefault "https://${access.host}:${toString access.port}";
locations = {
"/" = {
inherit proxyPass;
};
};
in {
options.services.nginx.access.radarr = with lib.types; {
host = mkOption {
type = str;
};
domain = mkOption {
type = str;
default = "radarr.${config.networking.domain}";
};
port = mkOption {
type = port;
default = cfg.port;
};
};
config.services.nginx = {
access.radarr = mkIf cfg.enable {
host = mkOptionDefault "localhost";
};
virtualHosts = {
${access.domain} = {
inherit locations;
};
};
};
}

38
nixos/access/sonarr.nix Normal file
View file

@ -0,0 +1,38 @@
{
config,
lib,
}: let
inherit (lib.modules) mkIf mkDefault mkOptionDefault;
cfg = config.services.sonarr;
access = config.services.nginx.access.sonarr;
proxyPass = mkDefault "https://${access.host}:${toString access.port}";
locations = {
"/" = {
inherit proxyPass;
};
};
in {
options.services.nginx.access.sonarr = with lib.types; {
host = mkOption {
type = str;
};
domain = mkOption {
type = str;
default = "sonarr.${config.networking.domain}";
};
port = mkOption {
type = port;
default = cfg.port;
};
};
config.services.nginx = {
access.sonarr = mkIf cfg.enable {
host = mkOptionDefault "localhost";
};
virtualHosts = {
${access.domain} = {
inherit locations;
};
};
};
}

38
nixos/access/tautulli.nix Normal file
View file

@ -0,0 +1,38 @@
{
config,
lib,
}: let
inherit (lib.modules) mkIf mkDefault mkOptionDefault;
cfg = config.services.tautulli;
access = config.services.nginx.access.tautulli;
proxyPass = mkDefault "https://${access.host}:${toString access.port}";
locations = {
"/" = {
inherit proxyPass;
};
};
in {
options.services.nginx.access.tautulli = with lib.types; {
host = mkOption {
type = str;
};
domain = mkOption {
type = str;
default = "tautulli.${config.networking.domain}";
};
port = mkOption {
type = port;
};
};
config.services.nginx = {
access.tautulli = mkIf cfg.enable {
host = mkOptionDefault "localhost";
port = mkOptionDefault cfg.port;
};
virtualHosts = {
${access.domain} = {
inherit locations;
};
};
};
}

View file

@ -1,12 +1,11 @@
{config, ...}: { {
services = { lib,
bazarr = { ...
enable = true; }: let
listenPort = 6767; inherit (lib.modules) mkDefault;
}; in {
services.bazarr = {
nginx.virtualHosts."bazarr.gensokyo.zone" = { enable = mkDefault true;
locations."/".proxyPass = "http://localhost:${toString config.services.bazarr.listenPort}"; listenPort = mkDefault 6767;
};
}; };
} }

View file

@ -17,7 +17,7 @@ in {
declarative = mkDefault true; declarative = mkDefault true;
openFirewall = mkDefault true; openFirewall = mkDefault true;
web = { web = {
enable = true; enable = mkDefault true;
}; };
config = { config = {
max_upload_speed = 10.0; max_upload_speed = 10.0;
@ -27,7 +27,7 @@ in {
max_active_limit = 100; max_active_limit = 100;
max_active_downloading = 75; max_active_downloading = 75;
max_upload_slots_global = 25; max_upload_slots_global = 25;
max_active_seeding = 1; max_active_seeding = 8;
allow_remote = true; allow_remote = true;
daemon_port = 58846; daemon_port = 58846;
listen_ports = [6881 6889]; listen_ports = [6881 6889];
@ -37,24 +37,24 @@ in {
}; };
services.mediatomb.mediaDirectories = let services.mediatomb.mediaDirectories = let
downloadLocation = cfg.config.download_location or (cfg.dataDir + "/Downloads"); inherit (cfg) downloadDir completedDir;
parent = builtins.dirOf downloadLocation; parent = builtins.dirOf downloadDir;
hasCompletedSubdir = cfg.config.move_completed or false && hasPrefix parent cfg.config.move_completed_path; hasCompletedSubdir = completedDir != null && hasPrefix parent completedDir;
completedSubdir = removePrefix parent cfg.config.move_completed_path; completedSubdir = removePrefix parent completedDir;
downloadDir = if hasCompletedSubdir then { download = if hasCompletedSubdir then {
path = parent; path = parent;
subdirectories = [ subdirectories = [
(builtins.baseNameOf downloadLocation) (builtins.baseNameOf downloadDir)
completedSubdir completedSubdir
]; ];
} else { } else {
path = downloadLocation; path = downloadDir;
}; };
completedDir = { completed = {
path = cfg.config.move_completed_path; path = cfg.config.move_completed_path;
}; };
in mkIf cfg.enable (mkAfter [ in mkIf cfg.enable (mkAfter [
downloadDir download
(mkIf (cfg.config.move_completed or false && !hasCompletedSubdir) completedDir) (mkIf (completedDir != null && !hasCompletedSubdir) completed)
]); ]);
} }

View file

@ -1,11 +1,5 @@
_: { _: {
services = { services.jackett = {
jackett = { enable = true;
enable = true;
};
nginx.virtualHosts."jackett.gensokyo.zone" = {
locations."/".proxyPass = "http://localhost:9117/";
};
}; };
# Port 9117
} }

View file

@ -1,11 +1,11 @@
{config, ...}: { {
services = { lib,
ombi = { ...
enable = true; }: let
port = 5000; inherit (lib.modules) mkDefault;
}; in {
nginx.virtualHosts."ombi.gensokyo.zone" = { services.ombi = {
locations."/".proxyPass = "http://localhost:${toString config.services.ombi.port}"; enable = mkDefault true;
}; port = mkDefault 5000;
}; };
} }

View file

@ -1,12 +1,5 @@
_: { _: {
services = { services.radarr = {
radarr = { enable = true;
enable = true;
};
nginx.virtualHosts."radarr.gensokyo.zone" = {
locations."/".proxyPass = "http://localhost:7878";
};
}; };
# Port 7878
} }

View file

@ -1,13 +1,5 @@
_: { _: {
services = { services.sonarr = {
sonarr = { enable = true;
enable = true;
};
nginx.virtualHosts."sonarr.gensokyo.zone" = {
locations."/".proxyPass = "http://localhost:8989";
};
}; };
# Port 8989
} }

View file

@ -1,20 +1,8 @@
{config, lib, ...}: let {lib, ...}: let
inherit (lib.modules) mkIf; inherit (lib.modules) mkDefault;
cfg = config.services.tautulli;
in { in {
services = { services.tautulli = {
tautulli = { enable = mkDefault true;
enable = true; port = mkDefault 8181;
port = 8181;
};
nginx.virtualHosts = {
"tautulli.${config.networking.domain}" = {
locations."/".proxyPass = "http://localhost:${toString cfg.port}";
};
"tautulli.local.${config.networking.domain}" = mkIf cfg.openFirewall {
locations."/".proxyPass = "http://localhost:${toString cfg.port}";
};
};
}; };
} }

View file

@ -4,8 +4,23 @@
lib, lib,
pkgs, pkgs,
... ...
}: { }: let
imports = with meta; [ inherit (lib.modules) mkIf mkMerge;
inherit (lib.attrsets) mapAttrs mapAttrsToList;
inherit (lib.strings) removePrefix;
inherit (config.services) deluge plex tautulli ombi sonarr radarr bazarr jackett cloudflared;
kyuuto = "/mnt/kyuuto-media";
kyuuto-library = kyuuto + "/library";
plexLibrary = {
"/mnt/Anime".hostPath = kyuuto-library + "/anime";
"/mnt/Shows".hostPath = kyuuto-library + "/tv";
"/mnt/Movies".hostPath = kyuuto-library + "/movies";
"/mnt/Music".hostPath = kyuuto-library + "/music";
};
in {
imports = let
inherit (meta) nixos;
in [
nixos.reisen-ct nixos.reisen-ct
nixos.sops nixos.sops
nixos.nginx nixos.nginx
@ -27,7 +42,7 @@
]; ];
sops.secrets.cloudflare_mediabox_tunnel = { sops.secrets.cloudflare_mediabox_tunnel = {
owner = config.services.cloudflared.user; owner = cloudflared.user;
}; };
services.cloudflared = let services.cloudflared = let
@ -37,33 +52,34 @@
default = "http_status:404"; default = "http_status:404";
credentialsFile = config.sops.secrets.cloudflare_mediabox_tunnel.path; credentialsFile = config.sops.secrets.cloudflare_mediabox_tunnel.path;
ingress = { ingress = {
"tautulli.gensokyo.zone".service = "http://localhost:${toString config.services.tautulli.port}"; "tautulli.gensokyo.zone".service = "http://localhost:${toString tautulli.port}";
"ombi.gensokyo.zone".service = "http://localhost:${toString config.services.ombi.port}"; "ombi.gensokyo.zone".service = "http://localhost:${toString ombi.port}";
"sonarr.gensokyo.zone".service = "http://localhost:8989"; "sonarr.gensokyo.zone".service = "http://localhost:${toString sonarr.port}";
"radarr.gensokyo.zone".service = "http://localhost:7878"; "radarr.gensokyo.zone".service = "http://localhost:${toString radarr.port}";
"bazarr.gensokyo.zone".service = "http://localhost:6767"; "bazarr.gensokyo.zone".service = "http://localhost:${toString bazarr.listenPort}";
"jackett.gensokyo.zone".service = "http://localhost:9117"; "jackett.gensokyo.zone".service = "http://localhost:${toString jackett.port}";
"deluge.gensokyo.zone".service = "http://localhost:${toString config.services.deluge.web.port}"; "deluge.gensokyo.zone".service = "http://localhost:${toString deluge.web.port}";
}; };
}; };
}; };
services.mediatomb = { services.mediatomb = {
serverName = "tewi"; serverName = "tewi";
mediaDirectories = [ mediaDirectories = let
rec { mkLibraryDir = dir: {
path = "/mnt/Anime"; path = kyuuto-library + "/${dir}";
mountPoint = path; mountPoint = kyuuto-library;
} };
rec { libraryDir = {
path = "/mnt/Shows"; path = kyuuto-library;
mountPoint = path; mountPoint = kyuuto-library;
} subdirectories =
rec { mapAttrsToList (_: { hostPath, ... }:
path = "/mnt/Movies"; removePrefix "${kyuuto-library}/" hostPath
mountPoint = path; ) plexLibrary
} ++ [ "tlmc" "music-raw" ];
]; };
in [ libraryDir ] ++ map mkLibraryDir [ "tlmc" "music-raw" "lewd" ];
}; };
hardware.opengl = { hardware.opengl = {
@ -71,6 +87,36 @@
extraPackages = with pkgs; [ mesa.drivers vaapiVdpau libvdpau-va-gl ]; extraPackages = with pkgs; [ mesa.drivers vaapiVdpau libvdpau-va-gl ];
}; };
fileSystems = let
bind = {
fsType = "none";
options = [ "bind" "nofail" ];
};
fsPlex = mapAttrs (_: { hostPath, ... }: mkMerge [
bind
{
device = hostPath;
}
]) plexLibrary;
fsDeluge = {
"${deluge.downloadDir}" = mkIf deluge.enable (mkMerge [ bind {
device = kyuuto + "/downloads/deluge/download";
} ]);
};
in mkMerge [
fsPlex
(mkIf deluge.enable fsDeluge)
];
systemd.services.deluged = mkIf deluge.enable {
unitConfig.RequiresMountsFor = [
"${deluge.downloadDir}"
];
};
systemd.services.plex = mkIf plex.enable {
unitConfig.RequiresMountsFor = mapAttrsToList (path: _: path) plexLibrary;
};
systemd.network.networks.eth0 = { systemd.network.networks.eth0 = {
name = "eth0"; name = "eth0";
matchConfig = { matchConfig = {