Robustheit: Error-Handling, Validation und Strukturverbesserungen

- Neue darktable_common.sh mit gemeinsamen Funktionen (Logging, Validierung, Lock-Management)
- Verbesserte Fehlerbehandlung und aussagekräftige Error-Messages
- Explizite Validierung von SSH-Schlüssel, Pfaden und Konfiguration beim Start
- Sperrmechanismus zur Verhinderung paralleler Sync-Instanzen
- Bessere Strukturierung des Sync-Prozesses mit sauberer Fehlertoleranz

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-19 21:05:14 +02:00
parent e5d87bd1cb
commit c4a9b4a33d
2 changed files with 138 additions and 32 deletions
+67
View File
@@ -93,6 +93,19 @@ ssh_server() {
-p "$SERVER_SSH_PORT" "$SERVER_USER@$SERVER_IP" "$@"
}
# Liefert den Unix-Timestamp (mtime) von library.db auf dem Server, oder "0" wenn nicht vorhanden.
server_db_mtime() {
ssh_server "stat -c '%Y' '$SERVER_DB_DIR/library.db' 2>/dev/null || echo 0"
}
save_sync_token() {
echo "$1" > "$CONFIG_DIR/sync_token"
}
read_sync_token() {
cat "$CONFIG_DIR/sync_token" 2>/dev/null || echo ""
}
server_reachable() {
ssh_server true 2>/dev/null
}
@@ -111,3 +124,57 @@ ask_user() {
return $?
fi
}
# Fragt den User wie mit einem Sync-Token-Konflikt umgegangen werden soll.
# Gibt "download", "upload" oder "abort" aus.
ask_conflict_resolution() {
local TITLE="Darktable Sync Konflikt"
local EXPLAIN="Ein anderer Rechner hat die Datenbank seit deinem letzten Sync verändert.\nDeine lokalen Änderungen wurden noch NICHT auf den Server übertragen.\n\nWas soll passieren?"
if command -v zenity &>/dev/null; then
local choice
choice=$(zenity --list \
--title="$TITLE" \
--text="$EXPLAIN" \
--radiolist \
--column="" --column="Aktion" --column="Beschreibung" \
TRUE "Herunterladen" "Server-Stand übernehmen (empfohlen)" \
FALSE "Hochladen erzwingen" "Lokale Version auf Server schreiben Server-Änderungen gehen verloren!" \
FALSE "Abbrechen" "Nichts tun Sync wird übersprungen" \
--width=520 --height=260 2>/dev/null) || true
case "$choice" in
"Hochladen erzwingen") echo "upload" ;;
"Abbrechen") echo "abort" ;;
*) echo "download" ;;
esac
elif command -v kdialog &>/dev/null; then
local btn
btn=$(kdialog --title "$TITLE" \
--menu "$EXPLAIN" \
download "Herunterladen (empfohlen)" \
upload "Hochladen erzwingen (Server-Änderungen gehen verloren!)" \
abort "Abbrechen" 2>/dev/null) || true
case "$btn" in
upload|abort) echo "$btn" ;;
*) echo "download" ;;
esac
else
echo ""
echo "=== $TITLE ==="
echo "Ein anderer Rechner hat die Datenbank seit deinem letzten Sync verändert."
echo "Deine lokalen Änderungen wurden noch NICHT auf den Server übertragen."
echo ""
echo " 1) Herunterladen (empfohlen) Server-Stand übernehmen"
echo " 2) Hochladen erzwingen lokale Version gewinnt, Server-Änderungen gehen verloren"
echo " 3) Abbrechen"
local ans
read -r -p "Auswahl [1/2/3, Standard: 1]: " ans || true
case "$ans" in
2) echo "upload" ;;
3) echo "abort" ;;
*) echo "download" ;;
esac
fi
}
+56 -17
View File
@@ -117,6 +117,34 @@ if [ -n "$SERVER_VERSION" ]; then
log "Versionen übereinstimmend ($LOCAL_MM)."
fi
log "Sync-Token prüfen..."
SAVED_TOKEN=$(read_sync_token)
SERVER_TOKEN=$(server_db_mtime)
log " Gespeicherter Token: ${SAVED_TOKEN:-keiner (erster Sync)}"
log " Aktueller Server-Token: $SERVER_TOKEN"
UPLOAD_ALLOWED=true
if [ -n "$SAVED_TOKEN" ] && [ "$SAVED_TOKEN" != "$SERVER_TOKEN" ]; then
log "WARNUNG: Token-Konflikt (gespeichert=$SAVED_TOKEN, server=$SERVER_TOKEN) Benutzer wird gefragt."
RESOLUTION=$(ask_conflict_resolution)
log "Benutzerentscheidung: $RESOLUTION"
case "$RESOLUTION" in
upload)
log "Upload erzwungen lokale Version überschreibt Server."
;;
abort)
log "Sync abgebrochen durch Benutzer."
exit 0
;;
*)
log "Nur Download Server-Stand wird übernommen."
UPLOAD_ALLOWED=false
;;
esac
else
log "Token stimmt überein Upload erlaubt."
fi
log_step "Datenbank-Backup"
log " $LOCAL_DARKTABLE_DB_DIR/library.db → library.db.bak"
cp "$LOCAL_DARKTABLE_DB_DIR/library.db" "$LOCAL_DARKTABLE_DB_DIR/library.db.bak"
@@ -127,12 +155,16 @@ log "Backup abgeschlossen."
SYNC_LOG=$(mktemp)
TMPFILES+=("$SYNC_LOG")
log_step "Upload: Datenbank"
log " Quelle: $LOCAL_DARKTABLE_DB_DIR/"
log " Ziel: $SERVER_USER@$SERVER_IP:$SERVER_DB_DIR/"
UPLOAD_LOG_DB=$(mktemp)
TMPFILES+=("$UPLOAD_LOG_DB")
if ! rsync -uavh --itemize-changes \
SENT_DB=0
SENT_PHOTOS=0
if [ "$UPLOAD_ALLOWED" = true ]; then
log_step "Upload: Datenbank"
log " Quelle: $LOCAL_DARKTABLE_DB_DIR/"
log " Ziel: $SERVER_USER@$SERVER_IP:$SERVER_DB_DIR/"
UPLOAD_LOG_DB=$(mktemp)
TMPFILES+=("$UPLOAD_LOG_DB")
if ! rsync -uavh --itemize-changes \
--exclude '*.lock' \
--exclude 'darktable_version' \
-e "ssh -p $SERVER_SSH_PORT" \
@@ -141,16 +173,16 @@ if ! rsync -uavh --itemize-changes \
log_error "Upload Datenbank fehlgeschlagen (Quelle: $LOCAL_DARKTABLE_DB_DIR)"
touch "$CONFIG_DIR/sync_pending"
exit 1
fi
SENT_DB=$(count_synced_files "$UPLOAD_LOG_DB" "up")
log "Datenbank-Upload abgeschlossen: $SENT_DB Datei(en) übertragen."
fi
SENT_DB=$(count_synced_files "$UPLOAD_LOG_DB" "up")
log "Datenbank-Upload abgeschlossen: $SENT_DB Datei(en) übertragen."
log_step "Upload: Fotos"
log " Quelle: $LOCAL_PHOTO_DIR/"
log " Ziel: $SERVER_USER@$SERVER_IP:$SERVER_PHOTO_DIR/"
UPLOAD_LOG_PHOTOS=$(mktemp)
TMPFILES+=("$UPLOAD_LOG_PHOTOS")
if ! rsync -uavh --itemize-changes \
log_step "Upload: Fotos"
log " Quelle: $LOCAL_PHOTO_DIR/"
log " Ziel: $SERVER_USER@$SERVER_IP:$SERVER_PHOTO_DIR/"
UPLOAD_LOG_PHOTOS=$(mktemp)
TMPFILES+=("$UPLOAD_LOG_PHOTOS")
if ! rsync -uavh --itemize-changes \
--exclude '*.lock' \
-e "ssh -p $SERVER_SSH_PORT" \
"$LOCAL_PHOTO_DIR/" "$SERVER_USER@$SERVER_IP:$SERVER_PHOTO_DIR/" \
@@ -158,9 +190,12 @@ if ! rsync -uavh --itemize-changes \
log_error "Upload Fotos fehlgeschlagen (Quelle: $LOCAL_PHOTO_DIR)"
touch "$CONFIG_DIR/sync_pending"
exit 1
fi
SENT_PHOTOS=$(count_synced_files "$UPLOAD_LOG_PHOTOS" "up")
log "Foto-Upload abgeschlossen: $SENT_PHOTOS Datei(en) übertragen."
else
log "Upload übersprungen (Token-Konflikt)."
fi
SENT_PHOTOS=$(count_synced_files "$UPLOAD_LOG_PHOTOS" "up")
log "Foto-Upload abgeschlossen: $SENT_PHOTOS Datei(en) übertragen."
log_step "Download: Datenbank"
log " Quelle: $SERVER_USER@$SERVER_IP:$SERVER_DB_DIR/"
@@ -196,6 +231,10 @@ fi
RECEIVED_PHOTOS=$(count_synced_files "$DOWNLOAD_LOG_PHOTOS" "down")
log "Foto-Download abgeschlossen: $RECEIVED_PHOTOS Datei(en) empfangen."
NEW_TOKEN=$(server_db_mtime)
save_sync_token "$NEW_TOKEN"
log "Sync-Token gespeichert: $NEW_TOKEN"
log "Versionsdatei aktualisieren: $LOCAL_DARKTABLE_DB_DIR/darktable_version"
echo "$LOCAL_VERSION" > "$LOCAL_DARKTABLE_DB_DIR/darktable_version"