Can now specify restic/rsync/rclone repo names in repofile.
Renamed various options in ~/.backup/config to DEF_* Records historical results of backups in ~/.backup/stats Added 'check' command to check for successful backups in the last 24 hours (uses new stats file) Now requires 'bc' (for check command)
This commit is contained in:
parent
cde65f6ff1
commit
f7af0de9f5
351
bare.sh
351
bare.sh
|
@ -2,8 +2,9 @@
|
|||
VALIDCOMMANDS="go ls init repos stats diff forget"
|
||||
|
||||
RCFILE=${HOME}/.backup/config
|
||||
AUTHFILE=${HOME}/.backup/auth
|
||||
DEF_AUTHFILE=${HOME}/.backup/auth
|
||||
REPOFILE=${HOME}/.backup/repos
|
||||
STATFILE=${HOME}/.backup/stats
|
||||
LOGFILE=/var/log/backup.log
|
||||
|
||||
RESTIC=/usr/local/bin/restic
|
||||
|
@ -28,19 +29,33 @@ function log() {
|
|||
echo "${now} <${mode}> $*" >>${LOG}
|
||||
}
|
||||
|
||||
function updatestats() {
|
||||
local repo cmd stamp code
|
||||
repo=$1
|
||||
cmd=$2
|
||||
code=$3
|
||||
stamp=`date +%s`
|
||||
if [[ -f $STATFILE ]]; then
|
||||
sed -i "/${repo}:${cmd}/d" $STATFILE
|
||||
fi
|
||||
echo "${repo}:${cmd}:${code}:${stamp}" >> $STATFILE
|
||||
}
|
||||
|
||||
function usage-repo() {
|
||||
echo " reponame1:/path/to/files1/:tag1,tag2,...,tagX"
|
||||
echo " reponame2:/path/to/files2/:tag1,tag2,...,tagX"
|
||||
echo " reponame1;/path/to/files1/;tag1,tag2,...,tagX;repo_url;repo_passfile;repo_excludefail"
|
||||
echo " reponame2;/path/to/files2/;tag1,tag2,...,tagX;repo_url;repo_passfile;repo_excludefail"
|
||||
echo " ..."
|
||||
echo " reponameX:/path/to/filesX/:tag1,tag2,...,tagX"
|
||||
echo " reponameX;/path/to/filesX/;tag1,tag2,...,tagX;repo_url;repo_passfile;repo_excludefail"
|
||||
echo ""
|
||||
echo " Default password file is: $DEF_AUTHFILE"
|
||||
echo ""
|
||||
echo "Backup method tags:"
|
||||
echo " restic Backup using restic to Backblaze B2 bucket \$B2_BUCKET_PREFIX-<reponame>"
|
||||
echo " rclone Backup using rclone to Backblaze B2 bucket \$B2_BUCKET_PREFIX-<reponame>"
|
||||
echo " rsync Backup using rsync to \$RSYNC_USER@\$RSYNC_SERVER:\$RSYNC_DIR/<reponame>."
|
||||
echo " restic Backup using restic (default repo is Backblaze B2 bucket \$B2_BUCKET_PREFIX-<reponame>)"
|
||||
echo " rclone Backup using rclone (default repo is Backblaze B2 bucket \$B2_BUCKET_PREFIX-<reponame>)"
|
||||
echo " rsync Backup using rsync (defualt repo is \$DEF_RSYNC_USER@\$DEF_RSYNC_SERVER:\$DEF_RSYNC_DIR/<reponame>)"
|
||||
echo ""
|
||||
echo "Pre-backup commands to access local files:"
|
||||
echo " nfs Mount \$NFS_SERVER:\$NFS_SERVER_BASE/<sharename> to <repopath>"
|
||||
echo " nfs Mount \$DEF_NFS_SERVER:\$DEF_NFS_SERVER_BASE/<sharename> to <repopath>"
|
||||
echo " before running. Sharename determined by stripping \$NFS_PREFIX"
|
||||
echo " from start of repo path."
|
||||
echo " usmb Run 'usmb reponame' to mount \$USMB_PREFIX/<sharename> before running."
|
||||
|
@ -53,18 +68,17 @@ function usage-rc() {
|
|||
echo " export B2_APP_KEY=xxx # Backblaze B2 bucket auth"
|
||||
echo " export B2_BUCKET_PREFIX=xxx # Prefix to append to create unique B2 bucket name"
|
||||
echo ""
|
||||
echo " export RESTIC_PASSWORD=xxx # Password used to encrypt Restic backups"
|
||||
echo " export RESTIC_KEEPDAYS=31 # Days to keep restic backups for"
|
||||
echo ""
|
||||
echo " export RSYNC_SERVER=xxx # Server used for repos with 'rsync' tag"
|
||||
echo " export RSYNC_USER=backups # Username for rsync server"
|
||||
echo " export RSYNC_DIR=/home/backups/backups # Remote directory on rsync server"
|
||||
echo " export DEF_RSYNC_SERVER=xxx # Server used for repos with 'rsync' tag"
|
||||
echo " export DEF_RSYNC_USER=backups # Username for rsync server"
|
||||
echo " export DEF_RSYNC_DIR=/home/backups/backups # Remote directory on rsync server"
|
||||
echo " export RSYNC_OPTIONS=-Pavz # Options to pass to rsync"
|
||||
echo ""
|
||||
echo " export USMB_PREFIX=/DataVolume/shares # Strip this from repo path to get USMB share name"
|
||||
echo ""
|
||||
echo " export NFS_SERVER=nfs.yourdomain.com # NFS server where local files for 'nfs' repos are found"
|
||||
echo " export NFS_SERVER_BASE=/remote/nfs/share/base # Path on local NFS server to prefix to repo names"
|
||||
echo " export DEF_NFS_SERVER=nfs.yourdomain.com # NFS server where local files for 'nfs' repos are found"
|
||||
echo " export DEF_NFS_SERVER_BASE=/remote/nfs/share/base # Path on local NFS server to prefix to repo names"
|
||||
echo " export NFS_PREFIX=/local/nfs/mountpoint # Where to mount NFS exports locally before backing them up"
|
||||
}
|
||||
|
||||
|
@ -94,15 +108,16 @@ function getdatapath() {
|
|||
|
||||
DATAPATH=""
|
||||
for x in ${REPODEFS[@]}; do
|
||||
match="^${REPO}:"
|
||||
match="^${REPO}\;"
|
||||
if [[ $x =~ $match ]]; then
|
||||
DATAPATH=`echo $x | sed -e s/${match}//`
|
||||
fi
|
||||
done
|
||||
DATAPATH=`echo $DATAPATH | sed -e s/:.*//`
|
||||
DATAPATH=`echo $DATAPATH | sed -e s/\;.*//`
|
||||
echo "$DATAPATH"
|
||||
}
|
||||
function getmode() {
|
||||
local mode
|
||||
checktag "$1" rclone
|
||||
if [[ $? -eq 0 ]]; then
|
||||
mode=rclone
|
||||
|
@ -114,28 +129,114 @@ function getmode() {
|
|||
mode=restic
|
||||
fi
|
||||
fi
|
||||
echo "$mode"
|
||||
}
|
||||
|
||||
function checktag() { # return 0 if tag matches
|
||||
local reponame lookfor x match repodef
|
||||
reponame="$1"
|
||||
lookfor="$2"
|
||||
function getrepoexcludefile() { # output path
|
||||
local res rv
|
||||
res=`getrepotok $1 7`
|
||||
rv=$?
|
||||
echo "$res"
|
||||
return $rv
|
||||
}
|
||||
|
||||
# if we were just given a repo name, look up the def
|
||||
if [[ $reponame =~ ^.*:.*$ ]]; then
|
||||
function getrepopath() { # output path
|
||||
local res rv mode def repobase
|
||||
res=`getrepotok $1 4`
|
||||
rv=$?
|
||||
|
||||
if [[ -z $res ]]; then
|
||||
mode=`getmode $1`
|
||||
repobase=`getreponame $1`
|
||||
if [[ $mode == "restic" ]]; then
|
||||
def="b2:${B2_BUCKET_PREFIX}-${repobase}"
|
||||
elif [[ $mode == "rclone" ]]; then
|
||||
def="remote:${B2_BUCKET_PREFIX}-${repobase}"
|
||||
elif [[ $mode == "rsync" ]]; then
|
||||
def="${DEF_RSYNC_USER}@${DEF_RSYNC_SERVER}:${DEF_RSYNC_DIR}/$repobase"
|
||||
else
|
||||
def="(no default repo for mode $mode)"
|
||||
fi
|
||||
res="$def"
|
||||
fi
|
||||
|
||||
echo "$res"
|
||||
return $rv
|
||||
}
|
||||
|
||||
function getrepopassfile() { # output path
|
||||
local res rv
|
||||
res=`getrepotok $1 5`
|
||||
rv=$?
|
||||
echo "$res"
|
||||
return $rv
|
||||
}
|
||||
|
||||
function getrepotags() { # output path
|
||||
local res rv
|
||||
res=`getrepotok $1 3`
|
||||
rv=$?
|
||||
echo "$res"
|
||||
return $rv
|
||||
}
|
||||
|
||||
function getrepotok() { # output given token from repo def
|
||||
local def res rv code idx
|
||||
def=`getrepodef "$1"`
|
||||
idx=$2
|
||||
code="{ print \$${idx} }"
|
||||
res=`echo "$def" | awk -F';' "$code"`
|
||||
echo "$res"
|
||||
if [[ -z $res ]]; then
|
||||
rv=1
|
||||
else
|
||||
rv=0
|
||||
fi
|
||||
return $rv
|
||||
}
|
||||
|
||||
function getreponame() {
|
||||
local reponame
|
||||
|
||||
reponame="$1"
|
||||
|
||||
if [[ $reponame =~ ^.*\;.*$ ]]; then
|
||||
# if we were given a repo def, return just the name
|
||||
reponame=`echo "$reponame" | sed -e 's/\;.*//g'`
|
||||
fi
|
||||
echo "$reponame"
|
||||
}
|
||||
|
||||
function getrepodef() {
|
||||
local reponame match repodef x
|
||||
|
||||
reponame="$1"
|
||||
|
||||
if [[ $reponame =~ ^.*\;.*$ ]]; then
|
||||
repodef="$reponame"
|
||||
else
|
||||
# if we were just given a repo name, look up the def
|
||||
repodef=""
|
||||
for x in ${REPODEFS[@]}; do
|
||||
match="^${reponame}:"
|
||||
match="^${reponame};"
|
||||
if [[ $x =~ $match ]]; then
|
||||
repodef="$x"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
echo "$repodef"
|
||||
}
|
||||
|
||||
|
||||
if [[ $repodef =~ ^.*:.*:.*${lookfor}.*$ ]]; then
|
||||
function checktag() { # return 0 if tag matches
|
||||
local reponame lookfor justtags
|
||||
|
||||
reponame="$1"
|
||||
lookfor="$2"
|
||||
|
||||
justtags=`getrepotags "$reponame"`
|
||||
|
||||
if [[ $justtags =~ ^.*${lookfor}.*$ ]]; then
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
|
@ -196,18 +297,15 @@ if ! [ -e ${REPOFILE} ]; then
|
|||
usage-repo
|
||||
exit 1
|
||||
fi
|
||||
which bc >/dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error - can't find bc in path"
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
. ${RCFILE}
|
||||
|
||||
|
||||
if [[ -z $B2_APP_ID ]]; then
|
||||
echo "Error - \$B2_APP_ID not set."
|
||||
exit 1
|
||||
fi
|
||||
if [[ -z $B2_APP_KEY ]]; then
|
||||
echo "Error - \$B2_APP_KEY not set."
|
||||
exit 1
|
||||
fi
|
||||
if [[ -z $RESTIC_KEEPDAYS ]]; then
|
||||
echo "Error - \$RESTIC_KEEPDAYS not set."
|
||||
exit 1
|
||||
|
@ -225,10 +323,26 @@ fi
|
|||
idx=0
|
||||
for f in `cat $REPOFILE`; do
|
||||
REPODEFS[$idx]="$f"
|
||||
|
||||
mode=`getmode "$f"`
|
||||
if [[ $mode == "restic" ]]; then
|
||||
thisrpath=`getrepopath $f`
|
||||
if [[ ${thisrpath,,} == *b2* ]]; then
|
||||
if [[ -z $B2_APP_ID ]]; then
|
||||
echo "Error - \$B2_APP_ID not set."
|
||||
exit 1
|
||||
fi
|
||||
if [[ -z $B2_APP_KEY ]]; then
|
||||
echo "Error - \$B2_APP_KEY not set."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ $DOALL -eq 1 ]]; then
|
||||
checktag "$f" auto
|
||||
if [[ $? -eq 0 ]]; then
|
||||
REPOSTOBACKUP="$REPOSTOBACKUP `echo $f | sed -e 's/:.*//'`"
|
||||
REPOSTOBACKUP="$REPOSTOBACKUP `echo $f | sed -e 's/\;.*//'`"
|
||||
fi
|
||||
fi
|
||||
idx=$((idx + 1))
|
||||
|
@ -247,13 +361,13 @@ if [[ -z $REPOSTOBACKUP ]]; then
|
|||
fi
|
||||
|
||||
if [[ $CMD == "repos" ]]; then
|
||||
format="%-20s%-40s%-10s\n"
|
||||
format="%-10s%-20s%-20s%s\n"
|
||||
echo "Repos defined in ${RCFILE}:"
|
||||
echo ""
|
||||
printf "$format" "Repo" "Path" "Tags"
|
||||
printf "$format" "Repo" "Path" "Tags" "Repo path"
|
||||
for x in ${REPODEFS[@]}; do
|
||||
|
||||
IFS=':' read -ra tok <<< "$x"
|
||||
IFS=';' read -ra tok <<< "$x"
|
||||
thisrepo=${tok[0]}
|
||||
thispath=${tok[1]}
|
||||
if [[ -z ${tok[2]} ]]; then
|
||||
|
@ -261,8 +375,10 @@ if [[ $CMD == "repos" ]]; then
|
|||
else
|
||||
tags=`echo "${tok[2]}" | sed -e 's/,/ /g'`
|
||||
fi
|
||||
thisrpath=`getrepopath $thisrepo`
|
||||
[[ -z $thisrpath ]] && thisrpath="(default)"
|
||||
|
||||
printf "$format" "$thisrepo" "$thispath" "$tags"
|
||||
printf "$format" "$thisrepo" "$thispath" "$tags" "$thisrpath"
|
||||
done
|
||||
exit 0
|
||||
fi
|
||||
|
@ -275,8 +391,9 @@ fi
|
|||
# Validate repos
|
||||
GOODREPOS=""
|
||||
for f in $REPOSTOBACKUP; do
|
||||
REPO=${f}
|
||||
DATAPATH=$(getdatapath $f)
|
||||
getmode "$f"
|
||||
mode=`getmode "$REPO"`
|
||||
|
||||
checktag "$f" usmb
|
||||
if [[ $? -eq 0 ]]; then
|
||||
|
@ -284,7 +401,7 @@ for f in $REPOSTOBACKUP; do
|
|||
USMBNAME=$f
|
||||
else
|
||||
if ! [[ $DATAPATH == *${USMB_PREFIX}* ]]; then
|
||||
log "Error: path '$DATAPATH' of repo '$REPO' does not contain '$USMB_PREFIX'."
|
||||
log "Error: path '$DATAPATH' of repo '$REPO' does not contain smb prefix '$USMB_PREFIX'."
|
||||
continue
|
||||
fi
|
||||
USMBNAME=`echo "${DATAPATH}" | sed -e "s,${USMB_PREFIX}/\(.*\).*,\1,"`
|
||||
|
@ -297,20 +414,20 @@ for f in $REPOSTOBACKUP; do
|
|||
|
||||
checktag "$f" nfs
|
||||
if [[ $? -eq 0 ]]; then
|
||||
if [[ -z $NFS_SERVER ]]; then
|
||||
log "Error: repo '$REPO' has nfs tag but \$NFS_SERVER not defined."
|
||||
if [[ -z $DEF_NFS_SERVER ]]; then
|
||||
log "Error: repo '$REPO' has nfs tag but \$DEF_NFS_SERVER not defined."
|
||||
continue
|
||||
fi
|
||||
if [[ -z $NFS_SERVER_BASE ]]; then
|
||||
log "Error: repo '$REPO' has nfs tag but \$NFS_SERVER_BASE not defined."
|
||||
if [[ -z $DEF_NFS_SERVER_BASE ]]; then
|
||||
log "Error: repo '$REPO' has nfs tag but \$DEF_NFS_SERVER_BASE not defined."
|
||||
continue
|
||||
fi
|
||||
if ! [[ $DATAPATH == *${NFS_PREFIX}* ]]; then
|
||||
log "Error: path '$DATAPATH' of repo '$REPO' does not contain '$NFS_PREFIX'."
|
||||
log "Error: path '$DATAPATH' of repo '$REPO' does not contain nfs prefix '$NFS_PREFIX'."
|
||||
continue
|
||||
fi
|
||||
NFSNAME=`echo "${DATAPATH}" | sed -e "s,${NFS_PREFIX}/\(.*\).*,\1,"`
|
||||
NFSPATH="${NFS_SERVER}:${NFS_SERVER_BASE}/${NFSNAME}"
|
||||
NFSPATH="${DEF_NFS_SERVER}:${DEF_NFS_SERVER_BASE}/${NFSNAME}"
|
||||
USENFS=1
|
||||
else
|
||||
NFSNAME=""
|
||||
|
@ -395,6 +512,8 @@ if [[ $TESTMODE -eq 1 ]]; then
|
|||
exit 0
|
||||
fi
|
||||
|
||||
errcount=0 # used for 'check' mode
|
||||
warncount=0 # used for 'check' mode
|
||||
for f in $REPOSTOBACKUP; do
|
||||
REPO=${f}
|
||||
DATAPATH=$(getdatapath $REPO)
|
||||
|
@ -414,16 +533,20 @@ for f in $REPOSTOBACKUP; do
|
|||
checktag "$f" nfs
|
||||
if [[ $? -eq 0 ]]; then
|
||||
NFSNAME=`echo "${DATAPATH}" | sed -e "s,${NFS_PREFIX}/\(.*\).*,\1,"`
|
||||
NFSPATH="${NFS_SERVER}:${NFS_SERVER_BASE}/${NFSNAME}"
|
||||
NFSPATH="${DEF_NFS_SERVER}:${DEF_NFS_SERVER_BASE}/${NFSNAME}"
|
||||
USENFS=1
|
||||
else
|
||||
NFSNAME=""
|
||||
USENFS=0
|
||||
fi
|
||||
export RESTIC_REPOSITORY="b2:${B2_BUCKET_PREFIX}-${REPO}"
|
||||
export RCLONE_REPOSITORY="remote:${B2_BUCKET_PREFIX}-${REPO}"
|
||||
export RSYNC_FULLDIR="${RSYNC_DIR}/${REPO}"
|
||||
export RSYNC_REPOSITORY="${RSYNC_USER}@${RSYNC_SERVER}:${RSYNC_FULLDIR}"
|
||||
|
||||
|
||||
export REPO_PATH=`getrepopath "$f"`
|
||||
if [[ $? -eq 0 ]]; then
|
||||
USINGDEFAULT=0
|
||||
else
|
||||
USINGDEFAULT=1
|
||||
fi
|
||||
|
||||
if [[ $CMD == "go" ]]; then
|
||||
NEEDMOUNT=1
|
||||
|
@ -434,10 +557,22 @@ for f in $REPOSTOBACKUP; do
|
|||
fi
|
||||
|
||||
|
||||
getmode "$f"
|
||||
mode=`getmode "$f"`
|
||||
|
||||
SPEEDOPTS=""
|
||||
AUTHOPTS=""
|
||||
OTHEROPTS=""
|
||||
CONNECTIONOPTS=""
|
||||
if [[ $mode == "restic" ]]; then
|
||||
MYREPO="restic: $RESTIC_REPOSITORY"
|
||||
MYREPO="restic: $REPO_PATH"
|
||||
export RESTIC_REPOSITORY="$REPO_PATH"
|
||||
export RESTIC_PASSWORD_FILE=`getrepopassfile "$f"`
|
||||
if [[ ! -z $RESTIC_PASSWORD_FILE ]]; then
|
||||
unset RESTIC_PASSWORD
|
||||
AUTHOPTS="-p ${RESTIC_PASSWORD_FILE}"
|
||||
else
|
||||
AUTHOPTS="-p ${DEF_AUTHFILE}"
|
||||
fi
|
||||
if [[ -z $KSPEED ]]; then
|
||||
SPEEDOPTS=""
|
||||
else
|
||||
|
@ -450,11 +585,22 @@ for f in $REPOSTOBACKUP; do
|
|||
CONNECTIONSOPTS="-o b2.connections=${CONNECTIONS}"
|
||||
fi
|
||||
|
||||
AUTHOPTS="-p ${AUTHFILE}"
|
||||
export RESTIC_EXCLUDEFILE=`getrepoexcludefile "$f"`
|
||||
if [[ ! -z $RESTIC_PASSWORD_FILE ]]; then
|
||||
OTHEROPTS="$OTHEROPTS -exclude-file=${RESTIC_EXCLUDE}"
|
||||
fi
|
||||
elif [[ $mode == "rsync" ]]; then
|
||||
# rsync
|
||||
MYREPO="rsync: ${RSYNC_USER}@${RSYNC_SERVER}:${RSYNC_FULLDIR}"
|
||||
for f in RSYNC_SERVER RSYNC_USER RSYNC_DIR RSYNC_OPTIONS ]]; do
|
||||
MYREPO="rsync: $REPO_PATH"
|
||||
export RSYNC_REPOSITORY="$REPO_PATH"
|
||||
export RSYNC_FULLDIR="${DEF_RSYNC_DIR}/${REPO}"
|
||||
if [[ $USINGDEFAULT -eq 1 ]]; then
|
||||
list="DEF_RSYNC_SERVER DEF_RSYNC_USER DEF_RSYNC_DIR RSYNC_OPTIONS"
|
||||
else
|
||||
list="RSYNC_OPTIONS"
|
||||
fi
|
||||
|
||||
for f in $list; do
|
||||
eval val='$'$f
|
||||
if [[ -z $val ]]; then
|
||||
echo "Error - \$$f not set. Please update ${RCFILE}."
|
||||
|
@ -472,7 +618,8 @@ for f in $REPOSTOBACKUP; do
|
|||
CONNECTIONSOPTS=""
|
||||
else
|
||||
# rclone
|
||||
MYREPO="rclone: $RCLONE_REPOSITORY"
|
||||
MYREPO="rclone: $REPO_PATH"
|
||||
export RCLONE_REPOSITORY="$REPO_PATH"
|
||||
if [[ -z $KSPEED ]]; then
|
||||
SPEEDOPTS=""
|
||||
else
|
||||
|
@ -487,15 +634,50 @@ for f in $REPOSTOBACKUP; do
|
|||
fi
|
||||
|
||||
|
||||
if [[ ! $CMD == "check" ]]; then
|
||||
text="Starting '$CMD' on repo '$REPO' [$DATAPATH <-> $MYREPO]"
|
||||
log "$text"
|
||||
|
||||
if [[ $mode == "restic" ]]; then
|
||||
fi
|
||||
if [[ $CMD == "check" ]]; then
|
||||
line=`egrep "^$REPO:go:" $STATFILE 2>/dev/null`
|
||||
if [[ $? -eq 0 ]]; then
|
||||
# Get result
|
||||
code=`echo "$line" | cut -d: -f3`
|
||||
stamp=`echo "$line" | cut -d: -f4`
|
||||
date --version 2>&1 | grep -q GNU
|
||||
if [[ $? -eq 0 ]]; then
|
||||
humanstamp=`date --date="@$stamp"`
|
||||
else
|
||||
humanstamp=`date -r $stamp`
|
||||
fi
|
||||
now=`date +%s`
|
||||
age=$( echo "$now - $stamp" | bc )
|
||||
oneday=$( echo "24 * 60 * 60" | bc)
|
||||
if [[ $code -eq 0 ]]; then
|
||||
if [[ $age -le $oneday ]]; then
|
||||
echo "OK: Last backup for '$REPO' succeeded on $humanstamp."
|
||||
rv=0
|
||||
else
|
||||
echo "CRITICAL: Last backup for '$REPO' succeeded on $humanstamp (not in last 24 hours)."
|
||||
errcount=$(( $errcount + 1))
|
||||
rv=2
|
||||
fi
|
||||
else
|
||||
echo "CRITICAL: Last backup for '$REPO' failed on $humanstamp."
|
||||
rv=2
|
||||
errcount=$(( $errcount + 1))
|
||||
fi
|
||||
else
|
||||
echo "WARNING: No history found for repo '$REPO'"
|
||||
rv=1
|
||||
warncount=$(( $warncount + 1))
|
||||
fi
|
||||
elif [[ $mode == "restic" ]]; then
|
||||
if [[ $CMD == "go" ]]; then
|
||||
if [[ $CRONMODE -eq 1 ]]; then
|
||||
${RESTIC} backup $AUTHOPTS $CONNECTIONSOPTS $SPEEDOPTS $DATAPATH 2>&1 | egrep "^(Added|processed|snapshot)" >> ${LOG}
|
||||
${RESTIC} backup $AUTHOPTS $CONNECTIONSOPTS $SPEEDOPTS $OTHEROPTS $DATAPATH 2>&1 | egrep "^(Added|processed|snapshot)" >> ${LOG}
|
||||
else
|
||||
${RESTIC} backup $AUTHOPTS $CONNECTIONSOPTS $SPEEDOPTS $DATAPATH 2>&1 >> ${LOG}
|
||||
${RESTIC} backup $AUTHOPTS $CONNECTIONSOPTS $SPEEDOPTS $OTHEROPTS $DATAPATH 2>&1 >> ${LOG}
|
||||
fi
|
||||
rv=$?
|
||||
elif [[ $CMD == "ls" ]]; then
|
||||
|
@ -512,17 +694,20 @@ for f in $REPOSTOBACKUP; do
|
|||
${RESTIC} stats $AUTHOPTS $CONNECTIONSOPTS >/dev/null 2>&1
|
||||
if [ $? -eq 0 ]; then
|
||||
log "ERROR: Repo ${REPO} already exists. Aborting."
|
||||
rv=1
|
||||
else
|
||||
${RESTIC} init $AUTHOPTS $CONNECTIONSOPTS >/dev/null 2>&1
|
||||
rv=$?
|
||||
fi
|
||||
elif [[ $CMD == "forget" ]]; then
|
||||
# age out stuff after RESTIC_KEEPDAYS days
|
||||
FORGETOPTS="-d ${RESTIC_KEEPDAYS}"
|
||||
${RESTIC} forget $AUTHOPTS $CONNECTIONSOPTS $FORGETOPTS 2>&1 | awk '($1 == "Applying") { print } ($2 == "snapshots") { show=0 } (show == 1 && $1 != "ID" && NF > 1) { print "Removing: " $0 } ($1 == "remove") { show=1 }' >> ${LOG}
|
||||
rv=$?
|
||||
${RESTIC} prune $AUTHOPTS 2>&1 | egrep "^(repository contain|found|will|remove)" >> ${LOG}
|
||||
else
|
||||
log "Error: invalid command $CMD"
|
||||
rv=0
|
||||
rv=1
|
||||
fi
|
||||
elif [[ $mode == "rsync" ]]; then
|
||||
REMOTE=""
|
||||
|
@ -532,22 +717,22 @@ for f in $REPOSTOBACKUP; do
|
|||
${RSYNC} ${RSYNC_OPTIONS} $DATAPATH/ ${RSYNC_REPOSITORY} 2>&1 >> ${LOG}
|
||||
rv=$?
|
||||
elif [[ $CMD == "ls" ]]; then
|
||||
ssh ${RSYNC_USER}@${RSYNC_SERVER} ls ${RSYNC_FULLDIR} 2>&1 >> ${LOG}
|
||||
ssh ${DEF_RSYNC_USER}@${DEF_RSYNC_SERVER} ls ${RSYNC_FULLDIR} 2>&1 >> ${LOG}
|
||||
rv=$?
|
||||
elif [[ $CMD == "stats" ]]; then
|
||||
echo "Size of remote data for ${REPO}:"
|
||||
ssh ${RSYNC_USER}@${RSYNC_SERVER} du -hs ${RSYNC_FULLDIR} 2>&1 >> ${LOG}
|
||||
ssh ${DEF_RSYNC_USER}@${DEF_RSYNC_SERVER} du -hs ${RSYNC_FULLDIR} 2>&1 >> ${LOG}
|
||||
rv=$?
|
||||
elif [[ $CMD == "diff" ]]; then
|
||||
${RSYNC} ${RSYNC_OPTIONS} -n $DATAPATH/ ${RSYNC_REPOSITORY} 2>&1 >> ${LOG}
|
||||
rv=$?
|
||||
elif [[ $CMD == "init" ]]; then
|
||||
# check whether it already exists first!
|
||||
ssh ${RSYNC_USER}@${RSYNC_SERVER} ls -d ${RSYNC_FULLDIR} 2>&1 >> ${LOG}
|
||||
ssh ${DEF_RSYNC_USER}@${DEF_RSYNC_SERVER} ls -d ${RSYNC_FULLDIR} 2>&1 >> ${LOG}
|
||||
if [ $? -eq 0 ]; then
|
||||
log "ERROR: Repo ${REPO} already exists. Aborting."
|
||||
else
|
||||
ssh ${RSYNC_USER}@${RSYNC_SERVER} mkdir -p ${RSYNC_FULLDIR} 2>&1 >>${LOG}
|
||||
ssh ${DEF_RSYNC_USER}@${DEF_RSYNC_SERVER} mkdir -p ${RSYNC_FULLDIR} 2>&1 >>${LOG}
|
||||
if [ $? -eq 0 ]; then
|
||||
log "Created directory ${RSYNC_FULLDIR}..."
|
||||
else
|
||||
|
@ -556,24 +741,25 @@ for f in $REPOSTOBACKUP; do
|
|||
fi
|
||||
elif [[ $CMD == "forget" ]]; then
|
||||
log "Error: forget not supported for rsync mode."
|
||||
rv=1
|
||||
else
|
||||
log "Error: invalid command $CMD"
|
||||
rv=0
|
||||
rv=1
|
||||
fi
|
||||
else
|
||||
# rclone
|
||||
REMOTE=""
|
||||
if [[ $CMD == "go" ]]; then
|
||||
${RCLONE} sync $RCLONEOPTS $CONNECTIONSOPTS $SPEEDOPTS $DATAPATH $RCLONE_REPOSITORY 2>&1 >> ${LOG}
|
||||
${RCLONE} sync $RCLONEOPTS $CONNECTIONSOPTS $SPEEDOPTS $OTHEROPTS $DATAPATH $RCLONE_REPOSITORY 2>&1 >> ${LOG}
|
||||
rv=$?
|
||||
elif [[ $CMD == "ls" ]]; then
|
||||
${RCLONE} ls $RCLONEOPTS $CONNECTIONSOPTS $SPEEDOPTS $RCLONE_REPOSITORY 2>&1 >> ${LOG}
|
||||
${RCLONE} ls $RCLONEOPTS $CONNECTIONSOPTS $SPEEDOPTS $OTHEROPTS $RCLONE_REPOSITORY 2>&1 >> ${LOG}
|
||||
rv=$?
|
||||
elif [[ $CMD == "stats" ]]; then
|
||||
${RCLONE} size $RCLONEOPTS $CONNECTIONSOPTS $SPEEDOPTS $RCLONE_REPOSITORY 2>&1 >> ${LOG}
|
||||
${RCLONE} size $RCLONEOPTS $CONNECTIONSOPTS $SPEEDOPTS $OTHEROPTS $RCLONE_REPOSITORY 2>&1 >> ${LOG}
|
||||
rv=$?
|
||||
elif [[ $CMD == "diff" ]]; then
|
||||
${RCLONE} check $RCLONEOPTS $CONNECTIONSOPTS $SPEEDOPTS $RCLONE_REPOSITORY 2>&1 >> ${LOG}
|
||||
${RCLONE} check $RCLONEOPTS $CONNECTIONSOPTS $SPEEDOPTS $OTHEROPTS $RCLONE_REPOSITORY 2>&1 >> ${LOG}
|
||||
rv=$?
|
||||
elif [[ $CMD == "init" ]]; then
|
||||
# check whether it already exists first!
|
||||
|
@ -606,19 +792,38 @@ for f in $REPOSTOBACKUP; do
|
|||
fi
|
||||
elif [[ $CMD == "forget" ]]; then
|
||||
log "Error: forget not supported for rclone mode."
|
||||
rv=1
|
||||
else
|
||||
log "Error: invalid command $CMD"
|
||||
rv=0
|
||||
rv=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ ! $CMD == "check" ]]; then
|
||||
# Record result
|
||||
updatestats $f $CMD $rv
|
||||
fi
|
||||
|
||||
if [[ $rv -eq 0 ]]; then
|
||||
if [[ $NEEDMOUNT -eq 1 ]]; then
|
||||
do_umount
|
||||
fi
|
||||
else
|
||||
elif [[ ! $CMD == "check" ]]; then
|
||||
log "Error: '$CMD' on repo '$REPO' failed"
|
||||
fi
|
||||
|
||||
if [[ ! $CMD == "check" ]]; then
|
||||
log "Finished '$CMD' on repo '$REPO'"
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ $CMD == "check" ]]; then
|
||||
if [[ $errcount -ge 1 ]]; then
|
||||
rv=2
|
||||
elif [[ $warncount -ge 1 ]]; then
|
||||
rv=1
|
||||
else
|
||||
rv=0
|
||||
fi
|
||||
exit $rv
|
||||
fi
|
||||
|
|
Loading…
Reference in New Issue