6074f101ff
- Zentralisiere alle rsync-Aufrufe in darktable_common.sh mit perform_rsync() - Trockenlauf-Flag-Handling in Gemeinsam-Funktionen - perform_rsync() gibt Zeilenanzahl zurück für Trockenlauf-Zählwerte - darktable_sync.sh nutzt nur noch perform_rsync(), reduziert Duplikation - Testabdeckung für perform_rsync() + rsync-Fehlerbehandlung erweitert - CLAUDE.md mit unison-Migration-Absicht dokumentiert Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
4.0 KiB
4.0 KiB
darktable-sync — Projektdokumentation für Claude
Zweck
Bash-Skripte zur bidirektionalen Synchronisation der Darktable-Datenbank und Fotobibliothek zwischen lokalem Rechner und einem Server via Unison/SSH. Entwickelt für Linux mit systemd.
Architektur
darktable_wrapper.sh → Startet Pre-/Post-Sync, dann Darktable
darktable_sync.sh → Hauptsync-Engine (Upload + Download)
darktable_common.sh → Gemeinsame Hilfsfunktionen (wird per source eingebunden)
Ablauf darktable_sync.sh
- Dependencies prüfen (unison, ssh, notify-send, darktable)
- Config laden und validieren
- Lock erwerben (atomares
mkdir) - Dry-Run-Modus prüfen (Standard: Trockenlauf;
--execute/-efür echten Sync) - Darktable-Prozess prüfen (Sync verboten wenn darktable läuft)
- Server-Erreichbarkeit prüfen →
sync_pendingbei Fehler - Unison-Versionen abgleichen (exakt gleiche Version auf beiden Seiten erforderlich)
- Active-Marker prüfen (verhindert gleichzeitige Clients)
- Darktable-Versionen abgleichen (Major.Minor müssen übereinstimmen)
- Sync-Token prüfen (Konflikterkennung bei mehreren Clients) →
-force local/-force remote/-prefer newer - DB-Backup erstellen (library.db.bak, data.db.bak) — nur bei
--execute - Backup-Verzeichnisse anlegen (
${LOCAL_PHOTO_DIR}-bak,${LOCAL_DARKTABLE_DB_DIR}-bak) - DB-Sync: bidirektional via Unison (lokal gelöscht + im Archiv → Server löschen; nie lokal vorhanden → herunterladen)
- Foto-Sync: bidirektional via Unison mit
-prefer newer - Sync-Token und Versionsdatei speichern
- Alte Backups bereinigen (
cleanup_old_backups, >730 Tage)
Konfiguration
- Datei:
~/.config/darktable-sync/.env(Permissions: 600) - Wichtige Variablen:
SERVER_IP,SERVER_USER,SERVER_SSH_PORT,SERVER_DB_DIR,SERVER_PHOTO_DIR,LOCAL_DARKTABLE_DB_DIR,LOCAL_PHOTO_DIR,DARKTABLE_BIN,SYNC_BIN - Vorlage:
.env.example
Unison-Flags
| Operation | Flags |
|---|---|
| DB-Sync | -batch -times -auto -prefer newer -ignore "Name *.lock" -ignore "Name darktable_version" -backup "Name *" -backupdir "${LOCAL_DARKTABLE_DB_DIR}-bak" |
| Foto-Sync | -batch -times -auto -prefer newer -ignore "Name *.lock" -backup "Name *" -backupdir "${LOCAL_PHOTO_DIR}-bak" |
| Bei DB-Konflikt (upload) | -force local statt -prefer newer |
| Bei DB-Konflikt (download) | -force remote für DB und Fotos |
Dry-Run: UNISON_DRY_FLAG=(-dryrun) wird zu allen Aufrufen hinzugefügt.
Unison-Output-Format (Dryrun)
new file ----> path— neue Datei (Upload, an Server)<---- new file path— neue Datei (Download, lokal)changed ----> path— aktualisiert (Upload)<---- changed path— aktualisiert (Download)deleted ----> path— gelöscht (Upload)<---- deleted path— gelöscht (Download)
Sicherheitsmechanismen
validate_path: Blockiert' " ; | & \$ ( ) ` und..in Pfaden (Server- UND lokale Pfade)load_config: Blockiert `; | & `` in der .env vor dem source- Leeres Quellverzeichnis vor Upload → Abbruch (Schutz vor falschem Mount)
- Atomares Locking via
mkdir - SSH immer mit
BatchMode=yesundConnectTimeout=5
Test-Infrastruktur
- Framework: BATS (
tests/*.bats) - Stubs in
tests/stubs/:unison,ssh,darktable,notify-send,pgrep,zenity,kdialog - Stub-Aktivierung:
run_with_stubssetzttests/stubs/vorne in PATH - Steuerung via Env-Variablen:
UNISON_STUB_FAIL,UNISON_STUB_DRY_LINES,UNISON_STUB_ARGS_FILE,SSH_STUB_FAIL,SSH_STUB_OUTPUT,UNISON_SERVER_VERSION,PGREP_STUB_FOUND - Setup:
create_valid_envintests/helpers/setup.bash; jeder Test bekommt isoliertes$HOMEin$BATS_TMPDIR - Tests ausführen:
bats tests/
Installation
install.sh — interaktiv, prüft Dependencies, kopiert Skripte nach ~/.local/bin/, richtet systemd-Service ein.
Bekannte offene Punkte
- M1 (Security, niedrig):
validate_pathsieht$VARnicht, da bash beimsource .envbereits expandiert. Angreifer braucht Schreibzugriff auf.env— begrenzter Schaden.