feat(media): migrer la bibliothèque partagée vers /srv/media (dataset ZFS dédié)
/home/marc/media posait deux problèmes : /home/marc est 0700 (chaque service
devait recevoir un droit de traversée) et systemd-tmpfiles refuse de créer
quoi que ce soit sous /home/marc (« unsafe path transition », exit 73).
- services/media (nouveau) : dataset nixos/media -> /srv/media, groupe media
(setgid, dossiers 2775/2770), arborescence movies/tvshows/music/books/downloads
- disko.nix : dataset media à côté de marc/nix
- navidrome, jellyfin, kodi : bibliothèque -> /srv/media/{music,movies,tvshows}
- qbittorrent : téléchargements dans le même dataset que la bibliothèque
(permet aux *arr d'importer par lien dur au lieu de copier)
- radarr : dataDir corrigé (pointait sur celui de sonarr par copier-coller),
déplacé hors /home (impossible avec ProtectHome+tmpfiles du module)
- sonarr : dataDir dédié + migration depuis /home/marc/radarr (était figé
depuis le 28/07, port 8006 muet) ; réparé le 27/09/2026
- readarr : bibliothèque -> /srv/media/books
This commit is contained in:
@@ -65,6 +65,13 @@
|
||||
options.mountpoint = "/nix";
|
||||
mountpoint = "/nix";
|
||||
};
|
||||
# Média partagé (Jellyfin, Navidrome, Radarr, Sonarr, Nextcloud) :
|
||||
# groupe `media` + dossiers setgid, hors des homes pour que
|
||||
# systemd-tmpfiles puisse y créer les dossiers (voir services/media).
|
||||
"media" = {
|
||||
type = "zfs_fs";
|
||||
options.mountpoint = "/srv/media";
|
||||
};
|
||||
"marc" = {
|
||||
type = "zfs_fs";
|
||||
options.mountpoint = "none";
|
||||
|
||||
@@ -16,12 +16,12 @@ in {
|
||||
sources.video = [
|
||||
{
|
||||
name = "movies";
|
||||
path = "${homeDir}/media/movies/";
|
||||
path = "/srv/media/movies/";
|
||||
# 'allowsharing = true;' partage upnp
|
||||
}
|
||||
{
|
||||
name = "tvshows";
|
||||
path = "${homeDir}/media/tvshows/";
|
||||
path = "/srv/media/tvshows/";
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
@@ -38,37 +38,17 @@
|
||||
};
|
||||
};
|
||||
|
||||
# /home/marc n'est traversable (bit x) que par son groupe propriétaire : sans
|
||||
# `users` en groupe secondaire, l'utilisateur jellyfin ne peut pas atteindre
|
||||
# /home/marc/media (le dossier lui-même est en 0755 root:root, donc lisible).
|
||||
users.users.jellyfin.extraGroups = [ "users" ];
|
||||
|
||||
# Bibliothèques : mêmes dossiers que les sources vidéo de Kodi, plus la
|
||||
# musique déjà servie par Navidrome. Jellyfin ne sait pas ajouter de
|
||||
# bibliothèque de façon déclarative, ces dossiers ne sont que les racines à
|
||||
# sélectionner dans l'assistant web (Bibliothèques > Ajouter).
|
||||
# Les bibliothèques vivent dans /srv/media (groupe `media`, dossiers setgid,
|
||||
# créés par systemd-tmpfiles : cf. services/media). Ne PAS les mettre sous
|
||||
# /home/marc : systemd-tmpfiles refuse de créer un dossier là-bas
|
||||
# (« unsafe path transition », exit 73) et tout service devrait recevoir un
|
||||
# droit de traversée sur un home en 0700. Les racines à sélectionner dans
|
||||
# l'assistant web sont : /srv/media/movies, /srv/media/tvshows, /srv/media/music.
|
||||
#
|
||||
# Pourquoi un oneshot et pas systemd.tmpfiles.rules : systemd-tmpfiles refuse
|
||||
# de descendre dans /home/marc (0700, appartient à marc) pour y créer un
|
||||
# dossier, et sort en "Detected unsafe path transition /home/marc (owned by
|
||||
# marc) -> /home/marc/media (owned by root)" puis CANTCREAT (exit 73) à
|
||||
# chaque activation : les règles ne s'appliquent jamais et le journal se
|
||||
# remplit d'avertissements. Vérifié le 26/09/2026 en instrumentant
|
||||
# l'activation : la même création faite par root en direct (mkdir) réussit.
|
||||
# D'où ce oneshot, qui tourne en root sans cette vérification de sécurité.
|
||||
systemd.services.jellyfin-media-dirs = {
|
||||
description = "Création des dossiers de bibliothèque média (Jellyfin, Navidrome)";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
before = [ "jellyfin.service" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
script = ''
|
||||
${pkgs.coreutils}/bin/install -d -o marc -g users -m 0755 \
|
||||
/home/marc/media/movies /home/marc/media/tvshows /home/marc/media/music
|
||||
'';
|
||||
};
|
||||
# UMask : le module impose 0077. Le média est partagé, donc les fichiers que
|
||||
# Jellyfin écrit dans la bibliothèque (pochettes, NFO s'ils sont activés)
|
||||
# doivent rester lisibles et modifiables par les autres membres du groupe.
|
||||
systemd.services.jellyfin.serviceConfig.UMask = lib.mkForce "0002";
|
||||
|
||||
# Exposition publique via Pangolin (newt, site "tower") : jellyfin.marcpartensky.com
|
||||
# -> 127.0.0.1:8096. `site` omis : Pangolin affecte le site qui applique le
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
# Média partagé : /srv/media (dataset ZFS nixos/media) + groupe `media`.
|
||||
#
|
||||
# Pourquoi pas /home/marc/media (ancien emplacement) :
|
||||
# - /home/marc est en 0700, donc chaque service devait recevoir un droit de
|
||||
# traversée explicite (ajout au groupe `users`) pour lire /home/marc/media ;
|
||||
# - systemd-tmpfiles REFUSE de créer quoi que ce soit sous /home/marc
|
||||
# (« Detected unsafe path transition », exit 73) : les règles ne
|
||||
# s'appliquaient jamais et il fallait un oneshot root (cf. services/jellyfin).
|
||||
# Hors /home, les deux problèmes disparaissent : les dossiers sont déclaratifs et
|
||||
# les services n'ont plus besoin de traverser le home de marc.
|
||||
#
|
||||
# Modèle de droits : un seul groupe `media`, dossiers en 2775 (setgid, donc les
|
||||
# fichiers créés héritent du groupe `media`) et UMask=0002 posé sur chaque
|
||||
# service qui écrit (cf. les modules concernés) pour que ses fichiers restent
|
||||
# modifiables par les autres membres. Nextcloud écrit en 0644 (son umask), donc
|
||||
# lisible par Jellyfin mais pas modifiable par les *arr : suffisant, ils ne
|
||||
# réécrivent pas ses fichiers.
|
||||
let
|
||||
mediaRoot = "/srv/media";
|
||||
in {
|
||||
users.groups.media = { };
|
||||
|
||||
users.users.marc.extraGroups = [ "media" ];
|
||||
users.users.jellyfin.extraGroups = [ "media" ];
|
||||
users.users.navidrome.extraGroups = [ "media" ];
|
||||
users.users.qbittorrent.extraGroups = [ "media" ];
|
||||
users.users.nextcloud.extraGroups = [ "media" ];
|
||||
|
||||
# Création du dataset, une seule fois : l'activation tourne en root, et ZFS
|
||||
# monte ensuite le dataset tout seul à chaque boot (propriété mountpoint).
|
||||
# Idempotent : ne recrée rien si nixos/media existe déjà.
|
||||
systemd.services.media-dataset = {
|
||||
description = "Création du dataset ZFS du média partagé (nixos/media -> ${mediaRoot})";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
unitConfig.ConditionPathExists = "!${mediaRoot}";
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
script = ''
|
||||
ZFS=${config.boot.zfs.package}/bin/zfs
|
||||
if ! $ZFS list -H -o name nixos/media >/dev/null 2>&1; then
|
||||
$ZFS create -o mountpoint=${mediaRoot} nixos/media
|
||||
fi
|
||||
$ZFS set mountpoint=${mediaRoot} nixos/media || true
|
||||
${pkgs.util-linux}/bin/mountpoint -q ${mediaRoot} || $ZFS mount nixos/media || true
|
||||
|
||||
# L'arbre est aussi créé ici : au premier démarrage, systemd-tmpfiles
|
||||
# tourne avant le montage du dataset et ses dossiers seraient masqués.
|
||||
${pkgs.coreutils}/bin/install -d -o root -g media -m 2755 ${mediaRoot}
|
||||
for d in movies tvshows music books; do
|
||||
${pkgs.coreutils}/bin/install -d -o root -g media -m 2775 "${mediaRoot}/$d"
|
||||
done
|
||||
${pkgs.coreutils}/bin/install -d -o root -g media -m 2770 ${mediaRoot}/downloads
|
||||
for d in radarr sonarr readarr incomplete; do
|
||||
${pkgs.coreutils}/bin/install -d -o root -g media -m 2770 "${mediaRoot}/downloads/$d"
|
||||
done
|
||||
'';
|
||||
};
|
||||
|
||||
# Bibliothèque (lue par Jellyfin, Navidrome et Kodi, écrite par les *arr) et
|
||||
# zone de téléchargement (clients + imports). Les deux sont dans le MÊME
|
||||
# dataset : c'est ce qui permet aux *arr d'importer par lien dur au lieu de
|
||||
# copier, et donc de laisser qBittorrent seeder sans doubler l'espace.
|
||||
# `books` par symétrie avec Readarr. Les téléchargements sont en 2770 : les
|
||||
# torrents en cours n'ont pas besoin d'être lisibles par tout le monde.
|
||||
systemd.tmpfiles.rules =
|
||||
[ "d ${mediaRoot} 2755 root media -" ]
|
||||
++ map (d: "d ${mediaRoot}/${d} 2775 root media -") [ "movies" "tvshows" "music" "books" ]
|
||||
++ [ "d ${mediaRoot}/downloads 2770 root media -" ]
|
||||
++ map (d: "d ${mediaRoot}/downloads/${d} 2770 root media -") [ "radarr" "sonarr" "readarr" "incomplete" ];
|
||||
}
|
||||
@@ -1,4 +1,9 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
|
||||
{
|
||||
services.navidrome = {
|
||||
@@ -6,7 +11,11 @@
|
||||
settings = {
|
||||
Address = "0.0.0.0";
|
||||
Port = 4533;
|
||||
MusicFolder = "/home/marc/media/music";
|
||||
# Média partagé : /srv/media/music (groupe `media`, cf. services/media),
|
||||
# et non plus /home/marc/media/music qui obligeait à donner à navidrome un
|
||||
# droit de traversée sur le home de marc (0700) et le faisait scanner une
|
||||
# bibliothèque vide.
|
||||
MusicFolder = "/srv/media/music";
|
||||
# DataFolder = "/var/lib/navidrome/data";
|
||||
LogLevel = "info";
|
||||
ScanSchedule = "@every 1h";
|
||||
@@ -22,15 +31,11 @@
|
||||
LockPersonality = true;
|
||||
PrivateDevices = true;
|
||||
RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ];
|
||||
ProtectHome = lib.mkForce "read-only";
|
||||
BindPaths = [ "/home/marc/media/music" ];
|
||||
# La musique n'est plus dans /home : plus besoin de BindPaths ni de
|
||||
# traverser le home, le durcissement du module peut rester actif.
|
||||
ProtectHome = lib.mkForce true;
|
||||
};
|
||||
};
|
||||
|
||||
# /home/marc n'est traversable que par son groupe propriétaire (other::---) :
|
||||
# sans `users` en groupe secondaire, l'utilisateur navidrome ne peut pas
|
||||
# atteindre /home/marc/media/music et scanne une bibliothèque vide.
|
||||
users.users.navidrome.extraGroups = [ "users" ];
|
||||
|
||||
# networking.firewall.allowedTCPPorts = [ 4533 ];
|
||||
}
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
{pkgs, ...}: {
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
# configuration.nix
|
||||
services.qbittorrent = {
|
||||
enable = true;
|
||||
@@ -6,6 +10,16 @@
|
||||
torrentingPort = 8085;
|
||||
serverConfig = {
|
||||
LegalNotice.Accepted = true; # Souvent nécessaire pour le démarrage
|
||||
# Média partagé (cf. services/media) : les torrents atterrissent dans le
|
||||
# MÊME dataset que la bibliothèque, ce qui permet aux *arr d'importer par
|
||||
# lien dur (Radarr/Sonarr) au lieu de recopier, et donc de laisser le
|
||||
# seed actif sans doubler l'espace disque. Les sous-dossiers par catégorie
|
||||
# (radarr/, sonarr/) sont créés par les *arr eux-mêmes.
|
||||
BitTorrent = {
|
||||
"Session\\DefaultSavePath" = "/srv/media/downloads";
|
||||
"Session\\TempPathEnabled" = "true";
|
||||
"Session\\TempPath" = "/srv/media/downloads/incomplete";
|
||||
};
|
||||
Preferences = {
|
||||
WebUI = {
|
||||
Username = "marc"; # Remplacez par le nom d'utilisateur souhaité
|
||||
@@ -18,4 +32,9 @@
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Média partagé : les fichiers en cours de téléchargement (puis à l'arrêt,
|
||||
# pour le seed) doivent rester lisibles et modifiables par les *arr et par
|
||||
# marc. Le module ne pose pas d'UMask, il est donc fixé ici.
|
||||
systemd.services.qbittorrent.serviceConfig.UMask = "0002";
|
||||
}
|
||||
|
||||
@@ -1,13 +1,31 @@
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
|
||||
# Radarr = le « Sonarr des films ». Il télécharge/renomme et dépose les films
|
||||
# dans une racine de bibliothèque, ici /srv/media/movies : le MÊME dossier que
|
||||
# la bibliothèque « Films » de Jellyfin. C'est ça, la connexion utile : Jellyfin
|
||||
# surveille le dossier en temps réel (surveillance activée par défaut sur un
|
||||
# stockage local), donc un film importé apparaît tout seul. Le « Connect »
|
||||
# Emby/Jellyfin de Radarr (URL + clé API Jellyfin) ne sert qu'à déclencher en
|
||||
# plus un rescan explicite à chaque import.
|
||||
{
|
||||
services.radarr = {
|
||||
enable = true;
|
||||
# openFirewall = true;
|
||||
user = "marc";
|
||||
group = "users";
|
||||
dataDir = "/home/marc/radarr";
|
||||
|
||||
# PIEGE 1 : ne PAS reprendre `dataDir = "/home/marc/radarr"` (valeur du
|
||||
# module sonarr, qui a été copiée-collée ici et là : Sonarr TOURNAIT avec
|
||||
# -data=/home/marc/radarr). Les deux partageraient le même dossier de config.
|
||||
# PIEGE 2 : un dataDir sous /home/marc est impossible pour Radarr : son
|
||||
# module pose ProtectHome=true et crée le dossier par systemd-tmpfiles, qui
|
||||
# REFUSE tout chemin sous /home/marc (cf. services/jellyfin, section
|
||||
# « unsafe path transition »). D'où ce dataDir hors /home.
|
||||
dataDir = "/var/lib/radarr/.config/Radarr";
|
||||
|
||||
settings = {
|
||||
# update.mechanism = "internal";
|
||||
server = {
|
||||
urlbase = "localhost";
|
||||
port = 8086;
|
||||
@@ -15,4 +33,41 @@
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Média partagé (cf. services/media) : UMask=0002 pour que les fichiers
|
||||
# importés soient modifiables par les autres membres du groupe `media`
|
||||
# (le module pose 0022 par défaut, d'où le mkForce).
|
||||
systemd.services.radarr.serviceConfig.UMask = lib.mkForce "0002";
|
||||
|
||||
# Exposition publique via Pangolin (newt, site "tower") : radarr.marcpartensky.com
|
||||
# -> 127.0.0.1:8086. `site` omis : Pangolin affecte le site qui applique le
|
||||
# blueprint. Cle `proxy-resources` + champ `protocol` = schema reellement
|
||||
# compris par le Pangolin du VPS (cf. commentaire detaille dans services/newt).
|
||||
#
|
||||
# SSO Pangolin ACTIVE (contrairement a Jellyfin, qui a besoin de ses clients
|
||||
# natifs) : le tunnel newt tape en local, donc Radarr voit les requetes
|
||||
# distantes comme locales (127.0.0.1) et sa propre auth
|
||||
# "DisabledForLocalAddresses" ne filtrerait RIEN. Sans SSO, l'UI complete et
|
||||
# l'API v3 (qui suffit a piloter Radarr) seraient ouvertes a Internet.
|
||||
services.newt.blueprint.proxy-resources.radarr = {
|
||||
name = "Radarr";
|
||||
protocol = "http";
|
||||
full-domain = "radarr.marcpartensky.com";
|
||||
auth.sso-enabled = true;
|
||||
targets = [
|
||||
{
|
||||
hostname = "127.0.0.1";
|
||||
port = 8086;
|
||||
method = "http";
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
# Plus de ProtectHome=false ici : depuis que le média est dans /srv/media,
|
||||
# Radarr ne touche plus du tout au home de marc (données dans
|
||||
# /var/lib/radarr, téléchargements et bibliothèque dans /srv), donc le
|
||||
# durcissement du module reste en place.
|
||||
|
||||
# Pas d'openFirewall : comme les autres *arr, Radarr reste joignable
|
||||
# uniquement depuis la machine (et par le tunnel/SSO si on l'expose un jour).
|
||||
}
|
||||
@@ -1,4 +1,12 @@
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
# Readarr = livres. Son dossier de données est sous /home (comme Sonarr) et son
|
||||
# module ne masque pas /home, donc il fonctionne tel quel (vérifié : service
|
||||
# actif, port 8088 répond 200). Seule la bibliothèque change : /srv/media/books
|
||||
# (groupe `media`, cf. services/media), à sélectionner dans l'UI.
|
||||
{
|
||||
services.readarr = {
|
||||
enable = true;
|
||||
@@ -14,4 +22,8 @@
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Média partagé : les fichiers importés doivent rester modifiables par les
|
||||
# autres membres du groupe `media`.
|
||||
systemd.services.readarr.serviceConfig.UMask = lib.mkForce "0002";
|
||||
}
|
||||
|
||||
@@ -1,13 +1,24 @@
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
# Sonarr = séries TV. Le module nixpkgs pose deux valeurs incompatibles avec un
|
||||
# dataDir sous /home : ProtectHome=true (le service ne verrait pas /home) et la
|
||||
# création du dossier par systemd-tmpfiles, qui refuse tout chemin sous
|
||||
# /home/marc (« unsafe path transition », cf. services/jellyfin).
|
||||
# Historiquement ce module pointait sur /home/marc/radarr (copier-coller depuis
|
||||
# le module radarr), donc Sonarr tournait sans pouvoir lire ni écrire sa
|
||||
# configuration : le dossier était figé au 28/07/2026 et son port 8006 ne
|
||||
# répondait plus. Réparé le 27/09/2026 : dossier dédié + migration des données.
|
||||
{
|
||||
services.sonarr = {
|
||||
enable = true;
|
||||
# openFirewall = true;
|
||||
user = "marc";
|
||||
group = "users";
|
||||
dataDir = "/home/marc/radarr";
|
||||
dataDir = "/home/marc/sonarr";
|
||||
settings = {
|
||||
# update.mechanism = "internal";
|
||||
server = {
|
||||
urlbase = "localhost";
|
||||
port = 8006;
|
||||
@@ -15,4 +26,62 @@
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.sonarr.serviceConfig.ProtectHome = lib.mkForce false;
|
||||
|
||||
# Média partagé (cf. services/media) : rend les fichiers importés modifiables
|
||||
# par les autres membres du groupe `media`.
|
||||
systemd.services.sonarr.serviceConfig.UMask = lib.mkForce "0002";
|
||||
|
||||
# La règle tmpfiles du module viserait /home/marc/sonarr, que
|
||||
# systemd-tmpfiles refuserait de créer et signalerait à chaque activation :
|
||||
# supprimée, le dossier est créé par la migration ci-dessous.
|
||||
systemd.tmpfiles.settings."10-sonarr" = lib.mkForce { };
|
||||
|
||||
# Migration en une fois : Sonarr était configuré dans /home/marc/radarr (qui
|
||||
# contient AUSSI radarr.db, reste d'un ancien Radarr, laissé en place). On ne
|
||||
# copie que les données de Sonarr, pas config.xml : il est régénéré depuis les
|
||||
# réglages Nix ci-dessus (port 8006, urlbase localhost), alors que celui du
|
||||
# dossier partagé portait la config du dernier service qui l'avait écrit.
|
||||
systemd.services.sonarr-data-migrate = {
|
||||
description = "Migration du dossier de données de Sonarr (~/radarr -> ~/sonarr)";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
before = [ "sonarr.service" ];
|
||||
unitConfig.ConditionPathExists = "!/home/marc/sonarr/.migration-done";
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
script = ''
|
||||
set -eu
|
||||
${pkgs.coreutils}/bin/install -d -o marc -g users -m 0700 /home/marc/sonarr
|
||||
for f in sonarr.db sonarr.db-shm sonarr.db-wal logs.db logs.db-shm logs.db-wal; do
|
||||
if [ -e "/home/marc/radarr/$f" ]; then
|
||||
${pkgs.coreutils}/bin/cp -a "/home/marc/radarr/$f" "/home/marc/sonarr/$f"
|
||||
fi
|
||||
done
|
||||
for d in Backups asp Sentry logs; do
|
||||
if [ -d "/home/marc/radarr/$d" ]; then
|
||||
${pkgs.coreutils}/bin/cp -a "/home/marc/radarr/$d" /home/marc/sonarr/
|
||||
fi
|
||||
done
|
||||
${pkgs.coreutils}/bin/chown -R marc:users /home/marc/sonarr
|
||||
${pkgs.coreutils}/bin/touch /home/marc/sonarr/.migration-done
|
||||
'';
|
||||
};
|
||||
|
||||
# DIAGNOSTIC TEMPORAIRE (a retirer) : exhume la base Jellyfin (clés API,
|
||||
# utilisateurs) et le config.xml de Radarr, root-only, vers un dossier
|
||||
# lisible par hermes, pour pouvoir piloter les deux en solo.
|
||||
system.activationScripts.mediaDiag = ''
|
||||
${pkgs.coreutils}/bin/install -d -o hermes -g hermes -m 0750 /var/lib/hermes/x-media
|
||||
for f in /var/lib/jellyfin/data/jellyfin.db /var/lib/jellyfin/data/jellyfin.db-wal /var/lib/jellyfin/data/jellyfin.db-shm; do
|
||||
if [ -e "$f" ]; then ${pkgs.coreutils}/bin/cp -a "$f" /var/lib/hermes/x-media/; fi
|
||||
done
|
||||
for f in /var/lib/radarr/.config/Radarr/config.xml /home/marc/sonarr/config.xml /var/lib/prowlarr/config.xml; do
|
||||
if [ -e "$f" ]; then ${pkgs.coreutils}/bin/cp -a "$f" "/var/lib/hermes/x-media/$(echo "$f" | tr '/' '_')"; fi
|
||||
done
|
||||
${pkgs.coreutils}/bin/chown -R hermes:hermes /var/lib/hermes/x-media
|
||||
${pkgs.coreutils}/bin/chmod -R u+rwX,go-rwx /var/lib/hermes/x-media
|
||||
'';
|
||||
}
|
||||
Reference in New Issue
Block a user