mirror of
https://github.com/gensokyo-zone/infrastructure.git
synced 2026-02-09 12:29:19 -08:00
fix(backups): plex
This commit is contained in:
parent
a202d0703f
commit
75dc495709
3 changed files with 73 additions and 48 deletions
|
|
@ -1,10 +1,11 @@
|
||||||
{config, systemConfig, lib, ...}: let
|
{pkgs, config, systemConfig, lib, ...}: let
|
||||||
inherit (lib.modules) mkIf mkMerge mkDefault;
|
inherit (lib.modules) mkIf mkMerge mkDefault;
|
||||||
inherit (lib.attrsets) mapAttrs' mapAttrsToList nameValuePair;
|
inherit (lib.attrsets) mapAttrs' mapAttrsToList nameValuePair;
|
||||||
inherit (lib.lists) concatMap;
|
inherit (lib.lists) concatMap toList;
|
||||||
inherit (lib.strings) replaceStrings;
|
inherit (lib.strings) replaceStrings concatMapStringsSep;
|
||||||
inherit (config.sops.secrets) restic-shared-repo-b2 restic-shared-password restic-shared-env-b2;
|
inherit (config.sops.secrets) restic-shared-repo-b2 restic-shared-password restic-shared-env-b2;
|
||||||
group = "backups";
|
group = "backups";
|
||||||
|
mkSharedPath = subpath: "/mnt/shared/${subpath}";
|
||||||
# TODO: this properly as a module or something
|
# TODO: this properly as a module or something
|
||||||
sharedServices = {
|
sharedServices = {
|
||||||
hass.config = config.services.home-assistant;
|
hass.config = config.services.home-assistant;
|
||||||
|
|
@ -13,11 +14,27 @@
|
||||||
kanidm = {
|
kanidm = {
|
||||||
config = config.services.kanidm;
|
config = config.services.kanidm;
|
||||||
enable = config.services.kanidm.enableServer;
|
enable = config.services.kanidm.enableServer;
|
||||||
|
subpath = "kanidm/kanidm.db";
|
||||||
};
|
};
|
||||||
mosquitto.config = config.services.mosquitto;
|
mosquitto.config = config.services.mosquitto;
|
||||||
plex = {
|
plex = {
|
||||||
config = config.services.plex;
|
config = config.services.plex;
|
||||||
compression = "auto";
|
compression = "auto";
|
||||||
|
subpath = [
|
||||||
|
"plex/Plex Media Server/Preferences.xml"
|
||||||
|
#"plex/Databases" # omitted, see dynamicFilesFrom to select only the latest backup...
|
||||||
|
];
|
||||||
|
settings = {
|
||||||
|
dynamicFilesFrom = let
|
||||||
|
databases = [
|
||||||
|
"com.plexapp.plugins.library.blobs.db"
|
||||||
|
"com.plexapp.plugins.library.db"
|
||||||
|
];
|
||||||
|
ls = "${pkgs.coreutils}/bin/ls";
|
||||||
|
tail = "${pkgs.coreutils}/bin/tail";
|
||||||
|
mkLatestDb = database: ''${ls} ${mkSharedPath "plex/Databases/${database}"}* | ${tail} -n1'';
|
||||||
|
in concatMapStringsSep " &&\n" mkLatestDb databases;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
postgresql = {
|
postgresql = {
|
||||||
# TODO: synchronize with postgresqlBackup service via flock or After=
|
# TODO: synchronize with postgresqlBackup service via flock or After=
|
||||||
|
|
@ -40,31 +57,31 @@
|
||||||
in {
|
in {
|
||||||
services.restic.backups = let
|
services.restic.backups = let
|
||||||
isBackup = config.networking.hostName == "hakurei";
|
isBackup = config.networking.hostName == "hakurei";
|
||||||
mkSharedPath = subpath: "/mnt/shared/${subpath}";
|
mkBackupB2 = name: subpath': { config, enable ? config.enable, user ? config.user or null, subpath ? subpath', compression ? "max", settings ? {} }: let
|
||||||
mkBackupB2 = name: subpath': { config, enable ? config.enable, user ? config.user or null, subpath ? subpath', path ? mkSharedPath subpath, compression ? "max" }: let
|
|
||||||
tags = [
|
tags = [
|
||||||
"infra"
|
"infra"
|
||||||
"shared-${name}"
|
"shared-${name}"
|
||||||
"system-${systemConfig.name}"
|
"system-${systemConfig.name}"
|
||||||
];
|
];
|
||||||
in mkIf (enable || isBackup) {
|
conf = {
|
||||||
user = mkIf (enable && user != null) user;
|
user = mkIf (enable && user != null) user;
|
||||||
repositoryFile = restic-shared-repo-b2.path;
|
repositoryFile = restic-shared-repo-b2.path;
|
||||||
passwordFile = restic-shared-password.path;
|
passwordFile = restic-shared-password.path;
|
||||||
environmentFile = restic-shared-env-b2.path;
|
environmentFile = restic-shared-env-b2.path;
|
||||||
paths = [path];
|
paths = map mkSharedPath (toList subpath);
|
||||||
extraBackupArgs = mkMerge [
|
extraBackupArgs = mkMerge [
|
||||||
(mkIf (compression != "auto") [
|
(mkIf (compression != "auto") [
|
||||||
"--compression" compression
|
"--compression" compression
|
||||||
])
|
])
|
||||||
(concatMap (tag: ["--tag" tag]) tags)
|
(concatMap (tag: ["--tag" tag]) tags)
|
||||||
];
|
];
|
||||||
timerConfig = {
|
timerConfig = {
|
||||||
OnCalendar = "03:30";
|
OnCalendar = "03:30";
|
||||||
Persistent = true;
|
Persistent = true;
|
||||||
RandomizedDelaySec = "4h";
|
RandomizedDelaySec = "4h";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
in mkIf (enable || isBackup) (mkMerge [ conf settings ]);
|
||||||
backups = mapAttrs' (subpath: service: let
|
backups = mapAttrs' (subpath: service: let
|
||||||
name = replaceStrings [ "/" ] [ "-" ] subpath;
|
name = replaceStrings [ "/" ] [ "-" ] subpath;
|
||||||
in nameValuePair "${name}-b2" (mkBackupB2 name subpath service)) sharedServices;
|
in nameValuePair "${name}-b2" (mkBackupB2 name subpath service)) sharedServices;
|
||||||
|
|
|
||||||
|
|
@ -5,38 +5,50 @@
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
inherit (lib.modules) mkIf mkForce mkDefault;
|
inherit (lib.modules) mkIf mkForce mkDefault;
|
||||||
inherit (lib.strings) escapeShellArg;
|
inherit (lib.attrsets) mapAttrs' filterAttrs mapAttrsToList nameValuePair;
|
||||||
|
inherit (lib.strings) escapeShellArg concatStringsSep;
|
||||||
cfg = config.services.plex;
|
cfg = config.services.plex;
|
||||||
|
plexCaches = {
|
||||||
|
mesa_shader_cache.path = null;
|
||||||
|
Cache = {};
|
||||||
|
Logs = {};
|
||||||
|
CrashReports.subpath = "Crash Reports";
|
||||||
|
Diagnostics = {};
|
||||||
|
Drivers = {};
|
||||||
|
Codecs = {};
|
||||||
|
Scanners = {};
|
||||||
|
Updates = {};
|
||||||
|
Caches.subpath = "Plug-in Support/Caches";
|
||||||
|
};
|
||||||
in {
|
in {
|
||||||
services.plex.enable = mkDefault true;
|
services.plex.enable = mkDefault true;
|
||||||
systemd.services.plex = mkIf cfg.enable {
|
systemd.services.plex = mkIf cfg.enable {
|
||||||
gensokyo-zone = {
|
gensokyo-zone = {
|
||||||
sharedMounts.plex.path = mkDefault cfg.dataDir;
|
sharedMounts.plex.path = mkDefault cfg.dataDir;
|
||||||
cacheMounts = {
|
cacheMounts = mapAttrs' (name: _: nameValuePair "plex/${name}" {
|
||||||
"plex/Cache" = {
|
path = mkDefault "${cfg.dataDir}/${name}";
|
||||||
path = mkDefault "${cfg.dataDir}/Cache";
|
}) plexCaches;
|
||||||
};
|
|
||||||
"plex/Logs" = {
|
|
||||||
path = mkDefault "${cfg.dataDir}/Logs";
|
|
||||||
};
|
|
||||||
"plex/mesa_shader_cache" = {
|
|
||||||
path = mkDefault "${cfg.dataDir}/mesa_shader_cache";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
# /var/lib/plex/mesa_shader_cache
|
# /var/lib/plex/mesa_shader_cache
|
||||||
environment.MESA_SHADER_CACHE_DIR = mkDefault cfg.dataDir;
|
environment.MESA_SHADER_CACHE_DIR = mkDefault cfg.dataDir;
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
ExecStartPre = let
|
ExecStartPre = let
|
||||||
|
ln = "${pkgs.coreutils}/bin/ln";
|
||||||
|
install = "${pkgs.coreutils}/bin/install";
|
||||||
# systemd doesn't seem to like spaces so use a symlink instead...
|
# systemd doesn't seem to like spaces so use a symlink instead...
|
||||||
|
mkCacheSetup = name: { path ? "Plex Media Server/${subpath}", subpath ? name }:
|
||||||
|
''${ln} -srfT "$PLEX_DATADIR/"${escapeShellArg name} "$PLEX_DATADIR/"${escapeShellArg path}'';
|
||||||
|
cacheSetup = mapAttrsToList mkCacheSetup (filterAttrs (_: cache: cache.path or "" != null) plexCaches);
|
||||||
preStartScript = pkgs.writeShellScript "plex-run-prestart" ''
|
preStartScript = pkgs.writeShellScript "plex-run-prestart" ''
|
||||||
set -eu
|
set -eu
|
||||||
|
|
||||||
if [[ ! -d $PLEX_DATADIR ]]; then
|
if [[ ! -d $PLEX_DATADIR ]]; then
|
||||||
${pkgs.coreutils}/bin/install -d -m 0755 -o ${escapeShellArg cfg.user} -g ${escapeShellArg cfg.group} "$PLEX_DATADIR/Plex Media Server"
|
${install} -d -m 0755 -o ${escapeShellArg cfg.user} -g ${escapeShellArg cfg.group} "$PLEX_DATADIR/Plex Media Server"
|
||||||
fi
|
fi
|
||||||
${pkgs.coreutils}/bin/ln -sfT ../Cache "$PLEX_DATADIR/Plex Media Server/Cache"
|
if [[ ! -d $PLEX_DATADIR/Databases ]]; then
|
||||||
${pkgs.coreutils}/bin/ln -sfT ../Logs "$PLEX_DATADIR/Plex Media Server/Logs"
|
${install} -d -m 0755 -o ${escapeShellArg cfg.user} -g ${escapeShellArg cfg.group} "$PLEX_DATADIR/Databases"
|
||||||
|
fi
|
||||||
|
${concatStringsSep "\n" cacheSetup}
|
||||||
'';
|
'';
|
||||||
in
|
in
|
||||||
mkForce [
|
mkForce [
|
||||||
|
|
|
||||||
|
|
@ -162,20 +162,16 @@ mkcache zigbee2mqtt 100317 100317 0700
|
||||||
mkcache taskchampion 100917 100917 0750
|
mkcache taskchampion 100917 100917 0750
|
||||||
mkcache minecraft 100913 100913 0750
|
mkcache minecraft 100913 100913 0750
|
||||||
mkcache plex 0 0 0755
|
mkcache plex 0 0 0755
|
||||||
if [[ ! -d /rpool/caches/plex/Cache ]]; then
|
for plexcache in Logs CrashReports Diagnostics Cache Caches Drivers Codecs Scanners Updates mesa_shader_cache; do
|
||||||
mkdir /rpool/caches/plex/Cache
|
if [[ ! -d /rpool/caches/plex/$plexcache ]]; then
|
||||||
fi
|
mkdir /rpool/caches/plex/$plexcache
|
||||||
if [[ ! -d /rpool/caches/plex/Logs ]]; then
|
fi
|
||||||
mkdir /rpool/caches/plex/Logs
|
chown 100193:100193 /rpool/caches/plex/$plexcache
|
||||||
fi
|
chmod 0775 /rpool/caches/plex/$plexcache
|
||||||
if [[ ! -d /rpool/caches/plex/mesa_shader_cache ]]; then
|
done
|
||||||
mkdir /rpool/caches/plex/mesa_shader_cache
|
|
||||||
fi
|
|
||||||
if [[ ! -d /rpool/caches/plex/tautulli/cache ]]; then
|
if [[ ! -d /rpool/caches/plex/tautulli/cache ]]; then
|
||||||
mkdir -p /rpool/caches/plex/tautulli/cache
|
mkdir -p /rpool/caches/plex/tautulli/cache
|
||||||
fi
|
fi
|
||||||
chown 100193:100193 /rpool/caches/plex/{Cache,Logs,mesa_shader_cache}
|
|
||||||
chmod 0775 /rpool/caches/plex/{Cache,Logs,mesa_shader_cache}
|
|
||||||
chown 100195:65534 /rpool/caches/plex/tautulli/cache
|
chown 100195:65534 /rpool/caches/plex/tautulli/cache
|
||||||
chmod 0755 /rpool/caches/plex/tautulli/cache
|
chmod 0755 /rpool/caches/plex/tautulli/cache
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue