Skip to content
Snippets Groups Projects
Commit bc12652d authored by Hahn Axel (hahn)'s avatar Hahn Axel (hahn)
Browse files

add restore (WIP)

parent 62245057
Branches
No related tags found
1 merge request!1Version 2
......@@ -21,6 +21,7 @@
# 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
# ================================================================================
......@@ -33,39 +34,42 @@
. `dirname $0`/jobhelper.sh
. `dirname $0`/inc_bash.sh
STORAGE_BASEDIR=`_j_getvar ${STORAGEFILE} "storage"`
STORAGE_BIN=`_j_getvar ${STORAGEFILE} "bin"`
if [ -z "$STORAGE_BIN" ]; then
STORAGE_BIN=restic
# STORAGE_BIN=duplicity
fi
. `dirname $0`/plugins/transfer/$STORAGE_BIN.sh || exit 1
# check
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
# ----- read something from config files
RESTORE_BASEDIR=`_j_getvar ${STORAGEFILE} "restore-path"`
PASSPHRASE=`_j_getvar ${STORAGEFILE} "gnupg-passphrase"`
PASSPHRASE=`_j_getvar ${STORAGEFILE} "passphrase"`
export PASSPHRASE
sFileSshPrivkey=`_j_getvar ${STORAGEFILE} "ssh-privatekey"`
sParams=
# task#1623 - fallback ssh backend for Debian 8
sSshBackend=`_j_getvar ${STORAGEFILE} "ssh-backend"`
if [ ! -z $sSshBackend ]; then
sParams="${sParams} --ssh-backend $sSshBackend"
fi
t_setVars || exit 1
# ----- init default vars
sParams="$( t_getParamDefault $1 $2 )"
sFileSshPrivkey=`_j_getvar ${STORAGEFILE} "ssh-privatekey"`
if [ ! -z $sFileSshPrivkey ]; then
sParams="${sParams} --ssh-options="""-oIdentityFile=${sFileSshPrivkey}""" "
sParams="${sParams} $( t_getParamSshKey $sFileSshPrivkey )"
fi
# task#3046 - add custom cache dir
sCacheDir=`_j_getvar ${STORAGEFILE} "cachedir"`
if [ ! -z $sCacheDir ]; then
sParams="${sParams} --archive-dir=$sCacheDir"
sParams="${sParams} $( t_getParamCacheDir $sCacheDir )"
fi
# ----- what to restore ...
......@@ -73,7 +77,7 @@
sRestoreItem=
sDate=`date +%Y-%m-%d`
# duplicity target
# target directory of directory specifi repository
sTarget=
# --------------------------------------------------------------------------------
......@@ -94,7 +98,7 @@ function enterBackupDir(){
echo "Enter the full path; marked entries with (*) do not exist on this machine"
echo
sDirs="`j_getDirs2Backup`"
local sDirs="`j_getDirs2Backup`"
for mydir in $sDirs
do
if [ ! -d "$mydir" ]; then
......@@ -115,196 +119,6 @@ function enterBackupDir(){
}
# ----------------------------------------------------------------------
# enter date to restore from; menu item
# ----------------------------------------------------------------------
function enterDate(){
h2 "edit date to restore"
echo "The acceptible time strings are intervals (like \"3D64s\"), w3-datetime"
echo "strings, like \"2002-04-26T04:22:01-07:00\" (strings like"
echo "\"2002-04-26T04:22:01\" are also acceptable - duplicity will use the"
echo "current time zone), or ordinary dates like 2/4/1997 or 2001-04-23"
echo "(various combinations are acceptable, but the month always precedes"
echo "the day)."
echo
echo "today in YYYY-MM-DD: `date +%Y-%m-%d`"
echo
color input
echo -n "[$sDate] >"
color reset
read sNewDate
if [ ! -z $sNewDate ]; then
sDate=$sNewDate
fi
}
# ----------------------------------------------------------------------
# enter relative path to restore; menu item
# ----------------------------------------------------------------------
function enterRestoreitem(){
h2 "set restore item (path)"
echo "enter a relative path behind ${sDir2restore}/"
echo "empty means: all data"
echo
color input
echo -n "[$sRestoreItem] >"
color reset
read sNewsRestoreItem
if [ ! -z $sNewsRestoreItem ]; then
sRestoreItem=$sNewsRestoreItem
setVars
fi
getRemoteFiles
}
# ----------------------------------------------------------------------
# search a file in backup; menu item
# ----------------------------------------------------------------------
function searchFile(){
h2 "search a file in backup --time $sDate"
echo "Enter something that was backuped from ${sDir2restore}"
echo "searchtext matches anywhere in filename or path - it is a grep grep in"
echo "duplicity list-current-files --time $sDate [target]"
echo "Press just Return to exit"
echo
color input
echo -n "search for >"
color reset
read sSearch
if [ ! -z $sSearch ]; then
getRemoteFiles $sSearch
fi
}
# ----------------------------------------------------------------------
# verify backup set with local files; menu item
# ----------------------------------------------------------------------
function verify(){
h2 "verify"
echo duplicity verify ${sParams} ${sTarget} -v4 $sDir2restore
color cmd
duplicity verify ${sParams} ${sTarget} -v4 $sDir2restore
fetchrc
color reset
}
# ----------------------------------------------------------------------
# show file changes in backupsets; menu item
# work in progress ... I don't know how to match a file...
# ----------------------------------------------------------------------
function showFilechanges(){
tmpcache=~/.cache/duplicity-changes-${sSafeName}.txt
h2 "show file changes"
egrep "\ \ (changed|deleted|new)\ \ " `fgrep -l "Localdir ${sDir2restore}" ~/.cache/duplicity/*/*.manifest` >$tmpcache
# ls -l $tmpcache
# head $tmpcache
echo "I hope you made a search first"
echo "Enter filename with complete path that was backuped from ${sDir2restore}"
echo "Press just Return to exit"
echo
color input
echo -n "search for >"
color reset
read sSearch
if [ ! -z "${sSearch}" ]; then
echo grep "${sSearch}"
color cmd
# duplicity collection-status --file-changed "`basename ${sSearch}`" ${sParams} ${sTarget}/`dirname "${sSearch}"`
cat $tmpcache | grep "${sSearch}" | while read line
do
sManifest=`echo $line | cut -f 1 -d ":"`
# duplicity-inc.20161111T152106Z.to.20161111T152141Z.manifest
sTime=`basename "${sManifest}" | cut -f 2 -d "."`
sOut=`echo $line | cut -f 2- -d ":"`
echo $sTime $sOut | sed "s#new#new #"
done | sort
echo
color reset
fi
}
# ----------------------------------------------------------------------
# show remote volumes with incremental and full backups
# ----------------------------------------------------------------------
function getRemoteVolumes(){
tmpoutVolumes=/tmp/outvolumelist_$$
h2 "volumes for $sDir2restore"
echo duplicity collection-status ${sParams} ${sTarget}
color cmd
duplicity collection-status ${sParams} ${sTarget} | tee -a $tmpoutVolumes
fetchrc
color reset
echo
if [ `cat $tmpoutVolumes | egrep "(Full|Incremental)" | wc -l` -eq 0 ]; then
color error
echo "ERROR: no backup sets were found for directory [$sDir2restore]"
echo
color reset
sDir2restore=
setVars
else
color ok
echo "OK, `cat $tmpoutVolumes | grep "Full" | wc -l` Full and `cat $tmpoutVolumes | grep "Incremental" | wc -l` incremental backups"
color reset
fi
rm -f $tmpoutVolumes
}
# ----------------------------------------------------------------------
# list files from backupset
# ----------------------------------------------------------------------
function getRemoteFiles(){
iLines=50
tmpout=/tmp/outfilelist_$$
sSearch=$1
if [ -z $sSearch ]; then
sSearch="^...\ ...\ ..\ ........\ ....\ $sRestoreItem"
fi
echo
echo
echo --- files ... filtered for date [$sDate] by [$sSearch]
echo duplicity list-current-files --time $sDate ${sParams} ${sTarget}
color cmd
duplicity list-current-files --time $sDate ${sParams} ${sTarget} 2>&1 | grep "$sSearch" | tee -a $tmpout | head -$iLines
fetchrc
color reset
if [ `cat $tmpout | wc -l` -eq 0 ]; then
color error
echo ERROR: your file does not match ... try another time ... or another search string
color reset
else
echo ... max $iLines lines ... maybe the output was cut
echo
if [ -z $1 ]; then
echo
doRestoreDryRun
echo
echo
fi
fi
rm -f $tmpout
}
# ----------------------------------------------------------------------
# set backup dir .. called when using cli parameter or enterBackupDir
......@@ -335,20 +149,18 @@ function setBackupDir(){
sDir2restore=$1
setVars
getRemoteVolumes
fi
fi
}
# ----------------------------------------------------------------------
# internal: set variables for target path and backup set to make
# duplicity calls
# internal: set variables for target path and backup set
# ----------------------------------------------------------------------
function setVars(){
sSafeName=`j_getSafename "$sDir2restore"`
sTarget=`j_getFullTarget "$sDir2restore"`
sTarget="$( t_sd_getTarget $sDir2restore )"
# sTarget=`j_getFullTarget "$sDir2restore"`
sRestorepath="${RESTORE_BASEDIR}/${sSafeName}"
if [ ! -z $sRestoreItem ]; then
......@@ -365,32 +177,50 @@ function setVars(){
fi
}
# ----------------------------------------------------------------------
# restore dry run ... called in getRemoteFiles
# ----------------------------------------------------------------------
function doRestoreDryRun(){
echo "--- dry run"
echo duplicity restore --dry-run --file-to-restore "$sRestoreItem" --time $sDate ${sParams} ${sTarget} ${sRestorepath}
color cmd
duplicity restore --dry-run --file-to-restore "$sRestoreItem" --time $sDate ${sParams} ${sTarget} ${sRestorepath}
fetchrc
color reset
}
# --------------------------------------------------------------------------------
# MAIN
# --------------------------------------------------------------------------------
# ----------------------------------------------------------------------
# restore and finish the script; menu item
# ----------------------------------------------------------------------
function doRestore(){
mkdir -p $sRestorepath
h1 "RESTORE - GET FILES FROM STORAGE"
# ----- set a directory to restore to have a useful initial point
setBackupDir $1
if [ -z $sDir2restore ]; then
enterBackupDir
fi
# ----- make inputs
h2 "RESTORE"
t_restoreSelect
t_restoreFilter
echo duplicity restore --file-to-restore "$sRestoreItem" --time $sDate ${sParams} ${sTarget} ${sRestorepath}
# ----- get restore command:
restorecmd=$( t_cmdRestore )
if [ -z "$restorecmd" ]; then
color error
echo "ERROR: no restore command ... "
echo "A developer must check t_inputs4Restore and t_cmdRestore in plugins/transfer/$STORAGE_BIN.sh"
color reset
exit 1
fi
echo
echo --- Restore:
echo $restorecmd
echo "RETURN to start restore ... or Ctrl + C to abort"
read dummy
mkdir -p "${sRestorepath}"
color cmd
duplicity restore --file-to-restore "$sRestoreItem" --time $sDate ${sParams} ${sTarget} ${sRestorepath}
$restorecmd
fetchrc
color reset
t_rcCheckRestore
echo
echo
echo Restore is finished.
......@@ -398,29 +228,9 @@ function doRestore(){
echo "The restore path has `find ${sRestorepath} -type f | wc -l` files (`du -hs ${sRestorepath} | awk '{ print $1 }'`)"
echo
echo find ${sRestorepath}
exit
echo
exit 0
}
# --------------------------------------------------------------------------------
# MAIN
# --------------------------------------------------------------------------------
h1 "RESTORE - GET FILES FROM STORAGE"
# ----- Check requirements
j_requireUser "root"
j_requireBinary "duplicity"
# ----- set a directory to restore to have a useful initial point
setBackupDir $1
if [ -z $sDir2restore ]; then
enterBackupDir
fi
# ----- menu and loop
......@@ -434,18 +244,18 @@ h1 "RESTORE - GET FILES FROM STORAGE"
echo
echo " D - directory to restore: $sDir2restore"
echo " T - time : $sDate"
echo " W - what to restore : $sRestoreItem"
echo
echo " C - show file changes"
echo " S - search file"
echo " V - verify"
echo " B - Bash (Shell)"
echo " W - time or snapshot ID : $RESTORE_ITEM"
echo " F - what to restore : $RESTORE_FILTER"
echo
# echo " C - show file changes"
# echo " S - search file"
# echo " V - verify"
# echo " B - Bash (Shell)"
# echo
echo " R - start restore"
echo
echo " retore from : $sTarget"
echo " retore to : $sRestorepath"
echo " restore from : $sTarget"
echo " restore to : $sRestorepath"
echo -n " "
ls -d $sRestorepath >/dev/null 2>&1
if [ $? -eq 0 ]; then
......@@ -469,8 +279,8 @@ h1 "RESTORE - GET FILES FROM STORAGE"
d|D)
enterBackupDir
;;
t|T)
enterDate
w|W)
t_restoreSelect
;;
c|C)
showFilechanges
......@@ -486,8 +296,8 @@ h1 "RESTORE - GET FILES FROM STORAGE"
export PS1="[`basename $0` \u@\h \w]\$ "
bash
;;
w|W)
enterRestoreitem
f|F)
t_restoreFilter
;;
r|R)
doRestore
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment