#!/usr/bin/env bash set -Eeuo pipefail ######################################## # Einstellungen ######################################## SOURCE_LIST="/root/backup-config/sources.txt" BACKUP_ROOT="/root/backup-config/backup" LOGFILE="/var/log/backup-config.log" # Git USE_GIT="yes" GIT_BRANCH="DockerDMZ_Configfiles" # Verzeichnisse, die automatisch nach Config-Dateien durchsucht werden AUTO_SCAN_DIRS=( "/root/docker" ) # Dateitypen, die automatisch erkannt werden AUTO_FILE_TYPES=( "*.sh" "*.yml" "*.yaml" "*.env" "*.conf" "*.cnf" "*.ini" "*.json" "*.toml" "*.service" "Dockerfile" "docker-compose.yml" "compose.yml" ) # Pfade, die beim automatischen Scan ausgeschlossen werden EXCLUDES=( "*/data/pages/*" "*/data/media/*" "*/data/cache/*" "*/data/tmp/*" "*/logs/*" "*/log/*" "*/db/*" "*/database/*" "*/mysql/*" "*/mariadb/*" "*/postgres/*" "*/redis/*" "*/.git/*" ) ######################################## # Logging ######################################## log() { printf '%s %s\n' "$(date '+%F %T')" "$1" | tee -a "$LOGFILE" } ######################################## # Hilfsfunktionen ######################################## is_excluded() { local path="$1" local ex for ex in "${EXCLUDES[@]}"; do if [[ "$path" == $ex ]]; then return 0 fi done return 1 } copy_path() { local src="$1" local rel local dst if is_excluded "$src"; then log "SKIP (exclude): $src" return 0 fi if [[ -f "$src" ]]; then rel="${src#/}" dst="$BACKUP_ROOT/$rel" mkdir -p "$(dirname "$dst")" cp -a "$src" "$dst" log "OK (FILE): $src -> $dst" return 0 fi if [[ -d "$src" ]]; then rel="${src#/}" dst="$BACKUP_ROOT/$rel" mkdir -p "$(dirname "$dst")" cp -a "$src" "$dst" log "OK (DIR): $src -> $dst" return 0 fi log "WARN: Pfad nicht gefunden: $src" return 1 } ######################################## # Automatischer Scan ######################################## auto_scan() { local dir local file local find_expr=() log "INFO: Starte automatischen Scan" # find-Ausdruck für Dateitypen bauen for pattern in "${AUTO_FILE_TYPES[@]}"; do find_expr+=( -name "$pattern" -o ) done unset 'find_expr[${#find_expr[@]}-1]' for dir in "${AUTO_SCAN_DIRS[@]}"; do if [[ ! -d "$dir" ]]; then log "WARN: Auto-Scan-Verzeichnis fehlt: $dir" continue fi while IFS= read -r file; do if is_excluded "$file"; then log "SKIP (exclude): $file" continue fi copy_path "$file" || true done < <( find "$dir" -type f \( "${find_expr[@]}" \) 2>/dev/null | sort -u ) done } ######################################## # Git ######################################## git_prepare_repo() { if [[ "$USE_GIT" != "yes" ]]; then return 0 fi if ! command -v git >/dev/null 2>&1; then log "ERROR: Git ist nicht installiert" return 1 fi mkdir -p "$BACKUP_ROOT" if [[ ! -d "$BACKUP_ROOT/.git" ]]; then log "INFO: Git-Repository wird initialisiert" git -C "$BACKUP_ROOT" init fi # Benutzerinfo prüfen if ! git -C "$BACKUP_ROOT" config user.name >/dev/null; then log "WARN: Git user.name ist im Repository nicht gesetzt" fi if ! git -C "$BACKUP_ROOT" config user.email >/dev/null; then log "WARN: Git user.email ist im Repository nicht gesetzt" fi } git_checkout_branch() { local branch="$1" if [[ "$USE_GIT" != "yes" ]]; then return 0 fi if [[ -z "$branch" ]]; then return 0 fi if git -C "$BACKUP_ROOT" show-ref --verify --quiet "refs/heads/$branch"; then git -C "$BACKUP_ROOT" checkout "$branch" >/dev/null 2>&1 log "INFO: Git-Branch aktiviert: $branch" return 0 fi # Wenn noch gar kein Commit existiert, zuerst initialen Commit anlegen if ! git -C "$BACKUP_ROOT" rev-parse --verify HEAD >/dev/null 2>&1; then git -C "$BACKUP_ROOT" add -A if ! git -C "$BACKUP_ROOT" diff --cached --quiet; then git -C "$BACKUP_ROOT" commit -m "Initial backup import" log "INFO: Initialer Commit erstellt" fi fi git -C "$BACKUP_ROOT" checkout -b "$branch" >/dev/null 2>&1 log "INFO: Git-Branch erstellt und aktiviert: $branch" } git_commit_changes() { local changed_files local commit_msg if [[ "$USE_GIT" != "yes" ]]; then return 0 fi git -C "$BACKUP_ROOT" add -A if git -C "$BACKUP_ROOT" diff --cached --quiet; then log "INFO: Keine Änderungen für Git" return 0 fi changed_files="$(git -C "$BACKUP_ROOT" diff --cached --name-only | sed 's#^# - #' || true)" commit_msg=$( cat <