11#! /usr/bin/env bash
22
33# =================================================================
4- # Restic Backup Script v0.36 - 2025.09.29
4+ # Restic Backup Script v0.37.1 - 2025.10.02
55# =================================================================
66
77set -euo pipefail
88umask 077
99
1010# --- Script Constants ---
11- SCRIPT_VERSION=" 0.36 "
11+ SCRIPT_VERSION=" 0.37.1 "
1212SCRIPT_DIR=$( cd -- " $( dirname -- " ${BASH_SOURCE[0]} " ) " & > /dev/null && pwd)
1313CONFIG_FILE=" ${SCRIPT_DIR} /restic-backup.conf"
1414LOCK_FILE=" /tmp/restic-backup.lock"
@@ -73,17 +73,43 @@ import_restic_key() {
7373 return 1
7474}
7575
76+ display_update_info () {
77+ local component_name=" $1 "
78+ local current_version=" $2 "
79+ local new_version=" $3 "
80+ local release_notes=" $4 "
81+ echo
82+ echo -e " ${C_BOLD}${C_YELLOW} A new version of ${component_name} is available!${C_RESET} "
83+ printf ' %-18s %s\n' " ${C_CYAN} Current Version:${C_RESET} " " ${current_version:- -not installed-} "
84+ printf ' %-18s %s\n' " ${C_GREEN} New Version:${C_RESET} " " $new_version "
85+ echo
86+ if [ -n " $release_notes " ]; then
87+ echo -e " ${C_YELLOW} Release Notes for v${new_version} :${C_RESET} "
88+ echo -e " ${release_notes// $' \n ' / $' \n ' } "
89+ echo
90+ fi
91+ }
92+
7693check_and_install_restic () {
7794 echo -e " ${C_BOLD} --- Checking Restic Version ---${C_RESET} "
78- if ! command -v bzip2 & > /dev/null || ! command -v curl & > /dev/null || ! command -v gpg & > /dev/null; then
79- echo -e " ${C_RED} ERROR: 'bzip2', 'curl', and 'gpg' are required for secure auto-installation.${C_RESET} " >&2
80- echo -e " ${C_YELLOW} On Debian based systems install with: sudo apt-get install bzip2 curl gnupg${C_RESET} " >&2
95+ if ! command -v bzip2 & > /dev/null || ! command -v curl & > /dev/null || ! command -v gpg & > /dev/null || ! command -v jq & > /dev/null; then
96+ echo
97+ echo -e " ${C_RED} ERROR: 'less', 'bzip2', 'curl', 'gpg', and 'jq' are required for secure auto-installation.${C_RESET} " >&2
98+ echo
99+ echo -e " ${C_YELLOW} On Debian based systems install with: sudo apt-get install less bzip2 curl gnupg jq${C_RESET} " >&2
100+ echo
81101 exit 1
82102 fi
103+ local release_info
104+ release_info=$( curl -s " https://api.github.com/repos/restic/restic/releases/latest" )
105+ if [ -z " $release_info " ]; then
106+ echo -e " ${C_YELLOW} Could not fetch latest restic version info from GitHub. Skipping check.${C_RESET} "
107+ return 0
108+ fi
83109 local latest_version
84- latest_version=$( curl -s " https://api.github.com/repos/restic/restic/releases/latest " | grep -o ' " tag_name": "[^"]*" ' | sed -E ' s/.*"v?([^"]+)".*/\1/ ' )
110+ latest_version=$( echo " $release_info " | jq -r ' . tag_name | sub("^v"; "") ' )
85111 if [ -z " $latest_version " ]; then
86- echo -e " ${C_YELLOW} Could not fetch latest restic version from GitHub. Skipping check.${C_RESET} "
112+ echo -e " ${C_YELLOW} Could not parse latest restic version from GitHub. Skipping check.${C_RESET} "
87113 return 0
88114 fi
89115 local local_version=" "
@@ -94,7 +120,11 @@ check_and_install_restic() {
94120 echo -e " ${C_GREEN} ✅ Restic is up to date (version $local_version ).${C_RESET} "
95121 return 0
96122 fi
97- echo -e " ${C_YELLOW} A new version of Restic is available ($latest_version ). Current version is ${local_version:- not installed} .${C_RESET} "
123+
124+ local release_notes
125+ release_notes=$( echo " $release_info " | jq -r ' .body' )
126+ display_update_info " Restic" " $local_version " " $latest_version " " $release_notes "
127+
98128 if [ -t 1 ]; then
99129 read -p " Would you like to download and install it? (y/n): " confirm
100130 if [[ " ${confirm,,} " != " y" && " ${confirm,,} " != " yes" ]]; then
@@ -112,7 +142,8 @@ check_and_install_restic() {
112142 local temp_binary temp_checksums temp_signature
113143 temp_binary=$( mktemp) && temp_checksums=$( mktemp) && temp_signature=$( mktemp)
114144 trap ' rm -f "$temp_binary" "$temp_checksums" "$temp_signature"' RETURN
115- local arch=$( uname -m)
145+ local arch
146+ arch=$( uname -m)
116147 local arch_suffix=" "
117148 case " $arch " in
118149 x86_64) arch_suffix=" amd64" ;;
@@ -157,27 +188,36 @@ check_for_script_update() {
157188 if ! [ -t 0 ]; then
158189 return 0
159190 fi
160- echo -e " ${C_BOLD} --- Checking for script updates ---${C_RESET} "
161- local SCRIPT_URL=" https://raw.githubusercontent.com/buildplan/restic-backup-script/main/restic-backup.sh"
191+ if ! command -v jq & > /dev/null; then
192+ echo -e " ${C_YELLOW} Skipping script update check: 'jq' command not found.${C_RESET} "
193+ return 0
194+ fi
195+ echo -e " ${C_BOLD} --- Checking for script updates ---${C_RESET} "
196+ local SCRIPT_API_URL=" https://api.github.com/repos/buildplan/restic-backup-script/releases/latest"
197+ local release_info
198+ release_info=$( curl -sL -H " Cache-Control: no-cache" -H " Pragma: no-cache" " $SCRIPT_API_URL " )
162199 local remote_version
163- remote_version=$( curl -sL " $SCRIPT_URL " | grep ' SCRIPT_VERSION= ' | head -n1 | sed -E ' s/.*"([^"]+)".*/\1/ ' )
200+ remote_version=$( echo " $release_info " | jq -r ' .tag_name | sub("^v"; "") ' )
164201 if [ -z " $remote_version " ] || [[ " $remote_version " == " $SCRIPT_VERSION " ]]; then
165202 echo -e " ${C_GREEN} ✅ Script is up to date (version $SCRIPT_VERSION ).${C_RESET} "
166203 return 0
167204 fi
168- echo -e " ${C_YELLOW} A new version of this script is available ($remote_version ). You are running $SCRIPT_VERSION .${C_RESET} "
169- read -p " Would you like to download and update now? (y/n): " confirm
170- if [[ " ${confirm,,} " != " y" && " ${confirm,,} " != " yes" ]]; then
205+ local release_notes
206+ release_notes=$( echo " $release_info " | jq -r ' .body // "Could not retrieve release notes."' )
207+ display_update_info " this script" " $SCRIPT_VERSION " " $remote_version " " $release_notes "
208+ read -rp " Would you like to download and update now? (y/n): " confirm
209+ if [[ ! " $confirm " =~ ^[yY]$ ]]; then
171210 echo " Skipping update."
172211 return 0
173212 fi
213+ local SCRIPT_URL=" https://raw.githubusercontent.com/buildplan/restic-backup-script/main/restic-backup.sh"
214+ local CHECKSUM_URL=" ${SCRIPT_URL} .sha256"
174215 local temp_script temp_checksum
175216 temp_script=$( mktemp)
176217 temp_checksum=$( mktemp)
177218 trap ' rm -f "$temp_script" "$temp_checksum"' RETURN
178- local CHECKSUM_URL=" ${SCRIPT_URL} .sha256"
179- local curl_opts=(-sL --fail --retry 3 --retry-delay 2)
180- echo " Downloading script update..."
219+ local curl_opts=(-sL --fail --retry 3 --retry-delay 2 -H " Cache-Control: no-cache" -H " Pragma: no-cache" )
220+ echo " Downloading script update from raw file URL..."
181221 if ! curl " ${curl_opts[@]} " -o " $temp_script " " $SCRIPT_URL " ; then echo " Download failed" ; return 1; fi
182222 if ! curl " ${curl_opts[@]} " -o " $temp_checksum " " $CHECKSUM_URL " ; then echo " Download failed" ; return 1; fi
183223 echo " Verifying downloaded file integrity..."
@@ -272,6 +312,9 @@ display_help() {
272312 echo -e " Verbose diff summary: ${C_GREEN} sudo $prog --verbose --diff${C_RESET} "
273313 echo -e " Fix perms (interactive): ${C_GREEN} sudo $prog --fix-permissions --test${C_RESET} "
274314 echo
315+ echo -e " ${C_BOLD}${C_YELLOW} DEPENDENCIES:${C_RESET} "
316+ echo -e " This script requires: ${C_GREEN} restic, curl, gpg, bzip2, less, jq, flock${C_RESET} "
317+ echo
275318 echo -e " Config: ${C_DIM}${CONFIG_FILE}${C_RESET} Log: ${C_DIM}${LOG_FILE}${C_RESET} "
276319 echo
277320 echo -e " For full details, see the online documentation: \e]8;;${readme_url} \a${C_CYAN} README.md${C_RESET} \e]8;;\a"
@@ -636,22 +679,21 @@ run_preflight_checks() {
636679 # System Dependencies
637680 if [[ " $verbosity " == " verbose" ]]; then
638681 echo -e " \n ${C_DIM} - Checking System Dependencies${C_RESET} "
639- printf " %-65s" " Required commands (restic, curl, flock)..."
682+ printf " %-65s" " Required commands (restic, curl, gpg, bzip2, less, flock, jq )..."
640683 fi
641- local required_cmds=(restic curl flock)
684+ local required_cmds=(restic curl flock jq less gpg bzip2 )
642685 for cmd in " ${required_cmds[@]} " ; do
643686 if ! command -v " $cmd " & > /dev/null; then
644- handle_failure " Required command '$cmd ' not found." " 10"
687+ local install_hint=" On Debian-based systems, try: sudo apt install $cmd "
688+ case " $cmd " in
689+ gpg) install_hint=" On Debian-based systems, try: sudo apt install gnupg" ;;
690+ bzip2) install_hint=" On Debian-based systems, try: sudo apt install bzip2" ;;
691+ less) install_hint=" On Debian-based systems, try: sudo apt install less" ;;
692+ esac
693+ handle_failure " Required command '$cmd ' not found. $install_hint " " 10"
645694 fi
646695 done
647696 if [[ " $verbosity " == " verbose" ]]; then echo -e " [${C_GREEN} OK ${C_RESET} ]" ; fi
648- if [[ " $mode " == " diff" ]]; then
649- if [[ " $verbosity " == " verbose" ]]; then printf " %-65s" " jq command for --diff..." ; fi
650- if ! command -v jq & > /dev/null; then
651- handle_failure " 'jq' is required for the --diff command. Install on Debian based system with sudo apt install jq" " 10"
652- fi
653- if [[ " $verbosity " == " verbose" ]]; then echo -e " [${C_GREEN} OK ${C_RESET} ]" ; fi
654- fi
655697 # --- Performance Settings Validation ---
656698 if [[ " $verbosity " == " verbose" ]]; then echo -e " \n ${C_DIM} - Checking Performance Settings${C_RESET} " ; fi
657699 local numeric_vars=(" GOMAXPROCS_LIMIT" " LIMIT_THREADS" " LIMIT_UPLOAD" " SFTP_CONNECTIONS" )
0 commit comments