fix(backups): plex

This commit is contained in:
arcnmx 2024-10-02 19:43:48 -07:00
parent a202d0703f
commit 75dc495709
3 changed files with 73 additions and 48 deletions

View file

@ -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;

View file

@ -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 [

View file

@ -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