Last active
September 5, 2021 15:45
-
-
Save DennisLfromGA/36629fd1a28a451658401b01609bd939 to your computer and use it in GitHub Desktop.
A script to restore brioche containers from brioche backups
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# brio-restore - A script to list brioche backups & restore brioche containers | |
## | |
####################### | |
### Setup variables ### | |
####################### | |
## | |
APPL="${0##*/}" | |
CONTAINERS='' | |
DELAY=5 | |
DOWNLOADS="${DOWNLOADS:-${HOME}/Downloads}" | |
RESTORALS='' | |
USAGE=" | |
==================================================================== | |
= PLEASE NOTE: This script is deprecated and replaced by 'brio-br' = | |
==================================================================== | |
## brio-restore - A script to list brioche backups & restore containers | |
USAGE: ${APPL} restores brioche container backups found under '${DOWNLOADS}' | |
(default: ${HOME}/Downloads) to the named container under '~/brioche/'. | |
The script will prompt for each container before proceeding. | |
NOTE: Will append the last modified date & time to any existing container folders found. | |
Optionally displays the script version, version history & help/usage (this blurb). | |
Options: | |
-c Check for & list backup files found in ${DOWNLOADS} | |
-h Displays this help/usage message and exits | |
-v Displays the current version of '${APPL}' and exits | |
-V Displays version number plus version history & exits | |
==================================================================== | |
= Please install 'brio-br' using 'install.brio-br' = | |
==================================================================== | |
" | |
# VERSION format: "n.n.$(date +%Y%m%d%H%M)" | |
VERSION='3.1.202109051056' | |
VERHIST="\ | |
${APPL}-3.1.202109051056 : This script is deprecated and replaced by 'brio-br' | |
${APPL}-3.0.202109011756 : Renamed script from brioche-restore to brio-restore | |
${APPL}-3.0.202109011756 + and backup file from brioche-... to end with .brio | |
${APPL}-2.4.202109011719 : Add command-line options [-v,-V,-h] | |
${APPL}-2.3.202109011647 : Use 'pv' when installed instead of 'spinner' | |
${APPL}-2.2.202108311120 : Added backup file selection | |
${APPL}-2.1.202108271957 : Cleaned up several routines | |
${APPL}-2.0.202108231443 : Converted conditionals, etc. to functions | |
${APPL}-1.1.202108221629 : Added version and version history | |
${APPL}-1.0.202108201513 : Created $APPL with 1 revision." | |
## Planned revisons: | |
# ${APPL}-4.0. : Combined both brio-backup & brio-restore to brio-br | |
## | |
####################### | |
### Setup functions ### | |
####################### | |
## | |
### functions with b/r prefix are for backup/restore respectively | |
### Following two functions, error & spinner, borrowed from the 'crouton' authors | |
## | |
## exit with exit code $1, spitting out message $@ to stderr | |
echo_e='/bin/echo -e' | |
error() { | |
local ecode="${1}" | |
shift | |
${echo_e} "${*}" 1>&2 | |
exit "${ecode}" | |
} | |
## | |
## Prints out a fancy spinner that updates every time a line is fed in, unless | |
## the output is not to a tty, in which case it just prints a new line. | |
# $1: number of lines between each update of the spinner | |
# $2...: Command to be run | |
# Erases the line each time, so it will always be at position 0. | |
# Either expect this and put text later in the line, or give this its own line. | |
spinner() { | |
local spin="$1" | |
shift | |
if [ -t 2 ]; then | |
# Keep track of the exit status of the piped command | |
local ret="`(("$@" || echo "$?" 1>&3) | mawk -Winteractive ' | |
BEGIN { | |
printf "\r" | |
} | |
{ | |
y = (y+1) % '"$spin"' | |
if (y == 0) { | |
x = (x+1) % 4 | |
printf substr("\|/-", x+1, 1) "\r" | |
} | |
}' 1>&2) 3>&1`" | |
if [ -n "$ret" ]; then | |
return "$ret" | |
fi | |
else | |
echo 1>&2 | |
"$@" 1>/dev/null | |
fi | |
} | |
## | |
check_for_opts() { | |
## Get command line parameters | |
local OPTIND | |
while getopts chvV OPT; do | |
case ${OPT} in | |
c) r_check_for_backups | |
echo; error 0 "${USAGE}";; | |
h) error 0 "$USAGE";; | |
v) echo "$VERHIST" | grep $VERSION 1>&2; exit 0;; | |
V) error 0 "VERSION:${VERSION}\n${VERHIST}" ;; | |
\?) error 2 "$USAGE";; | |
esac | |
done | |
shift "$((OPTIND-1))" | |
} | |
## | |
r_check_for_downloads() { | |
if [ ! -d ${DOWNLOADS} ]; then | |
echo "Sorry, no '${DOWNLOADS}' directory exists." | |
echo "If your backups are somewhere else please either move them under ${DOWNLOADS}" | |
error 1 "or invoke this script with 'DOWNLOADS=[path-to-backups-folder] ${APPL}'". | |
fi | |
} | |
## | |
r_check_for_backups() { | |
local CONT REST | |
cd ${DOWNLOADS} | |
for REST in $(ls *.brio 2>/dev/null); do | |
CONT=$(echo ${REST} | cut -d '.' -f1) | |
CONTAINERS="${CONTAINERS} ${CONT}," | |
done | |
CONTAINERS="$(echo "${CONTAINERS}" | tr ',' '\n' | sort -u | tr '\n' ',')" | |
if [ -n "${CONTAINERS}" ]; then | |
CONTAINERS="$(echo ${CONTAINERS}|sed 's/^,//; s/,$//')" | |
echo "Backups found for brioche container(s)${CONTAINERS} - see below:" | |
echo "(if multiple backups are found for the same container then you can select one from a list.)" | |
echo | |
ls -ltr *.brio 2>/dev/null | |
else | |
echo "No brioche container backups found ..." | |
error 1 "Note: They should be named: '[CONTAINER_NAME].[DATE-TIME].brio" | |
fi | |
} | |
## | |
r_check_for_containers() { | |
local CONT EXIST | |
if [ ! -d ${HOME}/brioche ]; then | |
echo "No '~/brioche/' directory exists, making one now ..." | |
mkdir -p ${HOME}/brioche | |
else | |
echo | |
echo "Found '~/brioche/' directory ..." | |
fi | |
sudo chown chronos:root ${HOME}/brioche | |
cd ${HOME}/brioche/ | |
CONTAINERS="$(echo ${CONTAINERS}|sed 's/,/ /')" | |
for CONT in ${CONTAINERS}; do | |
if [ -d "${CONT}" ]; then | |
EXIST="${EXIST}, ${CONT}" | |
fi | |
done | |
EXIST="$(echo ${EXIST}|sed 's/^,//; s/,$//')" | |
echo | |
echo "These corresponding brioche containers exist and if selected for restoral will be" | |
echo "be renamed to have their last modified date & time appended to them: ${EXIST}" | |
} | |
## | |
r_ask_for_restoral() { | |
local BEGIN CONT NMBR RESP REST | |
cd ${DOWNLOADS} | |
for CONT in ${CONTAINERS}; do | |
NMBR="$(ls -1 ${CONT}*.brio 2>/dev/null|wc -l)" | |
if [ "${NMBR}" -gt 1 ]; then | |
echo | |
echo "There were ${NMBR} backups found for '${CONT}'." | |
echo "Restore one of the '${CONT}' brioche backups to ~/brioche/${CONT} [Ysra] ?" | |
else | |
REST="$(ls -tr ${CONT}*.brio 2>/dev/null)" | |
echo | |
echo "Restore brioche backup '${REST}' to ~/brioche/${CONT} [Ysra] ?" | |
fi | |
read -n 1 -p "PRESS 'y' to restore, 's' to SKIP, 'r' to RESTART or 'a' to ABORT/QUIT! " RESP | |
if [ -n "${RESP}" ]; then | |
case ${RESP} in | |
[yY]) | |
echo; echo "Got '${RESP}', '${CONT}' added to restorals ..." | |
RESTORALS="${RESTORALS} ${CONT}," | |
;; | |
[sS]|[nN]) | |
echo; echo "Got '${RESP}', so Skipping '${CONT}' ..." | |
continue | |
;; | |
[rR]) | |
echo; echo "Got '${RESP}', so Restarting ..." | |
CONT=''; NMBR=''; RESP=''; REST=''; RESTORALS='' | |
r_ask_for_restoral | |
;; | |
[aA]|[xX]) | |
echo; echo -n "Got '${RESP}, '" | |
error 0 "okay, ABORTING/QUITTING ..." | |
;; | |
*) | |
echo; echo "Got '${RESP}', no such option '${RESP}' ..." | |
echo "Only 'y' to restore, 's' to SKIP, 'r' to RESTART or 'a' to ABORT/QUIT are accepted." | |
error 1 "${USAGE}" | |
;; | |
esac | |
else | |
echo; echo "Got 'ENTER', '${CONT}' added to restorals ..." | |
RESTORALS="${RESTORALS} ${CONT}," | |
fi | |
done | |
RESTORALS="$(echo ${RESTORALS}|sed 's/^ //; s/,$//g')" | |
echo | |
echo -n "Ready to restore container(s) '${RESTORALS}' - press 'ENTER' to begin or 'Ctrl-C' to ABORT/QUIT: " | |
read BEGIN | |
} | |
## | |
r_do_restoral() { | |
local CONT DIRDATE FILES NMBR PS3 REST | |
RESTORALS="$(echo ${RESTORALS}|sed 's/,//g')" | |
cd ${DOWNLOADS} | |
for CONT in ${RESTORALS}; do | |
NMBR="$(ls -1 ${CONT}*.brio 2>/dev/null|wc -l)" | |
if [ "${NMBR}" -gt 1 ]; then | |
echo | |
echo "More than one backup for '${CONT}' exists, please select one from the list below:" | |
echo "(the backup files are listed in chronogical order, #1 will be the most recent.)" | |
FILES="$(ls -1Ar ${CONT}*.brio)" | |
PS3="Choose one of the above backup files to restore to the '${CONT}' container,"$'\n'"or select Skip, Restart, or Abort/Quit ? " | |
echo | |
select REST in ${FILES} Skip Restart Abort/Quit; do | |
if [ -z "$REST" ] ; then | |
echo "[ERROR] Invalid option" | |
continue | |
fi | |
case "$REST" in | |
Skip) | |
echo; echo "Got '${REST}', so Skipping '${CONT}' ..." | |
continue 2 | |
;; | |
Restart) | |
echo; echo "Got '${REST}', so Restarting ..." | |
CONT=''; FILES=''; NMBR=''; PS3=''; REST=''; RESTORALS='' | |
r_ask_for_restoral | |
;; | |
Abort/Quit) | |
echo; echo -n "Got '${REST}, '" | |
error 0 "okay, Aborting/Quitting ..." | |
;; | |
*) echo "Brunch backup file selected: $REST" | |
RESTORALS="${RESTORALS} ${CONT}," | |
break | |
;; | |
esac | |
done | |
echo | |
else | |
REST="$(ls -tr ${CONT}*.brio 2>/dev/null)" | |
fi | |
if [ ! -d ${HOME}/brioche/${CONT} ]; then | |
echo | |
echo "No '~/brioche/${CONT}' directory exists, making one now ..." | |
else | |
echo | |
DIRDATE="$(date -r ${HOME}/brioche/${CONT} '+%Y%m%d%H%M')" | |
echo "WARNING: A brioche container '${CONT}' already exists, it is being renamed: ${CONT}.${DIRDATE} ..." | |
mv -n ${HOME}/brioche/${CONT} ${HOME}/brioche/${CONT}.${DIRDATE} | |
echo "Stopping '${CONT}' - just in case ..." | |
brioche ${CONT}.${DIRDATE} stop 2>/dev/null | |
sleep ${DELAY} | |
fi | |
mkdir -p ${HOME}/brioche/${CONT} | |
sudo chown chronos:root ${HOME}/brioche/${CONT} | |
echo "Restoring '${REST}' to '~/brioche/${CONT}' ..." | |
trap "sudo rm -f '${HOME}/brioche/${CONT}; \ | |
mv -f ${HOME}/brioche/${CONT}.${DIRDATE} ${HOME}/brioche/${CONT} 2>/dev/null \ | |
error 2 \"Restoral up of '${CONT}' aborted, container deleted!\"" INT HUP TERM 0 | |
if type -P pv 1>/dev/null; then | |
# "'pv' is installed." | |
sudo pv -Ws $(du -s ${REST} | awk '{print $1}') ${REST} | \ | |
tar -zx -C . || FAILED="${FAILED} ${CONT}" | |
if echo ${FAILED} | grep -q ${CONT}; then | |
mv -f ${HOME}/brioche/${CONT}.${DIRDATE} ${HOME}/brioche/${CONT} 2>/dev/null | |
echo "Restoral of '${CONT}' failed!" | |
else | |
RESTORED="${RESTORED} ${CONT}," | |
fi | |
else | |
# "'pv' is NOT installed." | |
spinner 10 sudo tar --checkpoint=10 --checkpoint-action=exec=echo --numeric-owner \ | |
-xzf ${REST} -C ${HOME}/brioche/${CONT} 1>&2 || FAILED="${FAILED} ${CONT}" | |
if echo ${FAILED} | grep -q ${CONT}; then | |
mv -f ${HOME}/brioche/${CONT}.${DIRDATE} ${HOME}/brioche/${CONT} 2>/dev/null | |
echo "Restoral of '${CONT}' failed!" | |
else | |
RESTORED="${RESTORED} ${CONT}," | |
fi | |
fi | |
trap - INT HUP TERM 0 | |
RESTORED="$(echo ${RESTORED}|sed 's/^ //')" | |
FAILED="$(echo ${FAILED}|sed 's/^ //')" | |
echo "Restoral of '${CONT}' finished ..." | |
sudo chown chronos:root ${HOME}/brioche/${CONT} | |
done | |
} | |
## | |
r_report_results() { | |
echo | |
if [ -n "${FAILED}" ]; then | |
echo "Restoral FAILED for brioche container(s) ${FAILED} !" | |
fi | |
if [ -n "${RESTORED}" ]; then | |
RESTORED="$(echo ${RESTORED}|sed 's/,$//')" | |
echo "Retorals complete for brioche container(s) ${RESTORED}" | |
echo | |
ls -l ${HOME}/brioche/ | |
else | |
echo "No brioche container restored ..." | |
fi | |
} | |
## | |
#################### | |
### Main section ### | |
#################### | |
## | |
check_for_opts "$@" | |
error 0 "${USAGE}" | |
## | |
if [ ${UID:-$(id -u)} -eq 0 ]; then | |
echo | |
echo "ERROR: ${APPL} must NOT be run as root!" | |
error 1 "${USAGE}" | |
fi | |
r_check_for_downloads | |
r_check_for_backups | |
r_check_for_containers | |
r_ask_for_restoral | |
r_do_restoral | |
r_report_results | |
echo | |
exit 0 |
PLEASE NOTE: This script is deprecated and replaced by 'brio-br'
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Inadvertently replaced brioche-restore with brioche-backup, this revision reverts that change.