# Music Sync Script (Unraid) ## Zweck Synchronisiert neue Musikdateien aus `incoming` in zwei Zielordner. Dateien werden nur verarbeitet, wenn sie vollständig geschrieben sind. --- ## Ablauf incoming → ready → DEST1 + DEST2 → delete --- ## Warum incoming → ready? Das Script verwendet zwei Verzeichnisse, um einen sauberen und sicheren Verarbeitungszustand zu gewährleisten. ### Problem ohne Trennung Wenn direkt aus `incoming` synchronisiert wird: - Dateien können noch geschrieben werden (z. B. durch Picard) - `rsync` kopiert ggf. unvollständige Dateien - bei mehreren Durchläufen entstehen Inkonsistenzen zwischen den Zielen --- ### Lösung: Staging mit `ready` Der Ablauf ist bewusst zweistufig: incoming (unsicher) → ready (stabil) → Sync #### incoming - hier schreibt Picard - Dateien können noch im Zugriff sein - kein Sync von hier #### ready - Dateien werden erst verschoben, wenn sie alt genug sind - `mv` innerhalb desselben Filesystems ist atomar - Datei ist danach garantiert vollständig 👉 Ergebnis: Das Script arbeitet nur mit fertigen, stabilen Dateien. --- ## Wichtiger Hinweis zu "atomar" Ein `mv` ist nur dann atomar, wenn sich Quelle und Ziel im selben Filesystem befinden. In diesem Setup: ``` INCOMING="/mnt/user/Cache/Picard/incoming" READY="/mnt/user/Cache/Picard/ready" ``` liegen beide Pfade im selben Share → gleicher Storage → atomarer Move. Wichtig: - Es ist egal, wo Picard läuft (Docker, anderer Host, etc.) - Entscheidend ist nur, wohin geschrieben wird Nicht atomar wäre z. B.: ``` /mnt/user/... → /mnt/diskX/... ``` Dann würde `mv` intern kopieren + löschen. --- ## Lockfile ``` /mnt/user/Cache/Picard/sync.lock ``` ### Zweck - verhindert parallele Ausführung - schützt vor doppelten Operationen ### Problemfall Wenn das Script abbricht, bleibt das Lockfile bestehen und blockiert weitere Runs. ### Lösung ``` rm /mnt/user/Cache/Picard/sync.lock ``` Nur ausführen, wenn sicher kein Script mehr läuft. --- ## CHOWN (Dateirechte / CIFS Problem) Nach dem Kopieren werden Dateien und Ordner explizit gesetzt auf: ``` CHOWN_USER="thorsten" CHOWN_GROUP="users" ``` ### Warum ist das nötig? Unraid + CIFS/Samba verhält sich so: - Dateien werden oft als `root` oder `nobody` angelegt - Netzwerkzugriff über CIFS hat dann **keine Löschrechte** - selbst wenn Lesen funktioniert 👉 Typisches Symptom: Datei kann geöffnet, aber nicht gelöscht werden --- ### Lösung im Script Nach erfolgreichem Sync: - wird jede Datei gechowned - zugehörige Ordner werden ebenfalls angepasst - Ordner aber nur **einmal pro Lauf** (Performance) 👉 Ergebnis: - Dateien gehören deinem User - CIFS Zugriff funktioniert korrekt - kein manuelles `chown -R` mehr nötig --- ## Eigenschaften - verarbeitet nur Dateien älter als 1 Minute - atomarer Move (incoming → ready) - Sync zu zwei Zielen per rsync - Löschen nur bei Erfolg beider Syncs - fehlgeschlagene Dateien bleiben erhalten - Lockfile verhindert parallele Ausführung - Dry-Run Modus vorhanden - Logging + Konsolenausgabe - Pfade tolerant gegenüber trailing `/` - Zielpfade müssen existieren (sonst Abbruch) - Ownership wird gesetzt (`chown`) - Ordner werden nur einmal pro Lauf angepasst --- ## Konfiguration ``` INCOMING="/mnt/user/Cache/Picard/incoming" READY="/mnt/user/Cache/Picard/ready" DEST1="/mnt/user/Cache/Syncthing/..." DEST2="/mnt/user/Media/Musik/..." LOG="/mnt/user/Cache/Picard/sync.log" LOCKFILE="/mnt/user/Cache/Picard/sync.lock" DRY_RUN=false CHOWN_USER="thorsten" CHOWN_GROUP="users" ``` --- ## Dry Run ``` DRY_RUN=true ``` - keine Änderungen am Dateisystem - rsync läuft mit --dry-run - Aktionen werden geloggt --- ## Cron Beispiel ``` 0 */6 * * * ``` --- ## Hinweise - Script beendet sich sofort, wenn keine Dateien vorhanden sind - `ready/` wird nur bei Bedarf erstellt und kann wieder verschwinden - Rechteproblem bei CIFS wird durch chown gelöst --- ## Debug ``` cat /mnt/user/Cache/Picard/sync.log ls /mnt/user/Cache/Picard ```