Main angleichen: agathe_backup.sh jetzt inkl. Tomedo

This commit is contained in:
René Mathieu
2026-03-11 11:01:59 +01:00
parent 4c7efb05c8
commit 841eedfe2f

View File

@@ -1,9 +1,11 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# MAIN-HINWEIS: Diese Version ist nun inkl. Tomedo-Backup.
# Robust: WireGuard hoch, CIFS mounten (inkl. Stale-Handle-Fix), rsync, # Robust: WireGuard hoch, CIFS mounten (inkl. Stale-Handle-Fix), rsync,
# nur erlaubte Dateitypen zusätzlich nach paperless-consume (flach, OHNE GIF), # nur erlaubte Dateitypen zusätzlich nach paperless-consume (flach, OHNE GIF),
# Paperless-Backup rsync als echtes Sync (mit --delete), # Paperless-Backup rsync als echtes Sync (mit --delete),
# Anmeldung ebenfalls sync + consume, # Anmeldung ebenfalls sync + consume,
# zusätzlich: Borg lokal (inkrementell, versioniert) + Mirror per rsync auf CIFS (mit delete), # zusätzlich: Borg lokal (inkrementell, versioniert) + Mirror per rsync auf CIFS (mit delete),
# zusätzlich: Tomedo-Backup per rsync,
# robust gegen CIFS-Aussetzer: ensure_cifs + rsync temp-dir lokal + Mount-Fallback. # robust gegen CIFS-Aussetzer: ensure_cifs + rsync temp-dir lokal + Mount-Fallback.
# Zusätzlich: Pushover-Benachrichtigung bei Erfolg/Fehler. # Zusätzlich: Pushover-Benachrichtigung bei Erfolg/Fehler.
# Fix: Wenn wg0 schon aktiv ist, wird es nicht erneut gestartet und beim Cleanup # Fix: Wenn wg0 schon aktiv ist, wird es nicht erneut gestartet und beim Cleanup
@@ -18,7 +20,6 @@ set -Eeuo pipefail
WG_IF="wg0" WG_IF="wg0"
VPN_TEST_IP="10.202.101.10" VPN_TEST_IP="10.202.101.10"
WG_WAS_STARTED_BY_SCRIPT=0 WG_WAS_STARTED_BY_SCRIPT=0
PUSHOVER_FAILURE_SENT=0
LOCK_FILE="/var/lock/agathe_backup.lock" LOCK_FILE="/var/lock/agathe_backup.lock"
@@ -80,6 +81,15 @@ DRY_RUN_DELETE="0"
# Welche Dateien nach paperless-consume? (OHNE GIF) # Welche Dateien nach paperless-consume? (OHNE GIF)
CONSUME_EXT_REGEX='\.([Pp][Dd][Ff]|[Dd][Oo][Cc][Xx]?|[Xx][Ll][Ss][Xx]?|[Pp][Pp][Tt][Xx]?|[Oo][Dd][Tt]|[Oo][Dd][Ss]|[Oo][Dd][Pp]|[Rr][Tt][Ff]|[Tt][Xx][Tt]|[Cc][Ss][Vv]|[Mm][Dd]|[Hh][Tt][Mm][Ll]?|[Jj][Pp][Ee]?[Gg]|[Pp][Nn][Gg]|[Tt][Ii][Ff][Ff]?|[Ww][Ee][Bb][Pp]|[Hh][Ee][Ii][Cc])$' CONSUME_EXT_REGEX='\.([Pp][Dd][Ff]|[Dd][Oo][Cc][Xx]?|[Xx][Ll][Ss][Xx]?|[Pp][Pp][Tt][Xx]?|[Oo][Dd][Tt]|[Oo][Dd][Ss]|[Oo][Dd][Pp]|[Rr][Tt][Ff]|[Tt][Xx][Tt]|[Cc][Ss][Vv]|[Mm][Dd]|[Hh][Tt][Mm][Ll]?|[Jj][Pp][Ee]?[Gg]|[Pp][Nn][Gg]|[Tt][Ii][Ff][Ff]?|[Ww][Ee][Bb][Pp]|[Hh][Ee][Ii][Cc])$'
# -----------------------------
# Tomedo Backup
# -----------------------------
TOMEDO_SRC_ROOT="/mnt/TomedoBackup"
TOMEDO_LAST_FILE="${TOMEDO_SRC_ROOT}/lastFilesBackup"
TOMEDO_DEST_ROOT="${CIFS_MOUNTPOINT}/TomedoBackup"
TOMEDO_MACOS_EXCLUDES="${TOMEDO_DEST_ROOT}/macos.excludes"
TOMEDO_FILES_EXCLUDES="${TOMEDO_DEST_ROOT}/files.excludes"
# ----------------------------- # -----------------------------
# Hilfsfunktionen # Hilfsfunktionen
# ----------------------------- # -----------------------------
@@ -91,27 +101,16 @@ send_pushover() {
local priority="${2:-0}" local priority="${2:-0}"
if command -v curl >/dev/null 2>&1; then if command -v curl >/dev/null 2>&1; then
local rc curl -s \
set +e
curl -fsS --max-time 20 --retry 2 --retry-delay 2 \
--form-string "token=${PUSHOVER_API_TOKEN}" \ --form-string "token=${PUSHOVER_API_TOKEN}" \
--form-string "user=${PUSHOVER_USER_TOKEN}" \ --form-string "user=${PUSHOVER_USER_TOKEN}" \
--form-string "title=${PUSHOVER_TITLE}" \ --form-string "title=${PUSHOVER_TITLE}" \
--form-string "message=${message}" \ --form-string "message=${message}" \
--form-string "priority=${priority}" \ --form-string "priority=${priority}" \
https://api.pushover.net/1/messages.json >/dev/null https://api.pushover.net/1/messages.json >/dev/null || true
rc=$?
set -e
if [[ "$rc" -ne 0 ]]; then
log "WARNUNG: Pushover konnte nicht gesendet werden (curl Exit-Code: $rc)."
return 1
fi
else else
log "WARNUNG: curl fehlt, Pushover konnte nicht gesendet werden." log "WARNUNG: curl fehlt, Pushover konnte nicht gesendet werden."
return 1
fi fi
return 0
} }
need_root() { need_root() {
@@ -161,22 +160,13 @@ on_error() {
local exit_code=$? local exit_code=$?
local line_no="${1:-unknown}" local line_no="${1:-unknown}"
log "FEHLER in Zeile ${line_no}, Exit-Code ${exit_code}" log "FEHLER in Zeile ${line_no}, Exit-Code ${exit_code}"
if send_pushover "Backup FEHLER auf $(hostname): Zeile ${line_no}, Exit-Code ${exit_code}" 1; then send_pushover "Backup FEHLER auf $(hostname): Zeile ${line_no}, Exit-Code ${exit_code}" 1
PUSHOVER_FAILURE_SENT=1
fi
trap - EXIT trap - EXIT
cleanup cleanup
exit "$exit_code" exit "$exit_code"
} }
on_exit() { on_exit() {
local exit_code=$?
if [[ "$exit_code" -ne 0 && "$PUSHOVER_FAILURE_SENT" -eq 0 ]]; then
log "WARNUNG: Abbruch ohne ERR-Notification erkannt (Exit-Code ${exit_code}), sende Fallback-Pushover."
if send_pushover "Backup FEHLER auf $(hostname): Exit-Code ${exit_code} (EXIT trap)." 1; then
PUSHOVER_FAILURE_SENT=1
fi
fi
cleanup cleanup
} }
@@ -184,7 +174,7 @@ trap 'on_error $LINENO' ERR
trap on_exit EXIT trap on_exit EXIT
check_deps() { check_deps() {
local deps=(wg-quick wg mount rsync ping mountpoint umount awk cp date basename tee mktemp sleep id mkdir rm dirname borg df curl hostname flock) local deps=(wg-quick wg mount rsync ping mountpoint umount awk cp date basename tee mktemp sleep id mkdir rm dirname borg df curl hostname flock cat)
for d in "${deps[@]}"; do for d in "${deps[@]}"; do
command -v "$d" >/dev/null 2>&1 || { echo "Fehlt: $d"; exit 1; } command -v "$d" >/dev/null 2>&1 || { echo "Fehlt: $d"; exit 1; }
done done
@@ -380,6 +370,67 @@ rsync_paperless_backup() {
"$SRC_PAPERLESS_BACKUP" "$DEST_PAPERLESS_BACKUP" "$SRC_PAPERLESS_BACKUP" "$DEST_PAPERLESS_BACKUP"
} }
rsync_tomedo_backup() {
ensure_cifs
log "== Tomedo Backup starten =="
if [[ ! -f "$TOMEDO_LAST_FILE" ]]; then
log "FEHLER: Datei fehlt: $TOMEDO_LAST_FILE"
exit 1
fi
local last_backup
last_backup="$(cat "$TOMEDO_LAST_FILE")"
if [[ -z "$last_backup" ]]; then
log "FEHLER: $TOMEDO_LAST_FILE ist leer"
exit 1
fi
local src_snapshot="${TOMEDO_SRC_ROOT}/${last_backup}/"
local dst_snapshot="${TOMEDO_DEST_ROOT}/${last_backup}"
local src_files="${TOMEDO_SRC_ROOT}/files/"
local dst_files="${TOMEDO_DEST_ROOT}/files"
if [[ ! -d "$src_snapshot" ]]; then
log "FEHLER: Tomedo Snapshot-Ordner fehlt: $src_snapshot"
exit 1
fi
if [[ ! -d "$src_files" ]]; then
log "FEHLER: Tomedo files-Ordner fehlt: $src_files"
exit 1
fi
if [[ ! -f "$TOMEDO_MACOS_EXCLUDES" ]]; then
log "FEHLER: Exclude-Datei fehlt: $TOMEDO_MACOS_EXCLUDES"
exit 1
fi
if [[ ! -f "$TOMEDO_FILES_EXCLUDES" ]]; then
log "FEHLER: Exclude-Datei fehlt: $TOMEDO_FILES_EXCLUDES"
exit 1
fi
mkdir -p "$dst_snapshot" "$dst_files"
log "== rsync Tomedo Snapshot: $src_snapshot -> $dst_snapshot =="
rsync -r -l -t -O --info=progress2 \
--exclude-from "$TOMEDO_MACOS_EXCLUDES" \
"$src_snapshot" \
"$dst_snapshot"
log "== rsync Tomedo Files: $src_files -> $dst_files =="
rsync -r -l -t -O --info=progress2 \
--exclude-from "$TOMEDO_MACOS_EXCLUDES" \
--exclude-from "$TOMEDO_FILES_EXCLUDES" \
"$src_files" \
"$dst_files"
log "== Tomedo Backup fertig: $last_backup =="
}
# ----------------------------- # -----------------------------
# Borg: lokal sichern + Mirror auf CIFS # Borg: lokal sichern + Mirror auf CIFS
# ----------------------------- # -----------------------------
@@ -497,6 +548,7 @@ rsync_and_copy_to_consume_flat "$SRC_GROOT" "$DEST_GROOT" "GROOT"
rsync_and_copy_to_consume_flat "$SRC_ANMELDUNG" "$DEST_ANMELDUNG" "ANMELDUNG" rsync_and_copy_to_consume_flat "$SRC_ANMELDUNG" "$DEST_ANMELDUNG" "ANMELDUNG"
rsync_paperless_backup rsync_paperless_backup
rsync_tomedo_backup
borg_local_backup borg_local_backup
rsync_borg_mirror_to_cifs rsync_borg_mirror_to_cifs