#!/bin/bash # ================================================================================ # # RESTORE - interactive restore # # Restore duplicity backup data to a local directory. # Please notice: duplicity does not overwrite any dir or file. So the restore # path is different to the path of the backed up data. # # SYNTAX: # restore.sh [path-to-restore] # # path-to-restore - optional # default: none ... you get an interactive selection of backup sets # # -------------------------------------------------------------------------------- # ah - Axel Hahn <axel.hahn@iml.unibe.ch> # ds - Daniel Schueler <daniel.schueler@iml.unibe.ch> # # 2016-11-17 ah,ds v1.0 # 2017-10-11 ah,ds v1.1 added support for duplicity param --ssh-backend # 2018-08-27 ah,ds v1.2 fix restore target with a given selection; handle '*' placeholder # 2019-06-05 ah,ds v1.3 add custom cache dir # 2021-05-19 ah,ds, v2.0 plugin driven # ================================================================================ # -------------------------------------------------------------------------------- # CONFIG # -------------------------------------------------------------------------------- # . `dirname $0`/inc_config.sh . `dirname $0`/jobhelper.sh . `dirname $0`/inc_bash.sh # --- load a transfer plugin STORAGE_BIN=`_j_getvar ${STORAGEFILE} "bin"` if [ -z "$STORAGE_BIN" ]; then # STORAGE_BIN=restic STORAGE_BIN=duplicity fi CFGPREFIX=${STORAGE_BIN}_ . `dirname $0`/plugins/transfer/$STORAGE_BIN.sh || exit 1 # --- get backend url of backup data STORAGE_BASEDIR=`_j_getvar ${STORAGEFILE} "storage"` if [ -z $STORAGE_BASEDIR ]; then echo ERROR: missing config for backup target. echo There must be an entry storage in ${STORAGEFILE} exit 1 fi # target directory of directory specific repository STORAGE_TARGETPATH= PASSPHRASE=`_j_getvar ${STORAGEFILE} "passphrase"` # timestamp or snapshot id RESTORE_ITEM= # include filter to restore a part of the backup set RESTORE_FILTER= # full path of restore data RESTORE_BASEDIR=`_j_getvar ${STORAGEFILE} "restore-path"` RESTORE_TARGETPATH= # set vars for transfer plugin t_setVars || exit 1 # ----- Create default command line parameters ARGS_DEFAULT="$( t_getParamDefault $1 $2 )" sFileSshPrivkey=`_j_getvar ${STORAGEFILE} "ssh-privatekey"` if [ ! -z $sFileSshPrivkey ]; then ARGS_DEFAULT="${ARGS_DEFAULT} $( t_getParamSshKey $sFileSshPrivkey )" fi # task#3046 - add custom cache dir sCacheDir=`_j_getvar ${STORAGEFILE} "cachedir"` ARGS_DEFAULT="${ARGS_DEFAULT} $( t_getParamCacheDir $sCacheDir )" # ----- what to restore ... BACKUP_DIR= # -------------------------------------------------------------------------------- # FUNCTIONS # -------------------------------------------------------------------------------- # ---------------------------------------------------------------------- # enter name of directory to restore; menu item # ---------------------------------------------------------------------- function enterBackupDir(){ h2 "select a directory to be restored" echo "This is a list of the directories from the backup configuration." echo "Enter the full path" echo echo "Enter the full path; marked entries with (*) do not exist on this machine" echo local sDirs="`j_getDirs2Backup`" for mydir in $sDirs do if [ ! -d "$mydir" ]; then color error echo "$mydir (*)" color reset else echo "$mydir" fi done color input echo -n "[$BACKUP_DIR] >" color reset read myinput setBackupDir "${myinput}" } # ---------------------------------------------------------------------- # set backup dir .. called when using cli parameter or enterBackupDir # param string full path of a directory to retore # ---------------------------------------------------------------------- function setBackupDir(){ if [ ! -z $1 ]; then sDirs2Backup="`j_getDirs2Backup`" bFound=0 for mydir in ${sDirs2Backup} do if [ "${mydir}" = "${1}" ]; then bFound=1 fi done if [ $bFound -eq 0 ]; then color error echo echo "WARNING: seems to be wrong ... " echo "At the moment I restore only known targets." color reset # TODO: if we want to retore other backup sets of other servers # we cannot be as strict else BACKUP_DIR=$1 setVars fi fi } # ---------------------------------------------------------------------- # internal: set variables for target path and backup set # ---------------------------------------------------------------------- # set backup url and local restore path (based on given backup directory) function setVars(){ local sSafeName=`j_getSafename "$BACKUP_DIR"` RESTORE_TARGETPATH="${RESTORE_BASEDIR}/${sSafeName}" STORAGE_TARGETPATH="$( t_backupDirGetTarget $BACKUP_DIR )" } # actions for restore function doRestore(){ local restorecmd=$( t_restoreDoRestore ) if [ -z "$restorecmd" ]; then color error echo "ERROR: There is no restore command ... " echo "A developer must check t_restoreDoRestore in plugins/transfer/$STORAGE_BIN.sh" color reset exit 1 fi mkdir -p "${RESTORE_TARGETPATH}" echo $restorecmd color cmd $restorecmd fetchrc color reset t_rcCheckRestore $myrc echo echo echo Restore is finished. echo Have look to the output above. echo "The restore path has `find ${RESTORE_TARGETPATH} | wc -l` items (`du -hs ${RESTORE_TARGETPATH} | awk '{ print $1 }'`)" echo echo find ${RESTORE_TARGETPATH} exit } # -------------------------------------------------------------------------------- # MAIN # -------------------------------------------------------------------------------- # ----- set a directory to restore to have a useful initial point t_checkRequirements setBackupDir $1 if [ -z $BACKUP_DIR ]; then enterBackupDir fi # ----- menu and loop while true do h1 "Restore :: Menu" echo " D - directory to restore: $BACKUP_DIR" echo -n " W - time or snapshot ID : $RESTORE_ITEM" test -z "$RESTORE_ITEM" && echo -n " ... set one first" test -z "$RESTORE_ITEMINFO" || echo -n " ($RESTORE_ITEMINFO)" echo echo -n " F - what to restore : $RESTORE_FILTER" test -z "$RESTORE_FILTER" && echo -n "(no filter = restore all files)" echo echo echo " M - mount backup" # echo " C - show file changes" # echo " S - search file" # echo " V - verify" # echo " B - Bash (Shell)" # echo echo " R - start restore with $STORAGE_BIN" echo echo " restore from : $STORAGE_TARGETPATH" echo " restore to : $RESTORE_TARGETPATH" echo -n " " ls -d $RESTORE_TARGETPATH >/dev/null 2>&1 if [ $? -eq 0 ]; then color error echo "WARNING: directory already exists! Backup will fail." color reset else echo "OK, it does not exist yet" fi echo echo " X - exit" echo showPrompt "Select (not case sensitive) --> " read action echo case $action in d|D) enterBackupDir ;; w|W) h2 "Set a time / select a snapshot" t_restoreDoSelect ;; c|C) showFilechanges ;; m|M) h2 "Mount backup data" t_restoreDoMountBackupdata ;; s|S) h2 "Search a file" filefilter=".*" showPrompt "Regex for filefilter; ${filefilter} for all >" read filefilter test -z "${filefilter}" || t_restoreDoSearchFile "${filefilter}" ;; v|V) verify ;; b|B) h2 "Shell" echo type exit to return... export PS1="[`basename $0` \u@\h \w]\$ " bash ;; f|F) h2 "Filter restore items" echo "By default all files will be restored." echo "You can limit it by setting include rules." t_restoreDoSetIncludeFilter ;; r|R) h2 "Start restore" doRestore ;; x|X) exit 0 ;; *) echo "Try again" esac done # --------------------------------------------------------------------------------