diff --git a/backup.sh b/backup.sh index 4973127f18f2df069e73d3d146ea2a0c6a689776..77bbe95b4e6173022512dd104a1aaf80d12a5a34 100755 --- a/backup.sh +++ b/backup.sh @@ -3,20 +3,11 @@ # # START BACKUP # -# schedule backups. -# If backup time is reached then -# - the local dumps for all database types will be performed -# - transfer of data directories will be started +# For a backup will be done: +# - local dumps for all database types will be performed +# - transfer of data directories will be started # -# This script is added as cron (see /etc/cron.d/) -# -# SYNTAX -# backup.sh [option] -# -# OPTIONS -# default: no parameter: start an incremental backup -# -f, --full force a full backup -# -d, --dryrun check date only; no run of a backup +# This script should be added as cronjob (see /etc/cron.d/) # # -------------------------------------------------------------------------------- # ah - Axel Hahn <axel.hahn@iml.unibe.ch> @@ -24,7 +15,7 @@ # 2022-01-14 ah v1.0 # ================================================================================ -. "$(dirname $0)"/jobhelper.sh +. $( dirname "$0" )/jobhelper.sh typeset -i rcBackup=0 @@ -97,7 +88,6 @@ do echo "ERROR: the value after $1 must be a number and a letter (for unit); i.e. 1M for 1 month" exit 1 else - JOB_DOTODAY=1 JOBDEF_TYPE=auto JOBDEF_AUTO=$2 bStart=1 @@ -107,14 +97,12 @@ do ;; -f|--full) echo "Param: setting to FULL" - JOB_DOTODAY=1 JOBDEF_TYPE=full JOBDEF_AUTO= bStart=1 ;; -i|--inc) echo "Param: setting to INC" - JOB_DOTODAY=1 JOBDEF_TYPE=inc JOBDEF_AUTO= bStart=1 @@ -127,43 +115,55 @@ do shift 1 done + + # update logfile after param overrides + _j_setLogfile + + # show infos + cfg_type=$(_j_getvar "${JOBFILE}" "type") + cfg_full=$(_j_getvar "${JOBFILE}" "full") + cfg_startfull=$(_j_getvar "${JOBFILE}" "start-time-full") + + test -z "${cfg_full}${cfg_startfull}" || cfg_info="INFO: Type is [auto]; ignoring config for full backup: [full = $cfg_full ... start-time-full = $cfg_startfull]" + JOBDEF_STARTTIME=$(date +%H%M) STORAGE_BIN=$( _j_getvar "${STORAGEFILE}" "bin" ) cat << EOFbackupinfo - DEPRECATED: execution times: $JOBDEF_INC at `_j_getvar ${JOBFILE} "start-time-inc"` - DEPRECATED: Full backup : $JOBDEF_FULL at `_j_getvar ${JOBFILE} "start-time-full"` + CONFIG: + Used Backup tool : $STORAGE_BIN + Backup type : $(_j_getvar ${JOBFILE} "type") + $( test "$cfg_type" = "auto" && echo "$cfg_info" )$( test "$cfg_type" = "auto" || echo "INFO: full backup: $cfg_info" ) - DEPRECATED: do today = $JOB_DOTODAY - - Used Backup tool: $STORAGE_BIN - type = $JOBDEF_TYPE $JOBDEF_AUTO - - starttime = $JOBDEF_STARTTIME - donefile = $JOB_DONEFILE + EFFECTIVE: + type : $JOBDEF_TYPE $JOBDEF_AUTO + donefile : $JOB_DONEFILE + log : $JOB_LOGFILE EOFbackupinfo j_requireUser "root" -echo "DEBUG $0 ... ABORT"; exit 1 - +# -------------------------------------------------------------------------------- +# start backup # -------------------------------------------------------------------------------- if [ $bStart -eq 1 ]; then + sleep 3 + # ----- local dumps - echo "INFO: `date` - starting backup ... type $JOBDEF_TYPE - time $JOBDEF_STARTTIME " | tee -a $JOB_LOGFILE + echo "INFO: $(date) - starting backup ... type $JOBDEF_TYPE - time $JOBDEF_STARTTIME " | tee -a "$JOB_LOGFILE" touch "${JOB_DONEFILE}.01.START" - cat $JOBFILE >>$JOB_LOGFILE + cat "$JOBFILE" >>"$JOB_LOGFILE" - echo "INFO: `date` - Making local backups ... ${DIR_SELF}/localdump.sh ALL" | tee -a $JOB_LOGFILE - ${DIR_SELF}/localdump.sh ALL | tee -a $JOB_LOGFILE + echo "INFO: $(date) - Making local backups ... ${DIR_SELF}/localdump.sh ALL" | tee -a "$JOB_LOGFILE" + "${DIR_SELF}"/localdump.sh ALL | tee -a "$JOB_LOGFILE" rcBackup=$? - echo "INFO: `date` - local backups were finished" | tee -a $JOB_LOGFILE + echo "INFO: $(date) - local backups were finished" | tee -a "$JOB_LOGFILE" sleep 2 @@ -172,32 +172,32 @@ echo "DEBUG $0 ... ABORT"; exit 1 if [ -x "${DIR_SELF}/transfer.sh" ]; then # transfer files - echo "INFO: `date` - Sending data to storage... ${DIR_SELF}/transfer.sh $JOBDEF_TYPE" | tee -a $JOB_LOGFILE + echo "INFO: $(date) - Sending data to storage... ${DIR_SELF}/transfer.sh $JOBDEF_TYPE" | tee -a "$JOB_LOGFILE" touch "${JOB_DONEFILE}.02.STARTTRANSFER" - ${DIR_SELF}/transfer.sh $JOBDEF_TYPE $JOBDEF_AUTO 2>&1 | tee -a $JOB_LOGFILE + "${DIR_SELF}"/transfer.sh $JOBDEF_TYPE "$JOBDEF_AUTO" 2>&1 | tee -a "$JOB_LOGFILE" rcTransfer=$? else - echo "SKIP - transfer.sh not found; all files will be kept on local filesystem only" | tee -a $JOB_LOGFILE + echo "SKIP - transfer.sh not found; all files will be kept on local filesystem only" | tee -a "$JOB_LOGFILE" fi rcBackup=$rcBackup+rcTransfer - echo "INFO: `date` - DONE" | tee -a $JOB_LOGFILE + echo "INFO: $(date) - DONE" | tee -a "$JOB_LOGFILE" touch "${JOB_DONEFILE}.03.DONE" echo - echo log for this executed job is - ls -l $JOB_LOGFILE + echo "log for this executed job is" + ls -l "$JOB_LOGFILE" echo - echo "INFO: `date` - cleanup logs" + echo "INFO: $(date) - cleanup logs" echo find "${DIR_LOGS}" -mtime +28 -delete -print find "${DIR_LOGS}" -mtime +28 -delete -print echo - echo STATUS $0 exit with final returncode rc=$rcBackup | tee -a $JOB_LOGFILE + echo STATUS $0 exit with final returncode rc=$rcBackup | tee -a "$JOB_LOGFILE" echo else diff --git a/check_clientbackup.sh b/check_clientbackup.sh index 1ec5d5eb0cddb5b32af64f34d7cc9fba3d61684b..1343cf30d36e43d91df09ff9f3f451d41716a1e7 100755 --- a/check_clientbackup.sh +++ b/check_clientbackup.sh @@ -12,25 +12,25 @@ # ds - Daniel Schueler <daniel.schueler@iml.unibe.ch> # # 2016-12-09 ah,ds v1.0 +# 2022-01-19 ah v1.1 fixes with shellcheck # ============================================================================== -. `dirname $0`/jobhelper.sh +. $(dirname $0)/jobhelper.sh # ------------------------------------------------------------------------------ # CONFIG # ------------------------------------------------------------------------------ typeset -i iOK=0 -typeset -i iErr=0 -typeset -i rc=0 +# limit when to warn if no backup was started typeset -i iMaxAgeInHours=96 typeset -i iAge typeset -i iAge2 typeset -i iError -logdir=`dirname $0`/logs +logdir=$(dirname "$0")/logs # ------------------------------------------------------------------------------ @@ -39,7 +39,7 @@ logdir=`dirname $0`/logs sShort="Client Backup -" -ls $logdir/*.log >/dev/null +ls "$logdir"/*.log >/dev/null if [ $? -ne 0 ]; then sShort="$sShort logs were not found. Backup was never executed" iError=1 @@ -48,14 +48,14 @@ else # iMaxAgeInHours=`j_getLastBackupAge` # echo verify last backup: $iMaxAgeInHours h ago - for logfile in $(ls -1t $logdir/inc*.log $logdir/full*.log $logdir/auto*.log 2>/dev/null | head -1) + for logfile in $(ls -1t "$logdir"/inc*.log "$logdir"/full*.log "$logdir"/auto*.log 2>/dev/null | head -1) do - echo LAST BACKUP: $logfile - grep "final.*rc=" $logfile + echo LAST BACKUP: "$logfile" + grep "final.*rc=" "$logfile" echo # --- SENSU Statusline - if [ -f `dirname $0`/transfer.sh ]; then + if [ -f "$(dirname $0)"/transfer.sh ]; then sShort="$sShort WITH" else sShort="$sShort NO" @@ -63,8 +63,8 @@ else sShort="$sShort transfer -" # --- count returncodes - iOK=`grep "final.*rc=0$" $logfile | wc -l` - iError=`grep "final.*rc=" $logfile | grep -v "rc=0$" | wc -l` + iOK=$(grep -c "final.*rc=0$" "$logfile" ) + iError=$(grep "final.*rc=" "$logfile" | grep -cv "rc=0$") echo "OK: $iOK ... Errors: $iError" # --- rc=0 must be here @@ -77,7 +77,7 @@ else iAge=$( date +%s )-$( date +%s -r "$logfile" ) iAge2=$iAge/60/60 echo "age: $iAge sec ... $iAge2 h" - sShort="$sShort last backup log: `basename $logfile` ($iAge2 h ago) " + sShort="$sShort last backup log: $(basename "$logfile") ($iAge2 h ago) " if [ $iAge2 -gt $iMaxAgeInHours ]; then echo "Error: the last backup is older than $iMaxAgeInHours hours" sShort="$sShort ERROR: backup is older than $iMaxAgeInHours hours " @@ -90,16 +90,16 @@ else # --- changes (incremental backups only) and backup status infos echo sSearch="Args:|ElapsedTime|SourceFiles|SourceFileSize|RawDeltaSize" - echo "$logfile" | fgrep "inc" >/dev/null + echo "$logfile" | grep -F "inc" >/dev/null if [ $? -eq 0 ]; then sSearch="[ADM]\ |${sSearch}" fi echo --- changes: - egrep "^(${sSearch})" $logfile + grep -E "^(${sSearch})" "$logfile" echo echo --- summary of backed up directories: - grep "DIR\ " $logfile + grep "DIR\ " "$logfile" sShort="$sShort - OK: $iOK ... Errors: $iError" @@ -110,8 +110,8 @@ fi echo -echo MONITORINFO: $sShort -echo STATUS $0 - final returncode rc=$iError -exit $iError +echo "MONITORINFO: $sShort" +echo "STATUS $0 - final returncode rc=$iError" +exit "$iError" # ------------------------------------------------------------------------------ diff --git a/jobhelper.sh b/jobhelper.sh index 739d974837a36fe899cedd3864dba4bde9ceee93..076b6530529b202f864ff558d9d63daca8432440 100755 --- a/jobhelper.sh +++ b/jobhelper.sh @@ -60,7 +60,7 @@ function j_init(){ done # for date definitions like weekdays - JOBDEF_LANG=`_j_getvar ${JOBFILE} "lang"` + JOBDEF_LANG=$(_j_getvar "${JOBFILE}" "lang") if [ -z "$JOBDEF_LANG" ]; then JOBDEF_LANG="en_us" fi @@ -100,24 +100,24 @@ eofbanner # get list of all directories to backup / restore # ------------------------------------------------------------ function j_getDirs2Backup(){ - STORAGE_SAMBASHARES=`_j_getvar ${STORAGEFILE} "sambashares"` + STORAGE_SAMBASHARES=$(_j_getvar "${STORAGEFILE}" "sambashares") - _j_getvar ${JOBFILE} dir-localdumps - _j_getvar ${JOBFILE} dir-dbarchive - _j_getvar ${DIRFILE} include + _j_getvar "${JOBFILE}" dir-localdumps + _j_getvar "${JOBFILE}" dir-dbarchive + _j_getvar "${DIRFILE}" include # get dirs of filesets, i.e. # set-custom-[key]--dir = /home/ladmin - _j_getvar ${DIRFILE} "set.*--dir" + _j_getvar "${DIRFILE}" "set.*--dir" # detect Samba shares (set sambashares = 1 for it) - if [ -z "${STORAGE_SAMBASHARES}" -o ${STORAGE_SAMBASHARES} -eq 0 ]; then + if [ -z "${STORAGE_SAMBASHARES}" ] || [ "${STORAGE_SAMBASHARES}" -eq 0 ]; then echo NO >/dev/null else if [ -f /etc/samba/smb.conf ]; then - for dirOfShare in `cat /etc/samba/smb.conf | grep "path.*=" | grep -v "#.*path" | cut -f 2 -d "=" ` + for dirOfShare in $( grep "path.*=" "/etc/samba/smb.conf" | grep -v "#.*path" | cut -f 2 -d "=" ) do - echo $dirOfShare + echo "$dirOfShare" done fi fi @@ -130,7 +130,7 @@ function j_getDirs2Backup(){ # param string path # ------------------------------------------------------------ function j_getSetnameOfPath(){ - cat ${DIRFILE} | grep "^set.*dir\ =\ $*$" | cut -f 1 -d "=" | sed "s#\-\-dir\ ##g" + grep "^set.*dir\ =\ $*$" "${DIRFILE}" | cut -f 1 -d "=" | sed "s#\-\-dir\ ##g" } # ------------------------------------------------------------ @@ -140,15 +140,15 @@ function j_getSetnameOfPath(){ # param string name of host (for future releases) # ------------------------------------------------------------ function j_getFullTarget(){ - sTmpSafeName=`j_getSafename "$1"` + sTmpSafeName=$(j_getSafename "$1") sTmpHostname=$2 - if [ -z $sTmpHostname ]; then - sTmpHostname=`hostname -f` + if [ -z "$sTmpHostname" ]; then + sTmpHostname=$(hostname -f) fi - if [ -z ${STORAGE_BASEDIR} ]; then - STORAGE_BASEDIR=`_j_getvar ${STORAGEFILE} "storage"` + if [ -z "${STORAGE_BASEDIR}" ]; then + STORAGE_BASEDIR=$(_j_getvar "${STORAGEFILE}" "storage") fi - echo ${STORAGE_BASEDIR}/${sTmpHostname}/${sTmpSafeName} + echo "${STORAGE_BASEDIR}/${sTmpHostname}/${sTmpSafeName}" } # ------------------------------------------------------------ @@ -167,8 +167,8 @@ function j_getFullTarget(){ # for iDeltaH in {24..96} # do # sCmpDate=`date +%s`-iDeltaH*60*60 -# iWasInc=`_j_wasThisDay @${sCmpDate} $JOBDEF_INC` -# iWasFull=`_j_wasThisDay @${sCmpDate} $JOBDEF_FULL` +# iWasInc=`_j_runToday @${sCmpDate} $JOBDEF_INC` +# iWasFull=`_j_runToday @${sCmpDate} $JOBDEF_FULL` # if [ ${iWasInc} -gt 0 -o ${iWasFull} -gt 0 ]; then # echo $iDeltaH # exit @@ -183,7 +183,8 @@ function j_getFullTarget(){ # param string name of directory # ------------------------------------------------------------ function j_getSafename(){ - echo $* | sed 's#/#_#g' + # echo $* | sed 's#/#_#g' + echo "${*//\//_}" } # ------------------------------------------------------------ @@ -196,7 +197,7 @@ function _j_getvar(){ echo "ERROR: cannot read file: ${1}. Abort." exit 100 fi - cat "${1}" | grep "^${2}\ =\ " | cut -f 3- -d " " + grep "^${2}\ =\ " < "${1}"| cut -f 3- -d " " } # ------------------------------------------------------------ @@ -214,38 +215,46 @@ function _j_getvar(){ # param string date to compare # param string value of full|inc in backup.job # ------------------------------------------------------------ -# function _j_wasThisDay(){ -# typeset -i bToday=0 -# sCompDate="$1" -# shift 1 -# value="$*" - -# # grep weekday -# echo $value | grep "^DOW:" | grep `date +%a -d $sCompDate` >/dev/null && bToday=1 - -# # grep day of month -# echo $value | grep "^DOM:" | grep `date +%d -d $sCompDate` >/dev/null && bToday=1 - -# # grep nth weekday of a month -# echo $value | grep "^WDM:" >/dev/null -# if [ $? -eq 0 ]; then - -# typeset -i iDayOfMonth=`date +%e -d $sCompDate` -# typeset -i iWeekday=`date +%u -d $sCompDate` -# # `date +%u` - weekday as int; Sun = 0 -# # `date +%e` - day in date -# typeset -i iWeekInMonth=$(echo $(( ( ${iDayOfMonth} - ${iWeekday} + 6 ) / 7 )) ) - -# typeset -i n=`echo $value | grep "^WDM:" | cut -f 2- -d ":" | cut -c 1` -# sDay=`echo $value | grep "^WDM:" | cut -f 2- -d ":" | cut -f 2 -d " "` - -# if [ ${n} -eq ${iWeekInMonth} -a ${sDay} = `date +%a -d $sCompDate` ]; then -# bToday=1 -# fi -# fi +function _j_runToday(){ + typeset -i local bToday=0 + local sCompDate="$1" + shift 1 + local value="$*" + + # grep weekday + echo "$value" | grep "^DOW:" | grep $(date +%a -d "$sCompDate") >/dev/null && bToday=1 + + # grep day of month + echo "$value" | grep "^DOM:" | grep $(date +%d -d "$sCompDate") >/dev/null && bToday=1 + + # grep nth weekday of a month + echo "$value" | grep "^WDM:" >/dev/null + if [ $? -eq 0 ]; then + + typeset -i local iDayOfMonth + iDayOfMonth=$(date +%e -d "$sCompDate") + + typeset -i local iWeekday + iWeekday=$(date +%u -d "$sCompDate") + + # `date +%u` - weekday as int; Sun = 0 + # `date +%e` - day in date + typeset -i local iWeekInMonth + iWeekInMonth=$(echo $(( ( ${iDayOfMonth} - ${iWeekday} + 6 ) / 7 )) ) + + typeset -i local n + n=$(echo "$value" | grep "^WDM:" | cut -f 2- -d ":" | cut -c 1) + + local sDay + sDay=$(echo "$value" | grep "^WDM:" | cut -f 2- -d ":" | cut -f 2 -d " ") + + if [ ${n} -eq ${iWeekInMonth} ] && [ ${sDay} = $(date +%a -d "$sCompDate") ]; then + bToday=1 + fi + fi -# echo $bToday -# } + echo $bToday +} # ------------------------------------------------------------ # parse day of week and day of month and echo 0 or 1 @@ -257,27 +266,25 @@ function _j_getvar(){ # # param string value of full|inc in backup.job # ------------------------------------------------------------ -# function _j_isToday(){ -# sCmpDate=`date +%s` -# _j_wasThisDay "@$sCmpDate" $* -# } +function _j_isToday(){ + sCmpDate=$(date +%s) + _j_runToday "@$sCmpDate" "$*" +} # ------------------------------------------------------------ # read local jobdescription and set as variables # ------------------------------------------------------------ function j_read(){ - mytime=`date +%H%M` + # mytime=$(date +%H%M) # --- parse something - BACKUP_TARGETDIR=$(_j_getvar ${JOBFILE} "dir-local-dumps") + BACKUP_TARGETDIR=$(_j_getvar "${JOBFILE}" "dir-local-dumps") + export BACKUP_TARGETDIR JOBDEF_TYPE=$(_j_getvar ${JOBFILE} "type") - if [ -z "$JOBDEF_TYPE" ]; then - JOBDEF_TYPE=auto - fi - + export JOBDEF_TYPE # JOBDEF_INC=`_j_getvar ${JOBFILE} "inc"` # JOBDEF_FULL=`_j_getvar ${JOBFILE} "full"` @@ -293,7 +300,7 @@ function j_read(){ # bIsTodayInc=`_j_isToday $JOBDEF_INC` # bIsTodayFull=`_j_isToday $JOBDEF_FULL` - + # JOB_DOTODAY=1 # if [ $bIsTodayFull -eq 0 -a $bIsTodayInc -eq 0 ]; then # JOB_DOTODAY=0 @@ -303,21 +310,42 @@ function j_read(){ # sStartInc=`_j_fetchLatestStarttime "start-time-inc"` # JOBDEF_STARTTIME=$sStartInc - # if [ $bIsTodayFull -eq 1 ]; then - # sStartFull=`_j_fetchLatestStarttime "start-time-full"` + if [ "$JOBDEF_TYPE" != "auto" ]; then - # if [ $bIsTodayInc -eq 1 -a $sStartFull -ne $sStartInc ]; then - # echo INFO: full backup today $sStartFull - but incremental is at $sStartInc - # echo -n "" - # else - # # echo INFO: full backup today $sStartFull - # JOBDEF_TYPE="full" - # JOBDEF_STARTTIME=$sStartFull - # fi - # fi + # ----- detect if current date matches a definition "full = ..." + local cfg_full; cfg_full=$(_j_getvar "${JOBFILE}" "full") + local bIsTodayFull; bIsTodayFull=$(_j_isToday "$cfg_full") + + # ... if "1" ... then verify time with "start-time-full = ..."" + if [ $bIsTodayFull -eq 1 ]; then + + local sStart + sStart=$(_j_getvar "${JOBFILE}" "start-time-full") + test -z "$sStart}" && sStart="." + if date +%H:%M | grep "$sStart" >/dev/null; then + JOBDEF_TYPE=full + fi + + fi + fi + + if [ -z "$JOBDEF_TYPE" ]; then + JOBDEF_TYPE=auto + fi - JOB_DONEFILE=${DIR_LOGS}/${JOBDEF_TYPE}-$(date +%Y%m%d)-${JOBDEF_STARTTIME} + test "${JOBDEF_TYPE}" = "auto" && JOBDEF_AUTO=$(_j_getvar ${JOBFILE} "auto") + export JOBDEF_AUTO + + _j_setLogfile +} + +# ------------------------------------------------------------ +# read local jobdescription and set as variables +# ------------------------------------------------------------ +function _j_setLogfile(){ + JOB_DONEFILE=${DIR_LOGS}/${JOBDEF_TYPE}-$(date +%Y%m%d-%H%M%S) JOB_LOGFILE="${JOB_DONEFILE}.log" + export JOB_LOGFILE } # ------------------------------------------------------------ @@ -362,7 +390,7 @@ function j_requireBinary(){ if [ $rcself -ne 0 ]; then rc=$rc+$rcself echo "INFO: missing binary $1" - if [ -z $2 ]; then + if [ -z "$2" ]; then exit 3 fi fi @@ -375,12 +403,13 @@ function j_requireBinary(){ # ------------------------------------------------------------ function j_requireProcess(){ # echo "CHECK process $1" - ps -ef | grep -v grep | grep -E "$1" >/dev/null + # ps -ef | grep -v grep | grep -E "$1" >/dev/null + pgrep -l "$1" >/dev/null rcself=$? if [ $rcself -ne 0 ]; then rc=$rc+$rcself echo "INFO: missing process $1" - if [ -z $2 ]; then + if [ -z "$2" ]; then exit 4 fi fi @@ -391,8 +420,8 @@ function j_requireProcess(){ # param string username, i.e. root # ------------------------------------------------------------ function j_requireUser(){ - sUser=`id | cut -f 2 -d "(" | cut -f 1 -d ")"` - if [[ $sUser != "$1" ]]; then + sUser=$(id | cut -f 2 -d "(" | cut -f 1 -d ")") + if [[ "$sUser" != "$1" ]]; then echo "ERROR: user $1 is reqired." exit 5 fi