Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/rear/rear into aussendorf
Browse files Browse the repository at this point in the history
  • Loading branch information
aussendorf committed Jan 17, 2017
2 parents 563d9e2 + 78ce953 commit 91f668f
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 30 deletions.
7 changes: 3 additions & 4 deletions usr/share/rear/conf/default.conf
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ USB_FILES=()
# In contrast when USB_SUFFIX is set, backup on USB works in compliance with how backup on NFS works
# (i.e. BACKUP_URL=usb:... and BACKUP_URL=nfs:... behave compatible when USB_SUFFIX is set)
# which means a fixed backup directory of the form rear/HOSTNAME/USB_SUFFIX on the USB medium
# and no automated removal of backups or other stuff (regardless of USB_RETAIN_BACKUP_NR)
# and no automated removal of backups or other files (regardless of USB_RETAIN_BACKUP_NR)
# see https://github.com/rear/rear/issues/1164
# Using multiple backups as described in doc/user-guide/11-multiple-backups.adoc
# requires a fixed backup directory so that USB_SUFFIX must be set for multiple backups on USB
Expand All @@ -374,9 +374,8 @@ USB_FILES=()
USB_SUFFIX=""

# Number of older rescue environments or backups to retain on USB.
# The default USB_RETAIN_BACKUP_NR=2 means that there is at most
# the latest (current) rescue environment or backup plus
# the second eldest and the third eldest (three all together):
# What is more than USB_RETAIN_BACKUP_NR gets automatically removed.
# This setting is ignored when USB_SUFFIX is set (see above).
USB_RETAIN_BACKUP_NR=2

# Define the default WORKFLOW for the udev handler (empty to disable)
Expand Down
31 changes: 24 additions & 7 deletions usr/share/rear/prep/NETFS/default/070_set_backup_archive.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,27 @@ local backup_directory=$BUILD_DIR/outputfs/$NETFS_PREFIX

# Normal (i.e. non-incremental/non-differential) backup:
if ! test "incremental" = "$BACKUP_TYPE" -o "differential" = "$BACKUP_TYPE" ; then
backuparchive="$backup_directory/$backup_file_name"
# In case of normal (i.e. non-incremental) backup there is only one restore archive
# and its name is the same as the backup archive (usually 'backup.tar.gz'):
RESTORE_ARCHIVES=( "$backuparchive" )
LogPrint "Using backup archive '$backup_file_name'"
backuparchive="$backup_directory/$backup_file_name"
LogPrint "Using backup archive '$backuparchive'"
# This script is also run during "rear recover/restoreonly" where RESTORE_ARCHIVES must be set.
local backup_restore_workflows=( "recover" "restoreonly" )
if IsInArray $WORKFLOW ${backup_restore_workflows[@]} ; then
# Only set RESTORE_ARCHIVES the backup archive is actually accessible
# cf. https://github.com/rear/rear/issues/1166
if test -r "$backuparchive" ; then
RESTORE_ARCHIVES=( "$backuparchive" )
else
# In case of USB backup there is the subsequent 540_choose_backup_archive.sh script
# that shows a backup selection dialog when RESTORE_ARCHIVES is not already set.
if test "usb" = "$scheme" ; then
LogPrint "Backup archive '$backuparchive' not readable. Need to select another one."
else
Error "Backup archive '$backuparchive' not readable."
fi
fi
fi
return
fi

Expand Down Expand Up @@ -137,7 +153,8 @@ local date_time_glob_regex="$date_glob_regex-[0-9][0-9][0-9][0-9]"
local create_backup_type=""
# Code regarding creating a backup is useless during "rear recover" and
# messages about creating a backup are misleading during "rear recover":
if ! test "recover" = "$WORKFLOW" ; then
local recovery_workflows=( "recover" "layoutonly" "restoreonly" )
if ! IsInArray $WORKFLOW ${recovery_workflows[@]} ; then
# When today is a specified full backup day, do a full backup in any case
# (regardless if there is already a full backup of this day):
if IsInArray "$current_weekday" "${FULLBACKUPDAY[@]}" ; then
Expand All @@ -161,7 +178,7 @@ if test "$latest_full_backup" ; then
local full_or_incremental_backup_glob_regex="$date_time_glob_regex-[$full_backup_marker$incremental_backup_marker]$backup_file_suffix"
# Code regarding creating a backup is useless during "rear recover" and
# messages about creating a backup are misleading during "rear recover":
if ! test "recover" = "$WORKFLOW" ; then
if ! IsInArray $WORKFLOW ${recovery_workflows[@]} ; then
# There is nothing to do here if it is already decided that
# a full backup must be created (see "full backup day" above"):
if ! test "full" = "$create_backup_type" ; then
Expand Down Expand Up @@ -215,7 +232,7 @@ if test "$latest_full_backup" ; then
else
# Code regarding creating a backup is useless during "rear recover" and
# messages about creating a backup are misleading during "rear recover":
if ! test "recover" = "$WORKFLOW" ; then
if ! IsInArray $WORKFLOW ${recovery_workflows[@]} ; then
# If no latest full backup is found create one during "rear mkbackup":
create_backup_type="full"
LogPrint "No full backup found (YYYY-MM-DD-HHMM-F.tar.gz) triggers full backup"
Expand All @@ -235,7 +252,7 @@ else
fi
# Code regarding creating a backup is useless during "rear recover" and
# messages about creating a backup are misleading during "rear recover":
if ! test "recover" = "$WORKFLOW" ; then
if ! IsInArray $WORKFLOW ${recovery_workflows[@]} ; then
# Set the right variables for creating a backup (but do not actually do anything at this point):
case "$create_backup_type" in
(full)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@

# In case of backup on USB let the user choose which backup will be restored.
# In case of backup restore from USB let the user choose which backup will be restored.
# This script is only run during a backup restore workflow (recover/restoreoly)
# so that RESTORE_ARCHIVES is set in this script.

scheme=$( url_scheme "$BACKUP_URL" )
# Skip if not backup on USB:
Expand All @@ -9,44 +11,85 @@ test "usb" = "$scheme" || return
# backup on USB works in compliance with backup on NFS which means
# a fixed backup directory where the user cannot choose the backup
# because what there is in the fixed backup directory will be restored
# via RESTORE_ARCHIVES in usr/share/rear/prep/NETFS/default/070_set_backup_archive.sh
# via RESTORE_ARCHIVES set by usr/share/rear/prep/NETFS/default/070_set_backup_archive.sh
# Use plain $USB_SUFFIX and not "$USB_SUFFIX" because when USB_SUFFIX contains only blanks
# test "$USB_SUFFIX" would result true because test " " results true:
test $USB_SUFFIX && return

# When backup on USB works in its default mode with several timestamp backup directories
# let the user choose the backup regardless whether or not RESTORE_ARCHIVES
# is already set by usr/share/rear/prep/NETFS/default/070_set_backup_archive.sh
# because when the user has created a backup plus recovery system via "rear mkbackup"
# and afterwards a newer backup without recovery system via "rear mkbackuponly"
# then the recovery system directory contains the (older) backup and that one gets
# set in RESTORE_ARCHIVES by usr/share/rear/prep/NETFS/default/070_set_backup_archive.sh
# but probably the user wants to choose the newer backup to be actually restored.

# Detect all backups on the USB device.
# FIXME: This fails when the backup archive name is not
# TODO: This fails when the backup archive name is not
# ${BACKUP_PROG_ARCHIVE}${BACKUP_PROG_SUFFIX}${BACKUP_PROG_COMPRESS_SUFFIX}
# so that in particular it fails for incremental/differential backups
# but incremental/differential backups usually require several backup archives
# to be restored (one full backup plus one differential or several incremental backups)
# cf. RESTORE_ARCHIVES in usr/share/rear/prep/NETFS/default/070_set_backup_archive.sh
# and the code below only works for one single backup archive:
# and the backup selection code below only works to select one single backup archive:
backups=()
backup_times=()
for rear_run in $BUILD_DIR/outputfs/rear/$HOSTNAME/* ;do
Debug "Relax-and-Recover run $rear_run detected."
for rear_run in $BUILD_DIR/outputfs/rear/$HOSTNAME/* ; do
Debug "Relax-and-Recover run '$rear_run' detected."
backup_name=$rear_run/${BACKUP_PROG_ARCHIVE}${BACKUP_PROG_SUFFIX}${BACKUP_PROG_COMPRESS_SUFFIX}
if [ -e $backup_name ] ; then
Debug "Relax-and-Recover backup $backup_name detected."
backups=( "${backups[@]}" "$backup_name")
backup_times=( "${backup_times[@]}" "${rear_run##*/}")
if test -r "$backup_name" ; then
LogPrint "Backup archive $backup_name detected."
backups=( "${backups[@]}" "$backup_name" )
backup_times=( "${backup_times[@]}" "${rear_run##*/}" )
fi
done

# The user has to choose the backup
# When there is no backup archive detected error out because in this case
# it does not make sense to show a basically empty backup selection dialog
# (strictly speaking a backup selection dialog with the only choice 'Abort').
# For the 'test' one must have all array members as a single word i.e. "${name[*]}"
# because it should succeed when there is any non-empty array member, not necessarily the first one:
test "${backups[*]}" || Error "No '${BACKUP_PROG_ARCHIVE}${BACKUP_PROG_SUFFIX}${BACKUP_PROG_COMPRESS_SUFFIX}' detected in '$BUILD_DIR/outputfs/rear/$HOSTNAME/*'"

# When there is only one backup archive detected use that and do not disrupt
# "rear recover" or "rear restoreonly" with a backup selection dialog
# because what else could the user chose except that one backup
# (it is questionable why there is an 'Abort' choice below):
if test "1" = "${#backups[@]}" ; then
backuparchive=${backups[0]}
RESTORE_ARCHIVES=( "$backuparchive" )
LogPrint "Using backup archive '$backuparchive'."
return
fi

# Let the user choose the backup that should be restored:
LogPrint "Select a backup archive."
select choice in "${backup_times[@]}" "Abort"; do
[ "$choice" != "Abort" ]
StopIfError "User chose to abort recovery."
n=( $REPLY ) # trim blanks from reply
let n-- # because bash arrays count from 0
# Disable printing commands and their arguments as they are executed on stderr
# which could have been enabled when running e.g. "rear -d -D recover"
# to not disturb the select output which also happens on stderr.
# When 'set -x' is set even calling 'set +x 2>/dev/null' would output '+ set +x' but
# http://stackoverflow.com/questions/13195655/bash-set-x-without-it-being-printed
# shows that when 'set -x' is set calling '{ set +x ; } 2>/dev/null' runs silently:
{ set +x ; } 2>/dev/null
select choice in "${backup_times[@]}" "Abort" ; do
test "Abort" = "$choice" && Error "User chose to abort recovery."
# trim blanks from reply
n=( $REPLY )
# bash arrays count from 0
let n--
if [ "$n" -lt 0 ] || [ "$n" -ge "${#backup_times[@]}" ] ; then
LogPrint "Invalid choice $REPLY, please try again or abort."
# direct output to stdout which is fd7 (see lib/_input-output-functions.sh)
# and not using a Print function to always print to the original stdout
# i.e. to the terminal wherefrom the user has started "rear recover":
echo "Invalid choice $REPLY, try again or abort." >&7
continue
fi
LogPrint "Backup archive ${backups[$n]} chosen."
backuparchive=${backups[$n]}
break
done 2>&1
done 2>&7
# Go back from "set +x" to the defaults:
apply_bash_flags_and_options_commands "$DEFAULT_BASH_FLAGS_AND_OPTIONS_COMMANDS"
RESTORE_ARCHIVES=( "$backuparchive" )
LogPrint "Using backup archive '$backuparchive'."

0 comments on commit 91f668f

Please sign in to comment.