scripts/borg_pull.sh
2025-04-01 21:09:43 +02:00

188 lines
5.8 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# This script requires SSHFS and Borg.
# It backs up data from a remote location to a local repository.
# =============
# CONFIGURATION
# =============
# Hostname, domain name, or IP address of the machine where the data to be backed up resides.
DATA_HOST="5ccppi"
# White-space-delimited list of absolute paths of directories on the remote machine to be backed up.
DATA_PATHS=( "/home/ccppi" "/var/lib" "/etc" )
PRENAMEARCHIVE="linode"
# Absolute local path where the remote system will be temporarily mounted locally.
# The directory will be created. Pick someplace to which you have write access.
SSHFS_MOUNTPOINT="/tmp/sshfs-tmp-borg_pull"
# The username for the account on the remote machine as which well be loggin in via SSH.
SSHFS_USER="user"
SSHFS_PORT="0000"
# The absolute local path for the directory where the backups will be stored.
BACKUP_ROOT="/mnt/backup/borg-linode"
# A command to generate the date stamp that will appear in a backups title.
BACKUP_DATE=$(date +"%Y-%m-%d_%H:%M")
# Whether or not to compacts repositories after backing up. I havent tested this
# because I have an older version of Borg that doesnt support compacting.
#COMPACT_REPOS="false"
DAILIES_TO_RETAIN="7"
WEEKLIES_TO_RETAIN="4"
# This script is intended to be run unattended. If this option is set to “true”,
# the script will pause for a few seconds before exiting if everything is successful,
# and wait for user input before exiting if anything goes wrong.
LINGER_ON_EXIT="true"
EMPHASIS_COLOR="\e[36m"
ERROR_COLOR="\e[91m"
SUCCESS_COLOR="\e[32m"
PROMPT_COLOR="\e[30;106m"
# =============
# Mise en place
# =============
NO_COLOR="\e[0m"
ERRORLEVEL=0
SUCCESSES="false"
PROBLEMS="false"
declare -A STATA
_backup() {
DATA_PATH=$1
FULL_REPO_PATH="${BACKUP_ROOT}"
#/${DATA_HOST}${DATA_PATH}"
printf "Backing up ${EMPHASIS_COLOR}%s%s${NO_COLOR}\nto %s%s...\n" "$DATA_HOST" "$DATA_PATH" "$BACKUP_ROOT"
if borg create --stats --progress --exclude /*/lost+found "$FULL_REPO_PATH"::"$PRENAMEARCHIVE""-""${DATA_PATH////-}""$BACKUP_DATE" "$SSHFS_MOUNTPOINT""$DATA_PATH"
then printf "%bSuccess.%b\n\n" "$SUCCESS_COLOR" "$NO_COLOR"
STATA["${DATA_PATH}"]="SUCCESS"
SUCCESSES="true"
if [[ $COMPACT_REPOS == "true" ]]
then borg --progress compact "$FULL_REPO_PATH"
fi
printf "Pruning %s...\n" "$FULL_REPO_PATH"
if ! borg prune --keep-daily="$DAILIES_TO_RETAIN" --keep-weekly="$WEEKLIES_TO_RETAIN" "$FULL_REPO_PATH"
then ERRORLEVEL=1
PROBLEMS="true"
fi
printf "\n"
else STATA["${DATA_PATH}"]="$?"
ERRORLEVEL=1
PROBLEMS="true"
printf "\n"
fi
}
_delete_mountpoint() {
if [[ ! "$(ls -A $SSHFS_MOUNTPOINT)" ]]
then printf "Deleting mountpoint %s...\n" "$SSHFS_MOUNTPOINT"
if rmdir "$SSHFS_MOUNTPOINT"
then printf "Deleted.\n\n"
else printf "%bFailed to delete the mountpoint.%b\n\n" "$ERROR_COLOR" "$NO_COLOR"
ERRORLEVEL=1
fi
else printf "%bNot deleting the mountpoint at %s\nbecause it looks like theres still something in it. Weird.%b\n\n" "$ERROR_COLOR" "$SSHFS_MOUNTPOINT" "$NO_COLOR"
ERRORLEVEL=1
fi
}
_exit() {
if [[ $ERRORLEVEL -eq 0 ]]
then if [[ $LINGER_ON_EXIT == "true" ]]
then printf "%bThis message will self-destruct.%b\n\n" "$PROMPT_COLOR" "$NO_COLOR"
sleep 5
exit 0
fi
elif [[ $LINGER_ON_EXIT == "true" ]]
then printf "%b" "$PROMPT_COLOR"
read -n1 -r -p "Press Enter to dismiss." input
printf "%b\n" "$NO_COLOR"
if [[ $input = "" ]]
then exit 1
else _exit
fi
exit 1
fi
}
# ====
# Prep
# ====
printf "\nWere about to back up the following remote directories from %b%s%b:\n" "$EMPHASIS_COLOR" "${DATA_HOST}" "$NO_COLOR"
for i in "${DATA_PATHS[@]}"
do
printf "• %b%s%b\n" "$EMPHASIS_COLOR" "${i}" "$NO_COLOR"
done
printf "\n"
if [[ ! -d "$SSHFS_MOUNTPOINT" ]]
then printf "Creating mountpoint %s...\n" "$SSHFS_MOUNTPOINT"
if mkdir "$SSHFS_MOUNTPOINT"
then printf "Success.\n\n"
else printf "%bWe seem to be having trouble creating the SSHFS mountpoint. Aborting!%b\n\n" "$ERROR_COLOR" "$NO_COLOR"
ERRORLEVEL=1
_exit
fi
fi
printf "Mounting %s at %s...\n" "$DATA_HOST" "$SSHFS_MOUNTPOINT"
if sshfs -o ro,port="$SSHFS_PORT" "$SSHFS_USER"@"$DATA_HOST":/ "$SSHFS_MOUNTPOINT"
then printf "Success.\n\n"
else printf "%bWe seem to be having trouble mounting the remote remote file system.%b\n\n" "$ERROR_COLOR" "$NO_COLOR"
ERRORLEVEL=1
_delete_mountpoint
_exit
fi
# =================
# Backup operations
# =================
for i in "${DATA_PATHS[@]}"
do
_backup "$i"
done
# ==========
# Denouement
# ==========
printf "Unmounting %s from %s...\n" "$DATA_HOST" "$SSHFS_MOUNTPOINT"
if fusermount -u "$SSHFS_MOUNTPOINT"
then printf "Success.\n\n"
_delete_mountpoint
else printf "%bWere having trouble unmounting the remote file system at %s.\n" "$ERROR_COLOR" "$SSHFS_MOUNTPOINT"
printf "Youll probably want to have a look at it.%b\n\n" "$NO_COLOR"
ERRORLEVEL=1
fi
printf "%b==========\nCONCLUSION\n==========%b\n\n" "${EMPHASIS_COLOR}" "$NO_COLOR"
if [[ $SUCCESSES == "true" ]]
then printf "The following locations backed up successfully:\n"
for i in "${DATA_PATHS[@]}"
do
if [[ ${STATA[${i}]} == "SUCCESS" ]]
then printf "• %b%s%b\n" "$EMPHASIS_COLOR" "$i" "$NO_COLOR"
fi
done
printf "\n"
fi
if [[ $PROBLEMS == "true" ]]
then printf "The following locations experienced issues:\n"
for i in "${DATA_PATHS[@]}"
do
if [[ ! ${STATA[${i}]} == "SUCCESS" ]]
then printf "• %b%s%b\n" "$ERROR_COLOR" "$i" "$NO_COLOR"
fi
done
printf "\n"
fi
_exit