Robuste Darktable-Synchronisation: sequenzieller Ablauf, Versions- und Concurrent-Schutz

- Race Condition behoben: Pre-Sync wird vollstaendig abgewartet bevor Darktable startet
- Post-Sync nach Schliessen von Darktable eingefuehrt (bisher fehlend)
- .env aus festem Pfad ~/.config/darktable-sync/.env geladen (nicht mehr relativ)
- Server-Erreichbarkeit per SSH statt ping (Firewall-sicher)
- Darktable-Versionscheck (Major.Minor) vor Download mit Abbruch bei Konflikt
- DB-Backup vor jedem Download (library.db.bak, data.db.bak)
- sync_pending-Marker bei Offline/Fehler, Hinweis beim naechsten Start
- darktable.active-Marker auf Server fuer Concurrent-Erkennung
- Lock-Dateien vom Sync ausgeschlossen
- systemd-Timer entfernt, Service bleibt als manueller Trigger
- Gemeinsame Hilfsfunktionen in darktable_common.sh extrahiert
- 20 BATS-Tests mit vollstaendigem Stub-System ohne GUI-Dialoge

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-19 19:41:26 +02:00
parent 3bdd26ed81
commit 6a6ce52cf9
21 changed files with 777 additions and 201 deletions
+71 -9
View File
@@ -1,12 +1,74 @@
#!/bin/bash
set -e
#!/usr/bin/env bash
set -euo pipefail
# Konfiguration (per ENV überschreibbar)
DARKTABLE_BIN="${DARKTABLE_BIN:-darktable}"
SYNC_BIN="${SYNC_BIN:-darktable_sync.sh}"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=darktable_common.sh
source "$SCRIPT_DIR/darktable_common.sh"
# Sync im Hintergrund starten
"$SYNC_BIN" --with-notify-start-stop &
check_dependency darktable
check_dependency ssh openssh-client
check_dependency notify-send libnotify-bin
# Darktable starten
exec "$DARKTABLE_BIN" "$@"
load_config
validate_config
export DISPLAY="${DISPLAY:-:0}"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"
}
if pgrep -x darktable &>/dev/null; then
notify-send "Darktable" \
"Darktable laeuft bereits. Bitte zuerst schliessen." -u critical
exit 1
fi
ACTIVE_MARKER_SET=false
cleanup() {
if [ "$ACTIVE_MARKER_SET" = true ]; then
ssh -o ConnectTimeout=5 -o BatchMode=yes \
-p "$SERVER_SSH_PORT" "$SERVER_USER@$SERVER_IP" \
"rm -f '$SERVER_DB_DIR/darktable.active'" 2>/dev/null || true
fi
}
trap cleanup EXIT INT TERM
if ! server_reachable; then
if ! ask_user "Darktable Sync" \
"Server nicht erreichbar.\nDarktable ohne Synchronisation starten?"; then
log "Abbruch durch Benutzer Server nicht erreichbar."
exit 0
fi
log "Starte Darktable ohne Sync..."
else
log "Pre-Sync..."
"$SYNC_BIN"
MARKER="$(hostname) seit $(date '+%Y-%m-%d %H:%M:%S')"
ssh -o ConnectTimeout=5 -o BatchMode=yes \
-p "$SERVER_SSH_PORT" "$SERVER_USER@$SERVER_IP" \
"echo '$MARKER' > '$SERVER_DB_DIR/darktable.active'" || true
ACTIVE_MARKER_SET=true
fi
log "Starte Darktable..."
"$DARKTABLE_BIN" "$@" || true
log "Darktable beendet."
if [ "$ACTIVE_MARKER_SET" = true ]; then
ssh -o ConnectTimeout=5 -o BatchMode=yes \
-p "$SERVER_SSH_PORT" "$SERVER_USER@$SERVER_IP" \
"rm -f '$SERVER_DB_DIR/darktable.active'" 2>/dev/null || true
ACTIVE_MARKER_SET=false
fi
if server_reachable; then
log "Post-Sync..."
"$SYNC_BIN"
else
touch "$CONFIG_DIR/sync_pending"
notify-send "Darktable Sync" \
"Server nicht erreichbar Sync ausstehend." -t 5000
fi