Select Git revision
inc_pluginfunctions.md
duplicity.sh 12.19 KiB
#!/bin/bash
# ================================================================================
#
# TRANSFER :: PLUGIN - DUPLICITY
#
# this script will be included in ../../transfer.sh
#
# --------------------------------------------------------------------------------
# ah - Axel Hahn <axel.hahn@iml.unibe.ch>
# 2021-05-19 ah v0.0 INIT ... WIP
# ================================================================================
# --------------------------------------------------------------------------------
# INIT
# --------------------------------------------------------------------------------
# check requirements
function t_checkRequirements(){
j_requireBinary "duplicity"
j_requireUser "root"
}
# set variables
function t_setVars(){
export PASSPHRASE
RESTORE_ITEM=$( date +%Y-%m-%d )
RESTORE_FILTER=
}
# --------------------------------------------------------------------------------
# GENERATE PARAMS :: ALL DIRS
# --------------------------------------------------------------------------------
# return a string with default params
# param string param1 of transfer.sh; one of full|inc|auto
# param string param2 of transfer.sh; for auto: date i.e. 3M for 3 monthes
function t_getParamDefault(){
local _method=
local _sSshBackend=
# --- method
test "$1" = "full" && _method="full"
test "$1" = "auto" && _method="--full-if-older-than $2"
echo -n "$_method"
# --- backend
# task#1623 - fallback ssh backend for Debian 8
_sSshBackend=`_j_getvar ${STORAGEFILE} "${CFGPREFIX}ssh-backend"`
test -z "$_sSshBackend" && _sSshBackend=`_j_getvar ${STORAGEFILE} "volsize"`
if [ ! -z $_sSshBackend ]; then
echo -n " --ssh-backend $_sSshBackend"
fi
# --- verbosity level to fetch changed files from log
echo -n " -v8"
}
# return a string with backup parameters that will be added to defaults
function t_getParamBackup(){
local _volsize=
# --- add asynchronous upload
echo -n " --asynchronous-upload"
# --- volume size
_volsize=`_j_getvar ${STORAGEFILE} "${CFGPREFIX}volsize"`
test -z "$_volsize" && _volsize=`_j_getvar ${STORAGEFILE} "volsize"`
if [ ! -z $_volsize ]; then
echo -n " --volsize ${_volsize}"
fi
}
# return a cli parameter for a single exlude directory
# param string cache directory for local index files
function t_getParamCacheDir(){
if [ ! -z "$1" ]; then
local sCacheDir="$1"
if [ ! -d $sCacheDir ]; then
mkdir -p $sCacheDir
chmod 750 $sCacheDir
fi
echo --archive-dir=$sCacheDir
fi
}
# return a cli parameter for a single exlude directory
# param string exlude pattern
function t_getParamExlude(){
test -z "$1" || echo --exclude-regexp "'"$*"'"
}
# return a cli parameter for a single exlude directory
# param string exlude pattern
function t_getParamInlude(){
test -z "$1" || echo --include-regexp "'"$*"'"
}
# return a cli parameter to use an ssh keyfile
# param string filename if ssh private key file
function t_getParamSshKey(){
test -z "$1" || echo --ssh-options="'"-oIdentityFile=$1"'"
}
# --------------------------------------------------------------------------------
# BACKUP ACTIONS :: TRANSFER
# --------------------------------------------------------------------------------
# pre backup actions
# uses global vars from ../../transfer.sh
function t_backupDoPreTasks(){
echo No PRE actions before starting transfer
}
# post backup actions
# uses global vars from ../../transfer.sh
function t_backupDoPostTasks(){
echo No POST actions after all transfers
}
# --------------------------------------------------------------------------------
# BACKUP ACTIONS :: SINGLE DIR
# --------------------------------------------------------------------------------
# get target url/ directory
# param string directory to backup
function t_backupDirGetTarget(){
# duplicity has a directory based target
j_getFullTarget "$1"
}
# get string with complete backup command
function t_backupDirGetCmdBackup(){
echo duplicity ${ARGS_DEFAULT} ${ARGS_BACKUP} ${mydir} ${STORAGE_TARGETPATH}
}
# pre backup tasks
# uses global vars from ../../transfer.sh
function t_backupDirDoPreTasks(){
# --- for rsync only: create remote directory
echo ${STORAGE_TARGETPATH} | fgrep "rsync://" >/dev/null
if [ $? -eq 0 ]; then
# sshTarget=`echo ${STORAGE_TARGETPATH} | sed "s#rsync://#scp://#"`
# echo Creating remote directory with fetching collection-status on $sshTarget
# color cmd
# duplicity collection-status ${ARGS_DEFAULT} ${sshTarget}
# color reset
sshTarget=`echo ${STORAGE_TARGETPATH} | cut -f 3 -d '/'`
RemoteDir=`echo ${STORAGE_TARGETPATH} | cut -f 4- -d '/'`
cmd="ssh"
if [ ! -z ${sFileSshPrivkey} ]; then
cmd="${cmd} -i ${sFileSshPrivkey}"
fi
cmd="${cmd} ${sshTarget} mkdir -p ${RemoteDir} 2>/dev/null ; ls -ld ${RemoteDir} "
echo Creating remote directory first ...
color cmd
$cmd
color reset
fi
}
# post backup tasks
# uses global vars from ../../transfer.sh
function t_backupDirDoPostTasks(){
local STORAGE_KEEP=`_j_getvar ${STORAGEFILE} "${CFGPREFIX}keep"`
test -z "$STORAGE_KEEP" && STORAGE_KEEP=`_j_getvar ${STORAGEFILE} "keep"`
if [ -z "$STORAGE_KEEP" ]; then
color error
echo ERROR: missing config for backup target.
echo There must be an entry keep in ${STORAGEFILE}
color reset
exit 1
fi
}
# prune old data
# uses global vars from ../../transfer.sh
function t_backupDoPrune(){
echo "--- FORGET some data"
cmd="duplicity remove-older-than $STORAGE_KEEP --force ${ARGS_DEFAULT} ${STORAGE_TARGETPATH}"
echo $cmd
color cmd
$cmd
fetchrc
color reset
t_rcCheckCleanup $myrc
}
# verify backup data
# uses global vars from ../../transfer.sh
function t_backupDoVerify(){
echo "--- VERIFY is not implemented yet for duplicity."
}
# --------------------------------------------------------------------------------
# RESTORE
# --------------------------------------------------------------------------------
# show stored volumes on backup repository
# used in restore; directory param is checked before
# param string name of backup dir, i.e. /etc
function t_restoreDoShowVolumes(){
duplicity collection-status ${ARGS_DEFAULT} ${STORAGE_TARGETPATH}
}
# select a snapshot to restore from
function t_restoreDoSelect(){
local tmpoutVolumes=/tmp/outvolumelist_$$
local _date=
echo "--- Existing snapshots:"
t_restoreDoShowVolumes \
| grep -E "(Full|Incremental).*[0-9][0-9]:[0-9][0-9]:[0-9][0-9]\ " \
| sort -u > $tmpoutVolumes
if [ `cat $tmpoutVolumes | wc -l` -eq 0 ]; then
color error
echo "ERROR: no backup sets were found for directory [$BACKUP_DIR]"
echo
color reset
BACKUP_DIR=
setVars
else
color cmd
cat $tmpoutVolumes
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
echo
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
showPrompt "[$RESTORE_ITEM] >"
read _date
test -z "$_date" && _date=$RESTORE_ITEM
RESTORE_ITEM=$_date
echo using \"$RESTORE_ITEM\"
# RESTORE_ITEMINFO=$( t_restoreDoShowVolumes | grep "^$RESTORE_ITEM" | awk '{ print $2 " " $3} ' )
RESTORE_ITEMINFO=
echo
}
# set a filter to reduce count of files to restore
function t_restoreDoSetIncludeFilter(){
local _inc=
echo "Enter a path behind ${BACKUP_DIR}/"
echo "empty means: all data"
echo
showPrompt "[$RESTORE_FILTER] >"
read _inc
RESTORE_FILTER=
RESTORE_TARGETPATH="${RESTORE_BASEDIR}/${sSafeName}"
if [ ! -z "$_inc" ]; then
echo ${_inc} | grep '\*' >/dev/null
if [ $? -eq 0 ]; then
_inc=`dirname $_inc | sed 's#^\.##'`
color error
echo ERROR: using a placeholder is not allowed. Using the directory above.
echo [$_inc]
color reset
fi
RESTORE_FILTER="--file-to-restore $_inc"
RESTORE_TARGETPATH="${RESTORE_TARGETPATH}/${_inc}"
fi
echo using parameter \"$RESTORE_FILTER\"
}
# show stored volumes on backup repository
# used in restore; directory param is checked before
# param string name of backup dir, i.e. /etc
function t_restoreDoRestore(){
echo "duplicity restore $RESTORE_FILTER --time $RESTORE_ITEM ${ARGS_DEFAULT} ${STORAGE_TARGETPATH} ${RESTORE_TARGETPATH}"
}
# Mount backup data
function t_restoreDoMountBackupdata(){
echo "Mounting the backup data is not supported by Duplicity."
}
# search a file in the given snapshot and backup dir
# param string regex to filter
function t_restoreDoSearchFile(){
eval restic ls ${ARGS_DEFAULT} --path "${BACKUP_DIR}" ${RESTORE_ITEM} | grep -E "$1"
}
# --------------------------------------------------------------------------------
# VERIFY RETURNCODES
# --------------------------------------------------------------------------------
# init repository
# param integer exitcode of command
function t_rcCheckInit(){
echo -n "__REPO__ "
case $1 in
0) color ok; echo "OK - the repository was created." ;;
*) color error; echo "Verify output above - returncode of init was $1" ;;
esac
color reset
}
# backup files
# param integer exitcode of command
# param string directory that was backed up
function t_rcCheckBackup(){
echo -n "__BACKUP__ "
case $1 in
0) color ok; echo "OK $1" ;;
23) color error
echo "FAILED - DIR ${2}"
echo A lock file was found. Maybe this server was rebooted while performing a backup.
echo If so delete the file lockfile.lock named in the output and start $0 again.
;;
31) color error
echo "FAILED - DIR ${2}"
echo Maybe you it is a problem with the gpg-agent.conf
ls -l ~/.gnupg/gpg-agent.conf && cat ~/.gnupg/gpg-agent.conf
;;
*) color error; echo "FAILED - DIR ${2} - Backup error - returncode was $1" ;;
esac
color reset
}
# repoitory cleanup
# param integer exitcode of command
function t_rcCheckCleanup(){
echo -n "__PRUNE__ "
case $1 in
0) color ok; echo "OK" ;;
*) color error; echo "Cleanup error - returncode was $1" ;;
esac
color reset
}
# restore files
# param integer exitcode of command
function t_rcCheckRestore(){
echo -n "__RESTORE__ "
case $1 in
0) color ok; echo "OK" ;;
*) color error; echo "Restore error - returncode was $1" ;;
esac
color reset
}
# --------------------------------------------------------------------------------