diff --git a/restic-backup.sh b/restic-backup.sh index 68f6985..9743e24 100644 --- a/restic-backup.sh +++ b/restic-backup.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # ================================================================= -# Restic Backup Script v0.42 - 2025.12.17 +# Restic Backup Script v0.43 - 2026.02.02 # ================================================================= export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH @@ -9,7 +9,7 @@ set -euo pipefail umask 077 # --- Script Constants --- -SCRIPT_VERSION="0.42" +SCRIPT_VERSION="0.43" SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd) PROG_NAME=$(basename "$0"); readonly PROG_NAME CONFIG_FILE="${SCRIPT_DIR}/restic-backup.conf" @@ -63,6 +63,7 @@ display_help() { printf " ${C_GREEN}%-20s${C_RESET} %s\n" "--unlock" "Remove stale repository locks." printf " ${C_GREEN}%-20s${C_RESET} %s\n" "--dump " "Dump a single file from a snapshot to stdout." printf " ${C_GREEN}%-20s${C_RESET} %s\n" "--restore" "Interactive restore wizard." + printf " ${C_GREEN}%-20s${C_RESET} %s\n" "--exact-ownership" "Perserve raw ownership, to use with restore flags." printf " ${C_GREEN}%-20s${C_RESET} %s\n" "--ls " "List files and directories inside a specific snapshot." printf " ${C_GREEN}%-20s${C_RESET} %s\n" "--find " "Search for files/dirs across all snapshots (e.g., --find \"*.log\" -l)." printf " ${C_GREEN}%-20s${C_RESET} %s\n" "--background-restore" "Run a non-interactive restore in the background." @@ -1473,6 +1474,18 @@ run_restore() { fi log_message "WARNING: User confirmed dangerous restore to: $restore_dest" fi + + echo -e "\n${C_YELLOW}Ownership Handling:${C_RESET}" + echo " n) Auto-fix ownership (Best for standard user files in /home)" + echo " y) Preserve exact backup UIDs/GIDs (Required for Docker/Databases)" + read -rp "Preserve exact raw ownership? (y/n) [n]: " preserve_confirm + if [[ "${preserve_confirm,,}" == "y" || "${preserve_confirm,,}" == "yes" ]]; then + SKIP_OWNERSHIP_FIX=true + echo -e "${C_CYAN}ℹ️ Exact ownership will be preserved (no auto-fix).${C_RESET}" + else + SKIP_OWNERSHIP_FIX=false + fi + local include_paths=() read -rp "Optional: Enter specific file(s) to restore, separated by spaces (leave blank for full restore): " -a include_paths local restic_cmd=(restic restore "$snapshot_id" --target "$restore_dest" --verbose) @@ -1534,18 +1547,23 @@ run_restore() { _handle_restore_ownership() { local restore_dest="$1" - + local dest_user="" if [[ "$restore_dest" == /home/* ]]; then - local dest_user dest_user=$(stat -c %U "$(dirname "$restore_dest")" 2>/dev/null || echo "${restore_dest#/home/}" | cut -d/ -f1) - - if [[ -n "$dest_user" ]] && id -u "$dest_user" &>/dev/null; then - log_message "Home directory detected. Setting ownership of restored files to '$dest_user'." - if chown -R "${dest_user}:${dest_user}" "$restore_dest"; then - log_message "Successfully changed ownership of $restore_dest to $dest_user" - else - log_message "WARNING: Failed to change ownership of $restore_dest to $dest_user. Please check permissions manually." - fi + fi + if [[ -n "$dest_user" ]] && id -u "$dest_user" &>/dev/null; then + if [ -d "$restore_dest" ]; then + chown "$dest_user:$dest_user" "$restore_dest" + fi + if [[ "${SKIP_OWNERSHIP_FIX:-false}" == "true" ]]; then + log_message "Exact ownership requested: Fixed access to $restore_dest, but preserved raw IDs inside." + return 0 + fi + log_message "Home directory detected. Recursively setting ownership to '$dest_user'." + if chown -R "${dest_user}:${dest_user}" "$restore_dest"; then + log_message "Successfully changed ownership of $restore_dest to $dest_user" + else + log_message "WARNING: Failed to change ownership of $restore_dest. Check permissions." fi fi } @@ -1754,6 +1772,7 @@ EOF # 1. Parse flags. VERBOSE_MODE=false +SKIP_OWNERSHIP_FIX=false AUTO_FIX_PERMS=${AUTO_FIX_PERMS:-false} while [[ $# -gt 0 ]]; do case "$1" in @@ -1761,6 +1780,10 @@ while [[ $# -gt 0 ]]; do VERBOSE_MODE=true shift ;; + --exact-ownership) + SKIP_OWNERSHIP_FIX=true + shift + ;; --fix-permissions) if ! [ -t 0 ]; then echo -e "${C_RED}ERROR: The --fix-permissions flag can only be used in an interactive session.${C_RESET}" >&2 diff --git a/restic-backup.sh.sha256 b/restic-backup.sh.sha256 index f7f9d4f..2e53876 100644 --- a/restic-backup.sh.sha256 +++ b/restic-backup.sh.sha256 @@ -1 +1 @@ -a7206371dd37d9803bd1df98083332c55f570da8bc6be3ac8a7e7538356d6430 restic-backup.sh +260732b0a22a5ed4bde396e09bf803481c72202d9600bf0609e5d6a362951c67 restic-backup.sh