Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 35 additions & 12 deletions restic-backup.sh
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
#!/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
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"
Expand Down Expand Up @@ -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 <id> <path>" "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 <snapshot_id>" "List files and directories inside a specific snapshot."
printf " ${C_GREEN}%-20s${C_RESET} %s\n" "--find <pattern...>" "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."
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -1754,13 +1772,18 @@ 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
--verbose)
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
Expand Down
2 changes: 1 addition & 1 deletion restic-backup.sh.sha256
Original file line number Diff line number Diff line change
@@ -1 +1 @@
a7206371dd37d9803bd1df98083332c55f570da8bc6be3ac8a7e7538356d6430 restic-backup.sh
260732b0a22a5ed4bde396e09bf803481c72202d9600bf0609e5d6a362951c67 restic-backup.sh
Loading