1
0
mirror of https://github.com/deajan/obackup.git synced 2024-11-14 03:33:41 +01:00
obackup/obackup.sh

1373 lines
37 KiB
Bash
Raw Normal View History

2013-07-16 23:10:27 +02:00
#!/bin/bash
###### Remote (or local) backup script for files & databases
###### (L) 2013 by Orsiris "Ozy" de Jong (www.netpower.fr)
2013-11-02 18:55:17 +01:00
OBACKUP_VERSION=1.84RC3
2014-03-23 17:46:08 +01:00
OBACKUP_BUILD=2303201401
2013-07-16 23:10:27 +02:00
DEBUG=no
SCRIPT_PID=$$
LOCAL_USER=$(whoami)
LOCAL_HOST=$(hostname)
## Default log file until config file is loaded
2013-11-02 18:55:17 +01:00
if [ -w /var/log ]
2013-09-22 12:04:09 +02:00
then
LOG_FILE=/var/log/obackup.log
else
LOG_FILE=./obackup.log
fi
## Default directory where to store run files
2013-11-02 18:55:17 +01:00
if [ -w /dev/shm ]
2013-09-22 12:04:09 +02:00
then
RUN_DIR=/dev/shm
2013-11-02 18:55:17 +01:00
elif [ -w /tmp ]
2013-09-22 12:04:09 +02:00
then
RUN_DIR=/tmp
2013-11-02 18:55:17 +01:00
elif [ -w /var/tmp ]
2013-09-22 12:04:09 +02:00
then
RUN_DIR=/var/tmp
else
RUN_DIR=.
fi
2013-07-16 23:10:27 +02:00
## Log a state message every $KEEP_LOGGING seconds. Should generally not be equal to soft or hard execution time so your log won't be unnecessary big.
KEEP_LOGGING=1801
## Global variables and forked command results
DATABASES_TO_BACKUP="" # Processed list of DBs that will be backed up
DATABASES_EXCLUDED_LIST="" # Processed list of DBs that won't be backed up
TOTAL_DATABASES_SIZE=0 # Total DB size of $DATABASES_TO_BACKUP
DIRECTORIES_RECURSE_TO_BACKUP="" # Processed list of recursive directories that will be backed up
DIRECTORIES_EXCLUDED_LIST="" # Processed list of recursive directorires that won't be backed up
DIRECTORIES_TO_BACKUP="" # Processed list of all directories to backup
TOTAL_FILES_SIZE=0 # Total file size of $DIRECTORIES_TO_BACKUP
2013-11-02 18:55:17 +01:00
# $RUN_DIR/obackup_remote_os_$SCRIPT_PID Result of remote OS detection
2013-09-22 12:04:09 +02:00
# $RUN_DIR/obackup_dblist_$SCRIPT_PID Databases list and sizes
# $RUN_DIR/obackup_dirs_recurse_list_$SCRIPT_PID Recursive directories list
# $RUN_DIR/obackup_local_sql_storage_$SCRIPT_PID Local free space for sql backup
# $RUN_DIR/obackup_local_file_storage_$SCRIPT_PID Local free space for file backup
# $RUN_DIR/obackup_fsize_$SCRIPT_PID Size of $DIRECTORIES_TO_BACKUP
# $RUN_DIR/obackup_rsync_output_$SCRIPT_PID Output of Rsync command
# $RUN_DIR/obackup_config_$SCRIPT_PID Parsed configuration file
# $RUN_DIR/obackup_run_local_$SCRIPT_PID Output of command to be run localy
# $RUN_DIR/obackup_run_remote_$SCRIPT_PID Output of command to be run remotely
2013-07-16 23:10:27 +02:00
function Log
{
2013-11-02 18:55:17 +01:00
echo -e "TIME: $SECONDS - $1" >> "$LOG_FILE"
2013-07-16 23:10:27 +02:00
if [ $silent -eq 0 ]
then
2013-09-03 21:31:41 +02:00
echo -e "TIME: $SECONDS - $1"
2013-07-16 23:10:27 +02:00
fi
}
function LogError
{
Log "$1"
error_alert=1
}
function TrapError
{
local JOB="$0"
local LINE="$1"
local CODE="${2:-1}"
if [ $silent -eq 0 ]
then
echo " /!\ Error in ${JOB}: Near line ${LINE}, exit code ${CODE}"
fi
}
function TrapStop
{
LogError " /!\ WARNING: Manual exit of backup script. Backups may be in inconsistent state."
exit 1
}
function TrapQuit
{
2013-09-03 21:31:41 +02:00
# Kill all child processes
2013-09-22 12:04:09 +02:00
if type -p pkill > /dev/null 2>&1
then
pkill -TERM -P $$
2013-11-02 18:55:17 +01:00
elif [ "$LOCAL_OS" == "msys" ] || [ "$OSTYPE" == "msys" ]
2013-09-22 12:04:09 +02:00
then
## This is not really a clean way to get child process pids, especially the tail -n +2 which resolves a strange char apparition in msys bash
for pid in $(ps -a | awk '{$1=$1}$1' | awk '{print $1" "$2}' | grep " $$$" | awk '{print $1}' | tail -n +2)
do
kill -9 $pid > /dev/null 2>&1
done
else
for pid in $(ps -a --Group $$)
do
kill -9 $pid
done
fi
2013-09-03 21:31:41 +02:00
2013-07-18 13:31:17 +02:00
if [ $error_alert -ne 0 ]
then
SendAlert
2013-08-18 11:58:55 +02:00
CleanUp
2013-07-18 13:31:17 +02:00
LogError "Backup script finished with errors."
exit 1
else
2013-08-18 11:58:55 +02:00
CleanUp
2013-07-18 13:31:17 +02:00
Log "Backup script finshed."
exit 0
fi
2013-07-16 23:10:27 +02:00
}
function Spinner
{
if [ $silent -eq 1 ]
then
return 1
fi
case $toggle
in
1)
echo -n $1" \ "
echo -ne "\r"
toggle="2"
;;
2)
echo -n $1" | "
echo -ne "\r"
toggle="3"
;;
3)
echo -n $1" / "
echo -ne "\r"
toggle="4"
;;
*)
echo -n $1" - "
echo -ne "\r"
toggle="1"
;;
esac
}
function Dummy
{
exit 1;
}
function StripQuotes
{
echo $(echo $1 | sed "s/^\([\"']\)\(.*\)\1\$/\2/g")
}
function EscapeSpaces
{
echo $(echo $1 | sed 's/ /\\ /g')
}
function CleanUp
{
if [ "$DEBUG" != "yes" ]
then
2013-10-12 19:12:15 +02:00
rm -f "$RUN_DIR/obackup_remote_os_$SCRIPT_PID"
2013-09-22 12:04:09 +02:00
rm -f "$RUN_DIR/obackup_dblist_$SCRIPT_PID"
rm -f "$RUN_DIR/obackup_local_sql_storage_$SCRIPT_PID"
rm -f "$RUN_DIR/obackup_local_file_storage_$SCRIPT_PID"
rm -f "$RUN_DIR/obackup_dirs_recurse_list_$SCRIPT_PID"
rm -f "$RUN_DIR/obackup_fsize_$SCRIPT_PID"
rm -f "$RUN_DIR/obackup_rsync_output_$SCRIPT_PID"
rm -f "$RUN_DIR/obackup_config_$SCRIPT_PID"
rm -f "$RUN_DIR/obackup_run_local_$SCRIPT_PID"
rm -f "$RUN_DIR/obackup_run_remote_$SCRIPT_PID"
fi
2013-07-16 23:10:27 +02:00
}
function SendAlert
{
2013-11-02 18:55:17 +01:00
cat "$LOG_FILE" | gzip -9 > $RUN_DIR/obackup_lastlog.gz
2013-07-16 23:10:27 +02:00
if type -p mutt > /dev/null 2>&1
then
2013-11-02 18:55:17 +01:00
echo $MAIL_ALERT_MSG | $(type -p mutt) -x -s "Backup alert for $BACKUP_ID" $DESTINATION_MAILS -a $RUN_DIR/obackup_lastlog.gz
2013-09-22 12:04:09 +02:00
if [ $? != 0 ]
then
Log "WARNING: Cannot send alert email via $(type -p mutt) !!!"
else
Log "Sent alert mail using mutt."
fi
2013-07-16 23:10:27 +02:00
elif type -p mail > /dev/null 2>&1
2013-09-22 12:04:09 +02:00
then
2013-11-02 18:55:17 +01:00
echo $MAIL_ALERT_MSG | $(type -p mail) -a $RUN_DIR/obackup_lastlog.gz -s "Backup alert for $BACKUP_ID" $DESTINATION_MAILS
2013-09-22 12:04:09 +02:00
if [ $? != 0 ]
then
Log "WARNING: Cannot send alert email via $(type -p mail) with attachments !!!"
echo $MAIL_ALERT_MSG | $(type -p mail) -s "Backup alert for $BACKUP_ID" $DESTINATION_MAILS
if [ $? != 0 ]
then
Log "WARNING: Cannot send alert email via $(type -p mail) without attachments !!!"
else
Log "Sent alert mail using mail command without attachment."
fi
else
Log "Sent alert mail using mail command."
fi
elif type -p sendemail > /dev/null 2>&1
then
$(type -p sendemail) -f $SENDER_MAIL -t $DESTINATION_MAILS -u "Backup alert for $BACKUP_ID" -m "$MAIL_ALERT_MSG" -s $SMTP_SERVER -o username $SMTP_USER -p password $SMTP_PASSWORD > /dev/null 2>&1
2013-07-16 23:10:27 +02:00
if [ $? != 0 ]
then
2013-09-22 12:04:09 +02:00
Log "WARNING: Cannot send alert email via $(type -p sendemail) !!!"
2013-07-16 23:10:27 +02:00
else
Log "Sent alert mail using mail command without attachment."
2013-09-22 12:04:09 +02:00
fi
2013-07-16 23:10:27 +02:00
else
Log "WARNING: Cannot send alert email (no mutt / mail present) !!!"
2014-03-23 17:46:08 +01:00
fi
if -f $RUN_DIR/obackup_lastlog.gz
then
rm $RUN_DIR/obackup_lastlog.gz
2013-07-16 23:10:27 +02:00
fi
}
function LoadConfigFile
{
if [ ! -f "$1" ]
then
LogError "Cannot load backup configuration file [$1]. Backup cannot start."
return 1
2013-08-04 16:16:27 +02:00
elif [[ "$1" != *".conf" ]]
2013-07-16 23:10:27 +02:00
then
LogError "Wrong configuration file supplied [$1]. Backup cannot start."
2013-08-04 16:16:27 +02:00
return 1
2013-07-16 23:10:27 +02:00
else
2013-09-22 12:04:09 +02:00
egrep '^#|^[^ ]*=[^;&]*' "$1" > "$RUN_DIR/obackup_config_$SCRIPT_PID"
source "$RUN_DIR/obackup_config_$SCRIPT_PID"
2013-07-16 23:10:27 +02:00
fi
}
function CheckEnvironment
{
sed --version > /dev/null 2>&1
if [ $? != 0 ]
then
LogError "GNU coreutils not found (tested for sed --version). Backup cannot start."
return 1
fi
if [ "$REMOTE_BACKUP" == "yes" ]
then
if ! type -p ssh > /dev/null 2>&1
then
LogError "ssh not present. Cannot start backup."
return 1
fi
if [ "$BACKUP_SQL" != "no" ]
then
if ! type -p mysqldump > /dev/null 2>&1
then
LogError "mysqldump not present. Cannot start backup."
return 1
fi
fi
fi
if [ "$BACKUP_FILES" != "no" ]
then
if ! type -p rsync > /dev/null 2>&1
then
LogError "rsync not present. Backup cannot start."
return 1
fi
fi
}
2013-10-12 19:12:15 +02:00
function GetOperatingSystem
{
2013-11-16 12:44:21 +01:00
LOCAL_OS_VAR=$(uname -spio 2>&1)
if [ $? != 0 ]
then
LOCAL_OS_VAR=$(uname -v 2>&1)
if [ $! != 0 ]
then
LOCAL_OS_VAR=($uname)
fi
fi
2013-11-02 18:55:17 +01:00
if [ "$REMOTE_BACKUP" == "yes" ]
2013-10-12 19:12:15 +02:00
then
2013-11-02 18:55:17 +01:00
eval "$SSH_CMD \"uname -spio\" > $RUN_DIR/obackup_remote_os_$SCRIPT_PID 2>&1"
2013-11-16 12:44:21 +01:00
child_pid=$!
WaitForTaskCompletion $child_pid 120 240
retval=$?
if [ $retval != 0 ]
then
eval "$SSH_CMD \"uname -v\" > $RUN_DIR/obackup_remote_os_$SCRIPT_PID 2>&1"
child_pid=$!
WaitForTaskCompletion $child_pid 120 240
retval=$?
if [ $retval != 0 ]
then
eval "$SSH_CMD \"uname\" > $RUN_DIR/obackup_remote_os_$SCRIPT_PID 2>&1"
child_pid=$!
WaitForTaskCompletion $child_pid 120 240
retval=$?
if [ $retval != 0 ]
then
LogError "Cannot Get remote OS type."
fi
fi
fi
REMOTE_OS_VAR=$(cat $RUN_DIR/obackup_remote_os_$SCRIPT_PID)
fi
2013-10-12 19:12:15 +02:00
case $LOCAL_OS_VAR in
"Linux"*)
LOCAL_OS="Linux"
;;
"FreeBSD"*)
LOCAL_OS="FreeBSD"
;;
"MINGW32"*)
LOCAL_OS="msys"
;;
2013-11-16 12:44:21 +01:00
"Darwin"*)
LOCAL_OS="MacOSX"
;;
2013-10-12 19:12:15 +02:00
*)
LogError "Running on >> $LOCAL_OS_VAR << not supported. Please report to the author."
exit 1
;;
esac
if [ "$REMOTE_BACKUP" == "yes" ]
then
case $REMOTE_OS_VAR in
"Linux"*)
REMOTE_OS="Linux"
;;
"FreeBSD"*)
REMOTE_OS="FreeBSD"
;;
"MINGW32"*)
REMOTE_OS="msys"
;;
"Darwin"*)
REMOTE_OS="MacOSX"
;;
*)
LogError "Running on remote >> $REMOTE_OS_VAR << not supported. Please report to the author."
exit 1
esac
fi
2013-11-02 18:55:17 +01:00
if [ "$DEBUG" == "yes" ]
then
Log "Local OS: [$LOCAL_OS_VAR]."
if [ "$REMOTE_BACKUP" == "yes" ]
then
Log "Remote OS: [$REMOTE_OS_VAR]."
fi
fi
2013-10-12 19:12:15 +02:00
}
2013-07-16 23:10:27 +02:00
# Waits for pid $1 to complete. Will log an alert if $2 seconds exec time exceeded unless $2 equals 0. Will stop task and log alert if $3 seconds exec time exceeded.
2013-07-18 13:31:17 +02:00
function WaitForTaskCompletion
2013-07-16 23:10:27 +02:00
{
soft_alert=0
SECONDS_BEGIN=$SECONDS
2013-10-12 19:12:15 +02:00
if [ "$LOCAL_OS" == "msys" ]
2013-09-22 12:04:09 +02:00
then
PROCESS_TEST="ps -a | awk '{\$1=\$1}\$1' | awk '{print \$1}' | grep $1"
else
PROCESS_TEST="ps -p$1"
fi
while eval $PROCESS_TEST > /dev/null
2013-07-16 23:10:27 +02:00
do
Spinner
sleep 1
EXEC_TIME=$(($SECONDS - $SECONDS_BEGIN))
if [ $(($EXEC_TIME % $KEEP_LOGGING)) -eq 0 ]
then
Log "Current task still running."
fi
if [ $EXEC_TIME -gt $2 ]
then
if [ $soft_alert -eq 0 ] && [ $2 != 0 ]
then
LogError "Max soft execution time exceeded for task."
soft_alert=1
fi
if [ $EXEC_TIME -gt $3 ] && [ $3 != 0 ]
then
LogError "Max hard execution time exceeded for task. Stopping task execution."
2013-07-20 14:48:06 +02:00
kill -s SIGTERM $1
2013-07-18 13:31:17 +02:00
if [ $? == 0 ]
then
LogError "Task stopped succesfully"
else
2013-07-20 14:48:06 +02:00
LogError "Sending SIGTERM to process failed. Trying the hard way."
kill -9 $1
if [ $? != 0 ]
then
LogError "Could not stop task."
fi
2013-07-18 13:31:17 +02:00
fi
2013-07-16 23:10:27 +02:00
return 1
fi
fi
done
2013-07-20 14:48:06 +02:00
wait $child_pid
return $?
2013-07-16 23:10:27 +02:00
}
## Runs local command $1 and waits for completition in $2 seconds
function RunLocalCommand
{
2013-09-03 21:31:41 +02:00
if [ $dryrun -ne 0 ]
then
Log "Dryrun: Local command [$1] not run."
return 1
fi
2013-11-02 18:55:17 +01:00
Log "Running command [$1] on local host."
2013-11-02 19:41:05 +01:00
eval "$1" > $RUN_DIR/obackup_run_local_$SCRIPT_PID 2>&1 &
2013-07-16 23:10:27 +02:00
child_pid=$!
2013-07-18 13:31:17 +02:00
WaitForTaskCompletion $child_pid 0 $2
2013-07-16 23:10:27 +02:00
retval=$?
if [ $retval -eq 0 ]
then
2013-11-02 18:55:17 +01:00
Log "Command succeded."
2013-07-16 23:10:27 +02:00
else
2013-11-02 18:55:17 +01:00
LogError "Command failed."
2013-07-16 23:10:27 +02:00
fi
2013-07-20 14:48:06 +02:00
2013-11-16 12:44:21 +01:00
if [ $verbose -eq 1 ] || [ $retval -ne 0 ]
2013-07-20 14:48:06 +02:00
then
2013-09-22 12:04:09 +02:00
Log "Command output:\n$(cat $RUN_DIR/obackup_run_local_$SCRIPT_PID)"
2013-07-20 14:48:06 +02:00
fi
2013-09-11 16:18:32 +02:00
2013-11-02 18:55:17 +01:00
if [ "$STOP_ON_CMD_ERROR" == "yes" ] && [ $retval -ne 0 ]
2013-09-11 16:18:32 +02:00
then
exit 1
fi
2013-07-16 23:10:27 +02:00
}
## Runs remote command $1 and waits for completition in $2 seconds
function RunRemoteCommand
{
CheckConnectivity3rdPartyHosts
2013-08-24 19:41:18 +02:00
CheckConnectivityRemoteHost
2013-09-03 21:31:41 +02:00
if [ $dryrun -ne 0 ]
then
Log "Dryrun: Remote command [$1] not run."
return 1
fi
2013-11-02 18:55:17 +01:00
Log "Running command [$1] on remote host."
2013-09-22 12:04:09 +02:00
eval "$SSH_CMD \"$1\" > $RUN_DIR/obackup_run_remote_$SCRIPT_PID 2>&1 &"
2013-08-24 19:41:18 +02:00
child_pid=$!
WaitForTaskCompletion $child_pid 0 $2
retval=$?
if [ $retval -eq 0 ]
then
2013-11-02 18:55:17 +01:00
Log "Command succeded."
2013-08-24 19:41:18 +02:00
else
2013-11-02 18:55:17 +01:00
LogError "Command failed."
2013-08-24 19:41:18 +02:00
fi
2013-11-16 12:44:21 +01:00
if [ -f $RUN_DIR/obackup_run_remote_$SCRIPT_PID ] && ([ $verbose -eq 1 ] || $retval -ne 0 ])
2013-08-24 19:41:18 +02:00
then
2013-09-22 12:04:09 +02:00
Log "Command output:\n$(cat $RUN_DIR/obackup_run_remote_$SCRIPT_PID)"
2013-07-16 23:10:27 +02:00
fi
2013-09-11 16:18:32 +02:00
2013-11-02 18:55:17 +01:00
if [ "$STOP_ON_CMD_ERROR" == "yes" ] && [ $retval -ne 0 ]
2013-09-11 16:18:32 +02:00
then
2013-11-02 18:55:17 +01:00
exit 1
2013-09-11 16:18:32 +02:00
fi
2013-07-16 23:10:27 +02:00
}
function RunBeforeHook
{
if [ "$LOCAL_RUN_BEFORE_CMD" != "" ]
then
RunLocalCommand "$LOCAL_RUN_BEFORE_CMD" $MAX_EXEC_TIME_PER_CMD_BEFORE
fi
if [ "$REMOTE_RUN_BEFORE_CMD" != "" ]
then
RunRemoteCommand "$REMOTE_RUN_BEFORE_CMD" $MAX_EXEC_TIME_PER_CMD_BEFORE
fi
}
function RunAfterHook
{
if [ "$LOCAL_RUN_AFTER_CMD" != "" ]
then
RunLocalCommand "$LOCAL_RUN_AFTER_CMD" $MAX_EXEC_TIME_PER_CMD_AFTER
fi
if [ "$REMOTE_RUN_AFTER_CMD" != "" ]
then
RunRemoteCommand "$REMOTE_RUN_AFTER_CMD" $MAX_EXEC_TIME_PER_CMD_AFTER
fi
}
function CreateLocalStorageDirectories
{
if [ ! -d $LOCAL_SQL_STORAGE ] && [ "$BACKUP_SQL" != "no" ]
then
mkdir -p $LOCAL_SQL_STORAGE
fi
if [ ! -d $LOCAL_FILE_STORAGE ] && [ "$BACKUP_FILES" != "no" ]
then
mkdir -p $LOCAL_FILE_STORAGE
fi
}
function CheckSpaceRequirements
{
if [ "$BACKUP_SQL" != "no" ]
then
2013-11-02 18:55:17 +01:00
if [ -w $LOCAL_SQL_STORAGE ]
2013-07-16 23:10:27 +02:00
then
# Not elegant solution to make df silent on errors
2013-09-22 12:04:09 +02:00
df -P $LOCAL_SQL_STORAGE > $RUN_DIR/obackup_local_sql_storage_$SCRIPT_PID 2>&1
2013-07-16 23:10:27 +02:00
if [ $? != 0 ]
then
LOCAL_SQL_SPACE=0
else
2013-09-22 12:04:09 +02:00
LOCAL_SQL_SPACE=$(cat $RUN_DIR/obackup_local_sql_storage_$SCRIPT_PID | tail -1 | awk '{print $4}')
LOCAL_SQL_DRIVE=$(cat $RUN_DIR/obackup_local_sql_storage_$SCRIPT_PID | tail -1 | awk '{print $1}')
2013-07-16 23:10:27 +02:00
fi
if [ $LOCAL_SQL_SPACE -eq 0 ]
then
LogError "Local sql storage space reported to be 0Ko."
elif [ $LOCAL_SQL_SPACE -lt $TOTAL_DATABASES_SIZE ]
then
LogError "Local disk space may be insufficient to backup files (available space is lower than non compressed databases)."
fi
else
LOCAL_SQL_SPACE=0
2013-11-02 18:55:17 +01:00
LogError "SQL storage path [$LOCAL_SQL_STORAGE] doesn't exist or cannot write to it."
2013-07-16 23:10:27 +02:00
fi
2013-09-13 13:36:08 +02:00
else
LOCAL_SQL_SPACE=0
2013-07-16 23:10:27 +02:00
fi
if [ "$BACKUP_FILES" != "no" ]
then
2013-11-02 18:55:17 +01:00
if [ -w $LOCAL_FILE_STORAGE ]
2013-07-16 23:10:27 +02:00
then
2013-09-22 12:04:09 +02:00
df -P $LOCAL_FILE_STORAGE > $RUN_DIR/obackup_local_file_storage_$SCRIPT_PID 2>&1
2013-07-16 23:10:27 +02:00
if [ $? != 0 ]
then
LOCAL_FILE_SPACE=0
else
2013-09-22 12:04:09 +02:00
LOCAL_FILE_SPACE=$(cat $RUN_DIR/obackup_local_file_storage_$SCRIPT_PID | tail -1 | awk '{print $4}')
LOCAL_FILE_DRIVE=$(cat $RUN_DIR/obackup_local_file_storage_$SCRIPT_PID | tail -1 | awk '{print $1}')
2013-07-16 23:10:27 +02:00
fi
if [ $LOCAL_FILE_SPACE -eq 0 ]
then
LogError "Local file storage space reported to be 0Ko."
elif [ $LOCAL_FILE_SPACE -lt $TOTAL_FILES_SIZE ]
then
LogError "Local disk space may be insufficient to backup files (available space is lower than full backup)."
fi
else
LOCAL_FILE_SPACE=0
2013-11-02 18:55:17 +01:00
LogError "File storage path [$LOCAL_FILE_STORAGE] doesn't exist or cannot write to it."
2013-07-16 23:10:27 +02:00
fi
2013-09-13 13:36:08 +02:00
else
LOCAL_FILE_SPACE=0
2013-07-16 23:10:27 +02:00
fi
if [ "$LOCAL_SQL_DRIVE" == "$LOCAL_FILE_DRIVE" ]
then
LOCAL_SPACE=$LOCAL_FILE_SPACE
else
LOCAL_SPACE=$(($LOCAL_SQL_SPACE+$LOCAL_FILE_SPACE))
fi
if [ $BACKUP_SIZE_MINIMUM -gt $(($TOTAL_DATABASES_SIZE+$TOTAL_FILES_SIZE)) ]
then
LogError "Backup size is smaller then expected."
elif [ $LOCAL_STORAGE_WARN_MIN_SPACE -gt $LOCAL_SPACE ]
then
LogError "Local disk space is lower than warning value [$LOCAL_STORAGE_WARN_MIN_SPACE Ko]."
fi
Log "Local Space: $LOCAL_SPACE Ko - Databases size: $TOTAL_DATABASES_SIZE Ko - Files size: $TOTAL_FILES_SIZE Ko"
}
function CheckTotalExecutionTime
{
2013-08-24 19:41:18 +02:00
#### Check if max execution time of whole script as been reached
2013-07-16 23:10:27 +02:00
if [ $SECONDS -gt $SOFT_MAX_EXEC_TIME_TOTAL ]
then
if [ $soft_alert_total -eq 0 ]
then
LogError "Max soft execution time of the whole backup exceeded while backing up $BACKUP_TASK."
soft_alert_total=1
fi
if [ $SECONDS -gt $HARD_MAX_EXEC_TIME_TOTAL ]
then
LogError "Max hard execution time of the whole backup exceeded while backing up $BACKUP_TASK, stopping backup process."
exit 1
fi
fi
}
function CheckConnectivityRemoteHost
{
if [ "$REMOTE_HOST_PING" != "no" ] && [ "$REMOTE_BACKUP" != "no" ]
then
2013-10-12 19:12:15 +02:00
if [ "$LOCAL_OS" == "msys" ]
2013-09-22 12:04:09 +02:00
then
2013-10-12 19:12:15 +02:00
ping -n 2 $REMOTE_HOST > /dev/null 2>&1
2013-09-22 12:04:09 +02:00
else
2013-10-12 19:12:15 +02:00
ping -c 2 $REMOTE_HOST > /dev/null 2>&1
2013-09-22 12:04:09 +02:00
fi
2013-07-16 23:10:27 +02:00
if [ $? != 0 ]
then
LogError "Cannot ping $REMOTE_HOST"
return 1
fi
fi
}
function CheckConnectivity3rdPartyHosts
{
if [ "$REMOTE_3RD_PARTY_HOSTS" != "" ]
then
remote_3rd_party_success=0
OLD_IFS=$IFS
IFS=$' \t\n'
2013-08-24 19:41:18 +02:00
for i in $REMOTE_3RD_PARTY_HOSTS
2013-07-16 23:10:27 +02:00
do
2013-10-12 19:12:15 +02:00
if [ "$LOCAL_OS" == "msys" ]
2013-09-22 12:04:09 +02:00
then
2013-10-12 19:12:15 +02:00
ping -n 2 $i > /dev/null 2>&1
2013-09-22 12:04:09 +02:00
else
2013-10-12 19:12:15 +02:00
ping -c 2 $i > /dev/null 2>&1
2013-09-22 12:04:09 +02:00
fi
2013-07-16 23:10:27 +02:00
if [ $? != 0 ]
then
LogError "Cannot ping 3rd party host $i"
else
remote_3rd_party_success=1
fi
done
IFS=$OLD_IFS
2013-07-16 23:10:27 +02:00
if [ $remote_3rd_party_success -ne 1 ]
then
LogError "No remote 3rd party host responded to ping. No internet ?"
return 1
fi
fi
}
function ListDatabases
{
SECONDS_BEGIN=$SECONDS
Log "Listing databases."
CheckConnectivity3rdPartyHosts
2013-08-24 19:41:18 +02:00
CheckConnectivityRemoteHost
if [ "$REMOTE_BACKUP" != "no" ]
2013-07-16 23:10:27 +02:00
then
2013-09-22 12:04:09 +02:00
eval "$SSH_CMD \"mysql -u $SQL_USER -Bse 'SELECT table_schema, round(sum( data_length + index_length ) / 1024) FROM information_schema.TABLES GROUP by table_schema;'\" > $RUN_DIR/obackup_dblist_$SCRIPT_PID &"
2013-07-16 23:10:27 +02:00
else
2013-09-22 12:04:09 +02:00
mysql -u $SQL_USER -Bse 'SELECT table_schema, round(sum( data_length + index_length ) / 1024) FROM information_schema.TABLES GROUP by table_schema;' > $RUN_DIR/obackup_dblist_$SCRIPT_PID &
2013-07-16 23:10:27 +02:00
fi
child_pid=$!
2013-07-18 13:31:17 +02:00
WaitForTaskCompletion $child_pid $SOFT_MAX_EXEC_TIME_DB_TASK $HARD_MAX_EXEC_TIME_DB_TASK
2013-07-16 23:10:27 +02:00
retval=$?
if [ $retval -eq 0 ]
then
Log "Listing databases succeeded."
else
LogError "Listing databases failed."
2013-09-22 12:04:09 +02:00
if [ -f $RUN_DIR/obackup_dblist_$SCRIPT_PID ]
2013-07-16 23:10:27 +02:00
then
2013-09-22 12:04:09 +02:00
LogError "Command output:\n$(cat $RUN_DIR/obackup_dblist_$SCRIPT_PID)"
2013-07-16 23:10:27 +02:00
fi
return $retval
fi
2013-09-22 12:04:09 +02:00
OLD_IFS=$IFS
IFS=$' \n'
for line in $(cat $RUN_DIR/obackup_dblist_$SCRIPT_PID)
2013-07-16 23:10:27 +02:00
do
2013-09-22 12:04:09 +02:00
db_name=$(echo $line | cut -f1)
db_size=$(echo $line | cut -f2)
2013-07-16 23:10:27 +02:00
if [ "$DATABASES_ALL" == "yes" ]
then
db_backup=1
for j in $DATABASES_ALL_EXCLUDE_LIST
do
if [ "$db_name" == "$j" ]
then
db_backup=0
fi
done
else
db_backup=0
for j in $DATABASES_LIST
do
if [ "$db_name" == "$j" ]
then
db_backup=1
fi
done
fi
if [ $db_backup -eq 1 ]
then
if [ "$DATABASES_TO_BACKUP" != "" ]
then
DATABASES_TO_BACKUP="$DATABASES_TO_BACKUP $db_name"
else
DATABASES_TO_BACKUP=$db_name
fi
TOTAL_DATABASES_SIZE=$((TOTAL_DATABASES_SIZE+$db_size))
else
DATABASES_EXCLUDED_LIST="$DATABASES_EXCLUDED_LIST $db_name"
fi
2013-09-22 12:04:09 +02:00
done
IFS=$OLD_IFS
2013-11-02 18:55:17 +01:00
if [ $verbose -eq 1 ]
then
Log "Database backup list: $DATABASES_TO_BACKUP"
Log "Database exclude list: $DATABASES_EXCLUDED_LIST"
fi
2013-07-16 23:10:27 +02:00
}
function BackupDatabase
{
CheckConnectivity3rdPartyHosts
if [ "$REMOTE_BACKUP" == "yes" ] && [ "$COMPRESSION_REMOTE" == "no" ]
then
CheckConnectivityRemoteHost
if [ $? != 0 ]
then
LogError "Connectivity test failed. Stopping current task."
exit 1
fi
2013-11-02 18:55:17 +01:00
sql_cmd="$SSH_CMD mysqldump -u $SQL_USER --skip-lock-tables --single-transaction --database $1 | $COMPRESSION_PROGRAM -$COMPRESSION_LEVEL $COMPRESSION_OPTIONS > $LOCAL_SQL_STORAGE/$1.sql$COMPRESSION_EXTENSION"
2013-07-16 23:10:27 +02:00
elif [ "$REMOTE_BACKUP" == "yes" ] && [ "$COMPRESSION_REMOTE" == "yes" ]
then
CheckConnectivityRemoteHost
if [ $? != 0 ]
then
LogError "Connectivity test failed. Stopping current task."
exit 1
fi
2013-11-02 18:55:17 +01:00
sql_cmd="$SSH_CMD \"mysqldump -u $SQL_USER --skip-lock-tables --single-transaction --database $1 | $COMPRESSION_PROGRAM -$COMPRESSION_LEVEL $COMPRESSION_OPTIONS\" > $LOCAL_SQL_STORAGE/$1.sql$COMPRESSION_EXTENSION"
2013-07-16 23:10:27 +02:00
else
2013-11-02 18:55:17 +01:00
sql_cmd="mysqldump -u $SQL_USER --skip-lock-tables --single-transaction --database $1 | $COMPRESSION_PROGRAM -$COMPRESSION_LEVEL $COMPRESSION_OPTIONS > $LOCAL_SQL_STORAGE/$1.sql$COMPRESSION_EXTENSION"
2013-07-16 23:10:27 +02:00
fi
2013-11-02 18:55:17 +01:00
if [ $verbose -eq 1 ]
then
Log "SQL_CMD: $sql_cmd"
fi
eval $sql_cmd
2013-07-16 23:10:27 +02:00
exit $?
}
function BackupDatabases
{
OLD_IFS=$IFS
IFS=$' \t\n'
2013-07-16 23:10:27 +02:00
for BACKUP_TASK in $DATABASES_TO_BACKUP
do
Log "Backing up database $BACKUP_TASK"
SECONDS_BEGIN=$SECONDS
BackupDatabase $BACKUP_TASK &
child_pid=$!
2013-07-18 13:31:17 +02:00
WaitForTaskCompletion $child_pid $SOFT_MAX_EXEC_TIME_DB_TASK $HARD_MAX_EXEC_TIME_DB_TASK
2013-07-16 23:10:27 +02:00
retval=$?
if [ $retval -ne 0 ]
then
LogError "Backup failed."
else
Log "Backup succeeded."
fi
CheckTotalExecutionTime
done
IFS=$OLD_IFS
2013-07-16 23:10:27 +02:00
}
# Fetches single quoted directory listing including recursive ones separated by commas (eg '/dir1';'/dir2';'/dir3')
function ListDirectories
{
SECONDS_BEGIN=$SECONDS
Log "Listing directories to backup."
OLD_IFS=$IFS
IFS=$PATH_SEPARATOR_CHAR
2013-08-24 19:41:18 +02:00
for dir in $DIRECTORIES_RECURSE_LIST
2013-07-16 23:10:27 +02:00
do
CheckConnectivity3rdPartyHosts
if [ "$REMOTE_BACKUP" == "yes" ]
then
CheckConnectivityRemoteHost
if [ $? != 0 ]
then
LogError "Connectivity test failed. Stopping current task."
Dummy &
else
2013-09-22 12:04:09 +02:00
eval "$SSH_CMD \"$COMMAND_SUDO $FIND_CMD $dir/ -mindepth 1 -maxdepth 1 -type d\" > $RUN_DIR/obackup_dirs_recurse_list_$SCRIPT_PID &"
2013-07-16 23:10:27 +02:00
fi
else
2013-09-22 12:04:09 +02:00
eval "$COMMAND_SUDO $FIND_CMD $dir/ -mindepth 1 -maxdepth 1 -type d > $RUN_DIR/obackup_dirs_recurse_list_$SCRIPT_PID &"
2013-07-16 23:10:27 +02:00
fi
child_pid=$!
2013-07-18 13:31:17 +02:00
WaitForTaskCompletion $child_pid $SOFT_MAX_EXEC_TIME_FILE_TASK $HARD_MAX_EXEC_TIME_FILE_TASK
2013-07-16 23:10:27 +02:00
retval=$?
if [ $retval != 0 ]
then
2013-08-24 19:41:18 +02:00
LogError "Could not enumerate recursive directories in $dir."
2013-09-22 12:04:09 +02:00
if [ -f $RUN_DIR/obackup_dirs_recurse_list_$SCRIPT_PID ]
2013-07-16 23:10:27 +02:00
then
2013-09-22 12:04:09 +02:00
LogError "Command output:\n$(cat $RUN_DIR/obackup_dirs_recurse_list_$SCRIPT_PID)"
2013-07-16 23:10:27 +02:00
fi
return 1
fi
2013-09-22 12:04:09 +02:00
OLD_IFS=$IFS
IFS=$' \n'
for line in $(cat $RUN_DIR/obackup_dirs_recurse_list_$SCRIPT_PID)
2013-07-16 23:10:27 +02:00
do
file_exclude=0
IFS=$PATH_SEPARATOR_CHAR
2013-07-16 23:10:27 +02:00
for k in $DIRECTORIES_RECURSE_EXCLUDE_LIST
do
if [ "$k" == "$line" ]
then
file_exclude=1
fi
done
IFS=$' \n'
2013-07-16 23:10:27 +02:00
if [ $file_exclude -eq 0 ]
then
if [ "$DIRECTORIES_TO_BACKUP" == "" ]
then
DIRECTORIES_TO_BACKUP="'$line'"
else
DIRECTORIES_TO_BACKUP="$DIRECTORIES_TO_BACKUP$PATH_SEPARATOR_CHAR'$line'"
fi
else
DIRECTORIES_EXCLUDED_LIST="$DIRECTORIES_EXCLUDED_LIST$PATH_SEPARATOR_CHAR'$line'"
fi
2013-09-22 12:04:09 +02:00
done
2013-11-02 18:55:17 +01:00
Log "Listing of recursive directories succeeded for $dir"
if [ $verbose -eq 1 ]
then
Log "\n$(cat $RUN_DIR/obackup_dirs_recurse_list_$SCRIPT_PID)"
fi
2013-09-22 12:04:09 +02:00
IFS=$OLD_IFS
2013-07-16 23:10:27 +02:00
done
DIRECTORIES_TO_BACKUP_RECURSE=$DIRECTORIES_TO_BACKUP
2013-08-24 19:41:18 +02:00
for dir in $DIRECTORIES_SIMPLE_LIST
2013-07-16 23:10:27 +02:00
do
if [ "$DIRECTORIES_TO_BACKUP" == "" ]
then
2013-08-24 19:41:18 +02:00
DIRECTORIES_TO_BACKUP="'$dir'"
2013-07-16 23:10:27 +02:00
else
2013-08-24 19:41:18 +02:00
DIRECTORIES_TO_BACKUP="$DIRECTORIES_TO_BACKUP$PATH_SEPARATOR_CHAR'$dir'"
2013-07-16 23:10:27 +02:00
fi
done
IFS=$OLD_IFS
}
function GetDirectoriesSize
{
# remove the path separator char from the dir list with sed 's/;/ /g'
dir_list=$(echo $DIRECTORIES_TO_BACKUP | sed 's/'"$PATH_SEPARATOR_CHAR"'/ /g' )
Log "Getting files size"
CheckConnectivity3rdPartyHosts
if [ "$REMOTE_BACKUP" == "yes" ]
then
CheckConnectivityRemoteHost
if [ $? != 0 ]
then
LogError "Connectivity test failed. Stopping current task."
Dummy &
else
2013-09-22 12:04:09 +02:00
eval "$SSH_CMD \"echo $dir_list | xargs $COMMAND_SUDO du -cs | tail -n1 | cut -f1\" > $RUN_DIR/obackup_fsize_$SCRIPT_PID &"
2013-07-16 23:10:27 +02:00
fi
else
2013-09-22 12:04:09 +02:00
echo $dir_list | xargs $COMMAND_SUDO du -cs | tail -n1 | cut -f1 > $RUN_DIR/obackup_fsize_$SCRIPT_PID &
2013-07-16 23:10:27 +02:00
fi
child_pid=$!
2013-07-18 13:31:17 +02:00
WaitForTaskCompletion $child_pid $SOFT_MAX_EXEC_TIME_FILE_TASK $HARD_MAX_EXEC_TIME_FILE_TASK
2013-07-16 23:10:27 +02:00
retval=$?
if [ $retval != 0 ]
then
LogError "Could not get files size."
2013-09-22 12:04:09 +02:00
if [ -f $RUN_DIR/obackup_fsize_$SCRIPT_PID ]
2013-07-16 23:10:27 +02:00
then
2013-09-22 12:04:09 +02:00
LogError "Command output:\n$(cat $RUN_DIR/obackup_fsize_$SCRIPT_PID)"
2013-07-16 23:10:27 +02:00
fi
return 1
else
Log "File size fetched successfully."
2013-09-22 12:04:09 +02:00
TOTAL_FILES_SIZE=$(cat $RUN_DIR/obackup_fsize_$SCRIPT_PID)
2013-07-16 23:10:27 +02:00
fi
}
function RsyncExcludePattern
{
OLD_IFS=$IFS
IFS=$PATH_SEPARATOR_CHAR
for excludedir in $RSYNC_EXCLUDE_PATTERN
do
if [ "$RSYNC_EXCLUDE" == "" ]
then
RSYNC_EXCLUDE="--exclude=$(EscapeSpaces $excludedir)"
else
RSYNC_EXCLUDE="$RSYNC_EXCLUDE --exclude=$(EscapeSpaces $excludedir)"
fi
done
IFS=$OLD_IFS
}
function Rsync
{
i="$(StripQuotes $1)"
if [ "$LOCAL_STORAGE_KEEP_ABSOLUTE_PATHS" == "yes" ]
then
local_file_storage_path="$(dirname $LOCAL_FILE_STORAGE$i)"
else
2013-11-02 18:55:17 +01:00
local_file_storage_path=$LOCAL_FILE_STORAGE
2013-07-16 23:10:27 +02:00
fi
2013-11-02 18:55:17 +01:00
## Manage to backup recursive directories lists files only (not recursing into subdirectories)
if [ "$2" == "no-recurse" ]
then
RSYNC_EXCLUDE=$RSYNC_EXCLUDE" --exclude=*/*/"
fi
2013-07-16 23:10:27 +02:00
if [ ! -d $local_file_storage_path ]
then
mkdir -p "$local_file_storage_path"
fi
CheckConnectivity3rdPartyHosts
if [ "$REMOTE_BACKUP" == "yes" ]
then
CheckConnectivityRemoteHost
if [ $? != 0 ]
then
LogError "Connectivity test failed. Stopping current task."
exit 1
fi
2013-11-02 18:55:17 +01:00
rsync_cmd="$(type -p $RSYNC_EXECUTABLE) $RSYNC_ARGS --stats $RSYNC_DELETE $RSYNC_EXCLUDE --rsync-path=\"$RSYNC_PATH\" -e \"$RSYNC_SSH_CMD\" \"$REMOTE_USER@$REMOTE_HOST:$1\" \"$local_file_storage_path\" > $RUN_DIR/obackup_rsync_output_$SCRIPT_PID 2>&1"
2013-07-16 23:10:27 +02:00
else
2013-11-02 18:55:17 +01:00
rsync_cmd="$(type -p $RSYNC_EXECUTABLE) $RSYNC_ARGS --stats $RSYNC_DELETE $RSYNC_EXCLUDE --rsync-path=\"$RSYNC_PATH\" \"$1\" \"$local_file_storage_path\" > $RUN_DIR/obackup_rsync_output_$SCRIPT_PID 2>&1"
2013-07-16 23:10:27 +02:00
fi
#### Eval is used so the full command is processed without bash adding single quotes round variables
2013-08-18 11:58:55 +02:00
if [ $verbose -eq 1 ]
2013-07-16 23:10:27 +02:00
then
2013-08-18 11:58:55 +02:00
Log "RSYNC_CMD: $rsync_cmd"
2013-07-16 23:10:27 +02:00
fi
eval $rsync_cmd
exit $?
}
#### First backup simple list then recursive list
function FilesBackup
{
OLD_IFS=$IFS
IFS=$PATH_SEPARATOR_CHAR
for BACKUP_TASK in $DIRECTORIES_SIMPLE_LIST
do
BACKUP_TASK=$(StripQuotes $BACKUP_TASK)
2013-11-02 18:55:17 +01:00
Log "Beginning recursive file backup on $BACKUP_TASK"
2013-07-16 23:10:27 +02:00
SECONDS_BEGIN=$SECONDS
Rsync $BACKUP_TASK &
child_pid=$!
2013-07-18 13:31:17 +02:00
WaitForTaskCompletion $child_pid $SOFT_MAX_EXEC_TIME_FILE_TASK $HARD_MAX_EXEC_TIME_FILE_TASK
2013-07-16 23:10:27 +02:00
retval=$?
2013-09-22 12:04:09 +02:00
if [ $verbose -eq 1 ] && [ -f $RUN_DIR/obackup_rsync_output_$SCRIPT_PID ]
2013-08-18 11:58:55 +02:00
then
2013-09-22 12:04:09 +02:00
Log "List:\n$(cat $RUN_DIR/obackup_rsync_output_$SCRIPT_PID)"
2013-08-18 11:58:55 +02:00
fi
2013-07-16 23:10:27 +02:00
if [ $retval -ne 0 ]
then
LogError "Backup failed on remote files."
2013-09-22 12:04:09 +02:00
if [ $verbose -eq 0 ] && [ -f $RUN_DIR/obackup_rsync_output_$SCRIPT_PID ]
2013-08-25 12:39:13 +02:00
then
2013-09-22 12:04:09 +02:00
LogError "$(cat $RUN_DIR/obackup_rsync_output_$SCRIPT_PID)"
2013-08-25 12:39:13 +02:00
fi
2013-07-16 23:10:27 +02:00
else
Log "Backup succeeded."
fi
CheckTotalExecutionTime
done
2013-11-02 18:55:17 +01:00
## Also backup files at root of DIRECTORIES_RECURSE_LIST directories
for BACKUP_TASK in $DIRECTORIES_RECURSE_LIST
do
BACKUP_TASK="$(StripQuotes $BACKUP_TASK)"
Log "Beginning non recursive file backup on $BACKUP_TASK"
SECONDS_BEGIN=$SECONDS
Rsync $BACKUP_TASK "no-recurse" &
child_pid=$!
WaitForTaskCompletion $child_pid $SOFT_MAX_EXEC_TIME_FILE_TASK $HARD_MAX_EXEC_TIME_FILE_TASK
retval=$?
if [ $verbose -eq 1 ] && [ -f $RUN_DIR/obackup_rsync_output_$SCRIPT_PID ]
then
Log "List:\n$(cat $RUN_DIR/obackup_rsync_output_$SCRIPT_PID)"
fi
if [ $retval -ne 0 ]
then
LogError "Backup failed on remote files."
if [ $verbose -eq 0 ] && [ -f $RUN_DIR/obackup_rsync_output_$SCRIPT_PID ]
then
LogError "$(cat $RUN_DIR/obackup_rsync_output_$SCRIPT_PID)"
fi
else
Log "Backup succeeded."
fi
CheckTotalExecutionTime
done
2013-07-16 23:10:27 +02:00
for BACKUP_TASK in $DIRECTORIES_TO_BACKUP_RECURSE
do
BACKUP_TASK=$(StripQuotes $BACKUP_TASK)
2013-11-02 18:55:17 +01:00
Log "Beginning recursive file backup on $BACKUP_TASK"
2013-07-16 23:10:27 +02:00
SECONDS_BEGIN=$SECONDS
Rsync $BACKUP_TASK "recurse" &
child_pid=$!
2013-07-18 13:31:17 +02:00
WaitForTaskCompletion $child_pid $SOFT_MAX_EXEC_TIME_FILE_TASK $HARD_MAX_EXEC_TIME_FILE_TASK
2013-07-16 23:10:27 +02:00
retval=$?
2013-09-22 12:04:09 +02:00
if [ $verbose -eq 1 ] && [ -f $RUN_DIR/obackup_rsync_output_$SCRIPT_PID ]
2013-08-25 12:39:13 +02:00
then
2013-09-22 12:04:09 +02:00
Log "List:\n$(cat $RUN_DIR/obackup_rsync_output_$SCRIPT_PID)"
2013-08-25 12:39:13 +02:00
fi
2013-07-16 23:10:27 +02:00
if [ $retval -ne 0 ]
then
LogError "Backup failed on remote files."
2013-09-22 12:04:09 +02:00
if [ $verbose -eq 0 ] && [ -f $RUN_DIR/obackup_rsync_output_$SCRIPT_PID ]
2013-07-16 23:10:27 +02:00
then
2013-09-22 12:04:09 +02:00
LogError "$(cat $RUN_DIR/obackup_rsync_output_$SCRIPT_PID)"
2013-07-16 23:10:27 +02:00
fi
else
Log "Backup succeeded."
fi
CheckTotalExecutionTime
done
2013-11-02 18:55:17 +01:00
2013-07-16 23:10:27 +02:00
IFS=$OLD_IFS
}
# Will rotate everything in $1
function RotateBackups
{
OLD_IFS=$IFS
IFS=$' \t\n'
2013-07-16 23:10:27 +02:00
for backup in $(ls -I "*.obackup.*" $1)
do
copy=$ROTATE_COPIES
while [ $copy -gt 1 ]
do
if [ $copy -eq $ROTATE_COPIES ]
then
rm -rf "$1/$backup.obackup.$copy"
fi
path="$1/$backup.obackup.$(($copy-1))"
if [[ -f $path || -d $path ]]
then
mv $path "$1/$backup.obackup.$copy"
fi
copy=$(($copy-1))
done
# Latest file backup will not be moved if script configured for remote backup so next rsync execution will only do delta copy instead of full one
if [[ $backup == *.sql.* ]]
then
mv "$1/$backup" "$1/$backup.obackup.1"
elif [ "$REMOTE_BACKUP" == "yes" ]
then
cp -R "$1/$backup" "$1/$backup.obackup.1"
else
mv "$1/$backup" "$1/$backup.obackup.1"
fi
done
IFS=$OLD_IFS
2013-07-16 23:10:27 +02:00
}
function Init
{
# Set error exit code if a piped command fails
set -o pipefail
set -o errtrace
trap TrapStop SIGINT SIGQUIT SIGKILL SIGTERM SIGHUP
trap TrapQuit EXIT
2013-07-16 23:10:27 +02:00
if [ "$DEBUG" == "yes" ]
then
trap 'TrapError ${LINENO} $?' ERR
fi
2013-08-18 11:58:55 +02:00
if [ "$LOGFILE" == "" ]
then
2013-11-02 18:55:17 +01:00
if [ -w /var/log ]
2013-09-22 12:04:09 +02:00
then
LOG_FILE=/var/log/obackup_$OBACKUP_VERSION-$BACKUP_ID.log
else
LOG_FILE=./obackup_$OBACKUP_VERSION_$BACKUP_ID.log
fi
2013-08-18 11:58:55 +02:00
else
LOG_FILE="$LOGFILE"
fi
2013-07-16 23:10:27 +02:00
MAIL_ALERT_MSG="Warning: Execution of obackup instance $BACKUP_ID (pid $SCRIPT_PID) as $LOCAL_USER@$LOCAL_HOST produced errors."
2013-09-22 12:04:09 +02:00
## If running Msys, find command of windows is used instead of msys one
2013-10-12 19:12:15 +02:00
if [ "$LOCAL_OS" == "msys" ]
2013-09-22 12:04:09 +02:00
then
FIND_CMD=$(dirname $BASH)/find
else
FIND_CMD=find
fi
2013-07-20 14:48:06 +02:00
## Set SSH command
if [ "$SSH_COMPRESSION" == "yes" ]
then
SSH_COMP=-C
else
SSH_COMP=
fi
2013-09-22 12:04:09 +02:00
SSH_CMD="$(type -p ssh) $SSH_COMP -i $SSH_RSA_PRIVATE_KEY $REMOTE_USER@$REMOTE_HOST -p $REMOTE_PORT"
RSYNC_SSH_CMD="$(type -p ssh) $SSH_COMP -i $SSH_RSA_PRIVATE_KEY -p $REMOTE_PORT"
2013-07-20 14:48:06 +02:00
## Support for older config files without RSYNC_EXECUTABLE option
if [ "$RSYNC_EXECUTABLE" == "" ]
then
RSYNC_EXECUTABLE=rsync
fi
## Sudo execution option
if [ "$SUDO_EXEC" == "yes" ]
then
2013-09-22 12:04:09 +02:00
if [ "$RSYNC_REMOTE_PATH" != "" ]
then
2014-03-23 17:46:08 +01:00
RSYNC_PATH="sudo $RSYNC_REMOTE_PATH/$RSYNC_EXECUTABLE"
2013-09-22 12:04:09 +02:00
else
2013-10-10 20:39:17 +02:00
RSYNC_PATH="sudo $RSYNC_EXECUTABLE"
2013-09-22 12:04:09 +02:00
fi
COMMAND_SUDO="sudo"
2013-07-20 14:48:06 +02:00
else
2013-09-22 12:04:09 +02:00
if [ "$RSYNC_REMOTE_PATH" != "" ]
then
2014-03-23 17:46:08 +01:00
RSYNC_PATH="$RSYNC_REMOTE_PATH/$RSYNC_EXECUTABLE"
2013-09-22 12:04:09 +02:00
else
2013-10-10 20:39:17 +02:00
RSYNC_PATH="$RSYNC_EXECUTABLE"
2013-09-22 12:04:09 +02:00
fi
2013-07-20 14:48:06 +02:00
COMMAND_SUDO=""
fi
2013-08-18 11:58:55 +02:00
## Set Rsync arguments
RSYNC_ARGS=-rlptgoDE
2013-09-10 11:58:45 +02:00
if [ "$PRESERVE_ACL" == "yes" ]
2013-08-18 11:58:55 +02:00
then
RSYNC_ARGS=$RSYNC_ARGS"A"
fi
if [ "$PRESERVE_XATTR" == "yes" ]
then
RSYNC_ARGS=$RSYNC_ARGS"X"
fi
if [ "$RSYNC_COMPRESS" == "yes" ]
then
RSYNC_ARGS=$RSYNC_ARGS"z"
fi
if [ $verbose -eq 1 ]
then
RSYNC_ARGS=$RSYNC_ARGS"i"
fi
if [ $dryrun -eq 1 ]
then
RSYNC_ARGS=$RSYNC_ARGS"n"
DRY_WARNING="/!\ DRY RUN"
fi
2013-11-02 18:55:17 +01:00
if [ "$BANDWIDTH" != "" ] && [ "$BANDWIDTH" != "0" ]
2013-08-18 11:58:55 +02:00
then
RSYNC_ARGS=$RSYNC_ARGS" --bwlimit=$BANDWIDTH"
fi
2013-07-20 14:48:06 +02:00
## Set compression executable and extension
if [ "$COMPRESSION_PROGRAM" == "xz" ] && type -p xz > /dev/null 2>&1
then
COMPRESSION_EXTENSION=.xz
elif [ "$COMPRESSION_PROGRAM" == "lzma" ] && type -p lzma > /dev/null 2>&1
then
COMPRESSION_EXTENSION=.lzma
elif [ "$COMPRESSION_PROGRAM" == "gzip" ] && type -p gzip > /dev/null 2>&1
then
COMPRESSION_EXTENSION=.gz
COMPRESSION_OPTIONS=--rsyncable
else
COMPRESSION_EXTENSION=
fi
2013-07-16 23:10:27 +02:00
}
function Main
{
if [ "$BACKUP_SQL" != "no" ]
then
ListDatabases
fi
if [ "$BACKUP_FILES" != "no" ]
then
ListDirectories
GetDirectoriesSize
fi
2013-08-18 11:58:55 +02:00
if [ $dryrun -ne 1 ]
then
CreateLocalStorageDirectories
fi
2013-08-24 19:41:18 +02:00
2013-07-16 23:10:27 +02:00
CheckSpaceRequirements
2013-08-18 11:58:55 +02:00
# Actual backup process
2013-07-16 23:10:27 +02:00
if [ "$BACKUP_SQL" != "no" ]
then
2013-08-18 11:58:55 +02:00
if [ $dryrun -ne 1 ]
2013-07-16 23:10:27 +02:00
then
2013-08-18 11:58:55 +02:00
if [ "$ROTATE_BACKUPS" == "yes" ]
then
RotateBackups $LOCAL_SQL_STORAGE
fi
BackupDatabases
else
Log "DRYRUN: databases not backed up."
2013-07-16 23:10:27 +02:00
fi
fi
2013-08-18 11:58:55 +02:00
2013-07-16 23:10:27 +02:00
if [ "$BACKUP_FILES" != "no" ]
then
2013-08-18 11:58:55 +02:00
if [ $dryrun -ne 1 ]
2013-07-16 23:10:27 +02:00
then
2013-08-18 11:58:55 +02:00
if [ "$ROTATE_BACKUPS" == "yes" ]
then
RotateBackups $LOCAL_FILE_STORAGE
fi
2013-07-16 23:10:27 +02:00
fi
RsyncExcludePattern
FilesBackup
fi
# Be a happy sysadmin (and drink a coffee ? Nahh... it's past midnight.)
}
function Usage
{
echo "Obackup $OBACKUP_VERSION $OBACKUP_BUILD"
echo ""
2013-09-03 21:31:41 +02:00
echo "usage: obackup /path/to/backup.conf [--dry] [--silent] [--verbose] [--no-maxtime]"
2013-07-16 23:10:27 +02:00
echo ""
echo "--dry: will run obackup without actually doing anything, just testing"
echo "--silent: will run obackup without any output to stdout, usefull for cron backups"
2013-07-21 21:42:00 +02:00
echo "--verbose: adds command outputs"
2013-08-18 11:58:55 +02:00
echo "--no-maxtime: disables any soft and hard execution time checks"
2013-07-16 23:10:27 +02:00
exit 128
}
# Command line argument flags
dryrun=0
silent=0
2013-08-18 11:58:55 +02:00
no_maxtime=0
if [ "$DEBUG" == "yes" ]
then
verbose=1
else
verbose=0
fi
2013-07-16 23:10:27 +02:00
# Alert flags
soft_alert_total=0
error_alert=0
if [ $# -eq 0 ]
then
Usage
fi
for i in "$@"
do
case $i in
--dry)
dryrun=1
;;
--silent)
silent=1
;;
2013-07-20 14:48:06 +02:00
--verbose)
verbose=1
;;
2013-08-18 11:58:55 +02:00
--no-maxtime)
no_maxtime=1
;;
2013-07-20 14:48:06 +02:00
--help|-h|--version|-v)
2013-07-16 23:10:27 +02:00
Usage
;;
esac
done
CheckEnvironment
if [ $? == 0 ]
then
if [ "$1" != "" ]
then
LoadConfigFile $1
if [ $? == 0 ]
then
Init
DATE=$(date)
Log "--------------------------------------------------------------------"
2013-08-18 11:58:55 +02:00
Log "$DRY_WARNING $DATE - Obackup v$OBACKUP_VERSION script begin."
2013-07-16 23:10:27 +02:00
Log "--------------------------------------------------------------------"
2013-08-18 11:58:55 +02:00
Log "Backup task [$BACKUP_ID] launched as $LOCAL_USER@$LOCAL_HOST (PID $SCRIPT_PID)"
2013-11-16 12:44:21 +01:00
GetOperatingSystem
2013-08-18 11:58:55 +02:00
if [ $no_maxtime -eq 1 ]
then
SOFT_MAX_EXEC_TIME=0
HARD_MAX_EXEC_TIME=0
fi
OLD_IFS=$IFS
RunBeforeHook
Main
IFS=$OLD_IFS
RunAfterHook
2013-07-16 23:10:27 +02:00
CleanUp
else
LogError "Configuration file could not be loaded."
exit 1
fi
else
LogError "No configuration file provided."
exit 1
fi
else
LogError "Environment not suitable to run obackup."
2013-10-10 19:17:45 +02:00
exit 1
2013-07-16 23:10:27 +02:00
fi