2013-06-18 11:34:14 +00:00
#!/bin/bash
2013-07-16 11:55:15 +00:00
###### Osync - Rsync based two way sync engine.
###### (L) 2013 by Orsiris "Ozy" de Jong (www.netpower.fr)
## todo:
2013-07-16 21:06:26 +00:00
# add dryrun, DOC: never run dry when already run real or you will lose your deleted file history
2013-07-16 11:55:15 +00:00
# add logging
# add resume on error
# remote functionnality
2013-07-15 22:10:23 +00:00
OSYNC_VERSION = 0.4
2013-07-16 21:06:26 +00:00
OSYNC_BUILD = 1607201305
2013-06-18 11:34:14 +00:00
2013-07-15 22:10:23 +00:00
DEBUG = no
2013-06-18 11:34:14 +00:00
SCRIPT_PID = $$
LOCAL_USER = $( whoami)
LOCAL_HOST = $( hostname)
2013-07-15 22:10:23 +00:00
## Default log file until config file is loaded
LOG_FILE = /var/log/osync.log
2013-07-16 11:55:15 +00:00
## Working directory. Will keep current file states, backups and soft deleted files.
2013-07-15 22:10:23 +00:00
OSYNC_DIR = ".osync_workdir"
## Log a state message every $KEEP_LOGGING seconds. Should not be equal to soft or hard execution time so your log won't be unnecessary big.
KEEP_LOGGING = 1801
2013-06-18 11:34:14 +00:00
function Log
{
2013-07-16 21:06:26 +00:00
echo -e " TIME: $SECONDS - $1 " >> " $LOG_FILE "
2013-07-15 22:10:23 +00:00
if [ $silent -eq 0 ]
then
2013-07-16 21:06:26 +00:00
echo -e " TIME: $SECONDS - $1 "
2013-07-15 22:10:23 +00:00
fi
2013-06-18 11:34:14 +00:00
}
function LogError
{
2013-07-15 22:10:23 +00:00
Log " $1 "
error_alert = 1
2013-06-18 11:34:14 +00:00
}
function TrapError
{
2013-07-15 22:10:23 +00:00
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
2013-06-18 11:34:14 +00:00
}
2013-07-16 21:06:26 +00:00
function TrapStop
{
LogError " /!\ WARNING: Manual exit of osync is really not recommended. Sync will be in inconsistent state."
LogError " /!\ WARNING: If you are sure, please hit CTRL+C another time to quit."
if [ $soft_stop -eq 0 ]
then
soft_stop = 1
fi
if [ " $DEBUG " = = "no" ] && [ $soft_stop -eq 1 ]
then
CleanUp
exit 1
fi
}
2013-06-18 11:34:14 +00:00
function Spinner
{
2013-07-15 22:10:23 +00:00
if [ $silent -eq 1 ]
then
return 1
fi
2013-06-18 11:34:14 +00:00
2013-07-15 22:10:23 +00:00
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
2013-06-18 11:34:14 +00:00
}
2013-07-15 22:10:23 +00:00
function CleanUp
2013-06-18 11:34:14 +00:00
{
2013-07-15 22:10:23 +00:00
rm -f /dev/shm/osync_config_$SCRIPT_PID
rm -f /dev/shm/osync_run_local_$SCRIPT_PID
rm -f /dev/shm/osync_run_remote_$SCRIPT_PID
2013-07-16 21:06:26 +00:00
rm -f /dev/shm/osync_master-tree-current_$SCRIPT_PID
rm -f /dev/shm/osync_slave-tree-current_$SCRIPT_PID
rm -f /dev/shm/osync_master-tree-before_$SCRIPT_PID
rm -f /dev/shm/osync_slave-tree-before_$SCRIPT_PID
rm -f /dev/shm/osync_update_master_replica_$SCRIPT_PID
rm -f /dev/shm/osync_update_slave_replica_$SCRIPT_PID
rm -f /dev/shm/osync_deletition_on_master_$SCRIPT_PID
rm -f /dev/shm/osync_deletition_on_slave_$SCRIPT_PID
2013-06-18 11:34:14 +00:00
}
function SendAlert
{
2013-07-15 22:10:23 +00:00
CheckConnectivityRemoteHost
CheckConnectivity3rdPartyHosts
cat " $LOG_FILE " | gzip -9 > /tmp/osync_lastlog.gz
2013-06-18 11:34:14 +00:00
if type -p mutt > /dev/null 2>& 1
then
echo $MAIL_ALERT_MSG | $( which mutt) -x -s " Sync alert for $SYNC_ID " $DESTINATION_MAILS -a /tmp/osync_lastlog.gz
if [ $? != 0 ]
then
Log " WARNING: Cannot send alert email via $( which mutt) !!! "
2013-07-15 22:10:23 +00:00
else
Log "Sent alert mail using mutt."
2013-06-18 11:34:14 +00:00
fi
elif type -p mail > /dev/null 2>& 1
2013-07-15 22:10:23 +00:00
then
2013-06-18 11:34:14 +00:00
echo $MAIL_ALERT_MSG | $( which mail) -a /tmp/osync_lastlog.gz -s " Sync alert for $SYNC_ID " $DESTINATION_MAILS
if [ $? != 0 ]
then
Log " WARNING: Cannot send alert email via $( which mail) with attachments !!! "
2013-07-15 22:10:23 +00:00
echo $MAIL_ALERT_MSG | $( which mail) -s " Sync alert for $SYNC_ID " $DESTINATION_MAILS
if [ $? != 0 ]
then
Log " WARNING: Cannot send alert email via $( which mail) without attachments !!! "
else
Log "Sent alert mail using mail command without attachment."
fi
else
Log "Sent alert mail using mail command."
2013-06-18 11:34:14 +00:00
fi
else
2013-07-15 22:10:23 +00:00
Log "WARNING: Cannot send alert email (no mutt / mail present) !!!"
return 1
fi
2013-06-18 11:34:14 +00:00
}
function LoadConfigFile
{
2013-07-15 22:10:23 +00:00
if [ ! -f " $1 " ]
then
LogError " Cannot load configuration file [ $1 ]. Sync cannot start. "
return 1
elif [ [ $1 != *.conf ] ]
then
LogError " Wrong configuration file supplied [ $1 ]. Sync cannot start. "
else
egrep '^#|^[^ ]*=[^;&]*' " $1 " > " /dev/shm/osync_config_ $SCRIPT_PID "
source " /dev/shm/osync_config_ $SCRIPT_PID "
fi
}
2013-06-18 11:34:14 +00:00
function CheckEnvironment
{
2013-07-15 22:10:23 +00:00
if [ " $REMOTE_SYNC " = = "yes" ]
2013-06-18 11:34:14 +00:00
then
2013-07-15 22:10:23 +00:00
if ! type -p ssh > /dev/null 2>& 1
then
LogError "ssh not present. Cannot start sync."
return 1
fi
fi
if ! type -p rsync > /dev/null 2>& 1
then
LogError "rsync not present. Sync cannot start."
return 1
fi
2013-06-18 11:34:14 +00: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.
function WaitForTaskCompletition
{
soft_alert = 0
SECONDS_BEGIN = $SECONDS
while ps -p$1 > /dev/null
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."
return 1
fi
fi
done
}
## Runs local command $1 and waits for completition in $2 seconds
function RunLocalCommand
{
2013-07-15 22:10:23 +00:00
CheckConnectivity3rdPartyHosts
$1 > /dev/shm/osync_run_local_$SCRIPT_PID &
child_pid = $!
WaitForTaskCompletition $child_pid 0 $2
wait $child_pid
retval = $?
if [ $retval -eq 0 ]
then
Log " Running command [ $1 ] on local host succeded. "
else
Log " Running command [ $1 ] on local host failed. "
fi
2013-06-18 11:34:14 +00:00
2013-07-15 22:10:23 +00:00
Log "Command output:"
Log " $( cat /dev/shm/osync_run_local_$SCRIPT_PID ) "
2013-06-18 11:34:14 +00:00
}
## Runs remote command $1 and waits for completition in $2 seconds
function RunRemoteCommand
{
2013-07-15 22:10:23 +00:00
CheckConnectivity3rdPartyHosts
if [ " $REMOTE_SYNC " = = "yes" ]
then
CheckConnectivityRemoteHost
if [ $? != 0 ]
then
LogError "Connectivity test failed. Cannot run remote command."
return 1
else
$( which ssh) $SSH_COMP -i $SSH_RSA_PRIVATE_KEY $REMOTE_USER @$REMOTE_HOST -p $REMOTE_PORT " $1 " > /dev/shm/osync_run_remote_$SCRIPT_PID &
fi
child_pid = $!
WaitForTaskCompletition $child_pid 0 $2
wait $child_pid
retval = $?
if [ $retval -eq 0 ]
then
Log " Running command [ $1 ] succeded. "
else
LogError " Running command [ $1 ] failed. "
fi
if [ -f /dev/shm/osync_run_remote_$SCRIPT_PID ]
then
Log " Command output: $( cat /dev/shm/osync_run_remote_$SCRIPT_PID ) "
fi
fi
2013-06-18 11:34:14 +00:00
}
function RunBeforeHook
{
2013-07-15 22:10:23 +00:00
if [ " $LOCAL_RUN_BEFORE_CMD " != "" ]
then
RunLocalCommand " $LOCAL_RUN_BEFORE_CMD " $MAX_EXEC_TIME_PER_CMD_BEFORE
fi
2013-06-18 11:34:14 +00:00
2013-07-15 22:10:23 +00:00
if [ " $REMOTE_RUN_BEFORE_CMD " != "" ]
then
RunRemoteCommand " $REMOTE_RUN_BEFORE_CMD " $MAX_EXEC_TIME_PER_CMD_BEFORE
fi
2013-06-18 11:34:14 +00:00
}
function RunAfterHook
{
if [ " $LOCAL_RUN_AFTER_CMD " != "" ]
then
2013-07-15 22:10:23 +00:00
RunLocalCommand " $LOCAL_RUN_AFTER_CMD " $MAX_EXEC_TIME_PER_CMD_AFTER
2013-06-18 11:34:14 +00:00
fi
2013-07-15 22:10:23 +00:00
if [ " $REMOTE_RUN_AFTER_CMD " != "" ]
then
RunRemoteCommand " $REMOTE_RUN_AFTER_CMD " $MAX_EXEC_TIME_PER_CMD_AFTER
fi
2013-06-18 11:34:14 +00:00
}
function SetCompressionOptions
{
2013-07-15 22:10:23 +00:00
if [ " $SSH_COMPRESSION " = = "yes" ]
then
SSH_COMP = -C
else
SSH_COMP =
fi
}
function SetSudoOptions
{
## Add this to support prior config files without RSYNC_EXECUTABLE option
if [ " $RSYNC_EXECUTABLE " = = "" ]
then
RSYNC_EXECUTABLE = rsync
fi
if [ " $SUDO_EXEC " = = "yes" ]
then
RSYNC_PATH = " sudo $( which $RSYNC_EXECUTABLE ) "
COMMAND_SUDO = "sudo"
else
RSYNC_PATH = " $( which $RSYNC_EXECUTABLE ) "
COMMAND_SUDO = ""
fi
}
function CheckConnectivityRemoteHost
{
if [ " $REMOTE_HOST_PING " != "no" ] && [ " $REMOTE_SYNC " != "no" ]
then
ping $REMOTE_HOST -c 2 > /dev/null 2>& 1
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
for $i in $REMOTE_3RD_PARTY_HOSTS
do
ping $i -c 2 > /dev/null 2>& 1
if [ $? != 0 ]
then
LogError " Cannot ping 3rd party host $i "
else
remote_3rd_party_success = 1
fi
done
if [ $remote_3rd_party_success -ne 1 ]
then
LogError "No remote 3rd party host responded to ping. No internet ?"
return 1
fi
fi
}
function CreateDirs
{
if ! [ -d $MASTER_SYNC_DIR /$OSYNC_DIR ]
2013-06-18 11:34:14 +00:00
then
2013-07-15 22:10:23 +00:00
mkdir $MASTER_SYNC_DIR /$OSYNC_DIR
2013-06-18 11:34:14 +00:00
fi
2013-07-15 22:10:23 +00:00
if ! [ -d $STATE_DIR ]
2013-06-18 11:34:14 +00:00
then
2013-07-15 22:10:23 +00:00
mkdir $STATE_DIR
2013-06-18 11:34:14 +00:00
fi
2013-07-15 22:10:23 +00:00
2013-06-18 11:34:14 +00:00
}
2013-07-15 22:10:23 +00:00
function CheckMasterSlaveDirs
2013-06-18 11:34:14 +00:00
{
2013-07-15 22:10:23 +00:00
if ! [ -d $MASTER_SYNC_DIR ]
2013-06-18 11:34:14 +00:00
then
2013-07-15 22:10:23 +00:00
LogError " Master directory [ $MASTER_SYNC_DIR ] does not exist. "
return 1
2013-06-18 11:34:14 +00:00
fi
2013-07-15 22:10:23 +00:00
if ! [ -d $SLAVE_SYNC_DIR ]
2013-06-18 11:34:14 +00:00
then
2013-07-15 22:10:23 +00:00
LogError " Slave directory [ $SLAVE_SYNC_DIR ] does not exist. "
return 1
2013-06-18 11:34:14 +00:00
fi
}
2013-07-15 22:10:23 +00:00
function LockMaster
{
2013-07-16 11:55:15 +00:00
echo "Not implemented yet"
2013-07-15 22:10:23 +00:00
}
function LockSlave
2013-06-18 11:34:14 +00:00
{
2013-07-16 11:55:15 +00:00
echo "Not implemented yet"
2013-07-15 22:10:23 +00:00
}
2013-07-16 11:55:15 +00:00
# Subfunction of Sync
function sync_update_master
2013-07-15 22:10:23 +00:00
{
2013-07-16 11:55:15 +00:00
Log "Updating slave replica."
2013-07-16 21:33:30 +00:00
rsync $DRY_OPTION -rlptgodEui $SLAVE_BACKUP --exclude " $OSYNC_DIR " --exclude-from " $STATE_DIR /master-deleted-list " --exclude-from " $STATE_DIR /slave-deleted-list " $MASTER_SYNC_DIR / $SLAVE_SYNC_DIR / > /dev/shm/osync_update_slave_replica_$SCRIPT_PID 2>& 1 &
2013-07-16 21:06:26 +00:00
child_pid = $!
WaitForTaskCompletition $child_pid $SOFT_MAX_EXEC_TIME 0
retval = $?
if [ $retval != 0 ]
then
LogError "Updating slave replica failed. Stopping execution."
else
Log "Updating slave replica succeded."
fi
if [ " $VERBOSE_LOGS " = = "yes" ]
then
Log " List:\n $( cat /dev/shm/osync_update_slave_replica_$SCRIPT_PID ) "
fi
return $retval
2013-07-16 11:55:15 +00:00
}
# Subfunction of Sync
function sync_update_slave
{
Log "Updating master replica."
2013-07-16 21:33:30 +00:00
rsync $DRY_OPTION -rlptgodEui $MASTER_BACKUP --exclude " $OSYNC_DIR " --exclude-from " $STATE_DIR /slave-deleted-list " --exclude-from " $STATE_DIR /master-deleted-list " $SLAVE_SYNC_DIR / $MASTER_SYNC_DIR / > /dev/shm/osync_update_master_replica_$SCRIPT_PID 2>& 1 &
2013-07-16 21:06:26 +00:00
child_pid = $!
WaitForTaskCompletition $child_pid $SOFT_MAX_EXEC_TIME 0
retval = $?
if [ $retval != 0 ]
then
LogError "Updating master replica failed. Stopping execution."
else
Log "Updating master replica succeded."
fi
if [ " $VERBOSE_LOGS " = = "yes" ]
then
Log " List:\n $( cat /dev/shm/osync_update_master_replica_$SCRIPT_PID ) "
fi
return $retval
2013-07-16 11:55:15 +00:00
}
2013-07-15 22:10:23 +00:00
2013-07-16 11:55:15 +00:00
function Sync
{
2013-07-15 22:10:23 +00:00
## Lock master dir
## Lock slave dir
Log "Starting synchronization task."
2013-07-16 11:55:15 +00:00
Log "Creating master replica file list."
2013-07-16 21:06:26 +00:00
rsync -rlptgodE --exclude " $OSYNC_DIR " --list-only $MASTER_SYNC_DIR / | grep "^-\|^d" | awk '{print $5}' | grep -v " ^\. $" > /dev/shm/osync_master-tree-current_$SCRIPT_PID &
child_pid = $!
WaitForTaskCompletition $child_pid $SOFT_MAX_EXEC_TIME $HARD_MAX_EXEC_TIME
retval = $?
if [ $retval = = 0 ] && [ -f /dev/shm/osync_master-tree-current_$SCRIPT_PID ]
then
mv /dev/shm/osync_master-tree-current_$SCRIPT_PID $STATE_DIR /master-tree-current
else
LogError "Cannot create master file list."
return 1
fi
2013-07-16 11:55:15 +00:00
Log "Creating slave replica file list."
2013-07-16 21:06:26 +00:00
rsync -rlptgodE --exclude " $OSYNC_DIR " --list-only $SLAVE_SYNC_DIR / | grep "^-\|^d" | awk '{print $5}' | grep -v " ^\. $" > /dev/shm/osync_slave-tree-current_$SCRIPT_PID &
child_pid = $!
WaitForTaskCompletition $child_pid $SOFT_MAX_EXEC_TIME $HARD_MAX_EXEC_TIME
retval = $?
if [ $retval = = 0 ] && [ -f /dev/shm/osync_slave-tree-current_$SCRIPT_PID ]
then
mv /dev/shm/osync_slave-tree-current_$SCRIPT_PID $STATE_DIR /slave-tree-current
else
LogError "Cannot create slave file list."
return 1
fi
2013-07-15 22:10:23 +00:00
2013-07-16 11:55:15 +00:00
Log "Creating master replica deleted file list."
2013-07-15 22:10:23 +00:00
if [ -f $STATE_DIR /master-tree-before ]
2013-06-18 11:34:14 +00:00
then
2013-07-15 22:10:23 +00:00
comm --nocheck-order -23 $STATE_DIR /master-tree-before $STATE_DIR /master-tree-current > $STATE_DIR /master-deleted-list
2013-06-18 11:34:14 +00:00
else
2013-07-15 22:10:23 +00:00
touch $STATE_DIR /master-deleted-list
2013-06-18 11:34:14 +00:00
fi
2013-07-16 11:55:15 +00:00
Log "Creating slave replica deleted file list."
2013-07-15 22:10:23 +00:00
if [ -f $STATE_DIR /slave-tree-before ]
2013-06-18 11:34:14 +00:00
then
2013-07-15 22:10:23 +00:00
comm --nocheck-order -23 $STATE_DIR /slave-tree-before $STATE_DIR /slave-tree-current > $STATE_DIR /slave-deleted-list
else
touch $STATE_DIR /slave-deleted-list
2013-06-18 11:34:14 +00:00
fi
2013-07-15 22:10:23 +00:00
2013-07-16 11:55:15 +00:00
if [ " $CONFLICT_PREVALANCE " != "master" ]
then
sync_update_slave
2013-07-16 21:06:26 +00:00
if [ $? != 0 ]
then
return 1
fi
2013-07-16 11:55:15 +00:00
sync_update_master
2013-07-16 21:06:26 +00:00
if [ $? != 0 ]
then
return 1
fi
2013-07-16 11:55:15 +00:00
else
sync_update_master
2013-07-16 21:06:26 +00:00
if [ $? != 0 ]
then
return 1
fi
2013-07-16 11:55:15 +00:00
sync_update_slave
2013-07-16 21:06:26 +00:00
if [ $? != 0 ]
then
return 1
fi
2013-07-16 11:55:15 +00:00
fi
2013-07-15 22:10:23 +00:00
2013-07-16 11:55:15 +00:00
Log "Propagating deletitions to slave replica."
2013-07-16 21:33:30 +00:00
rsync $DRY_OPTION -rlptgodEui $SLAVE_DELETE --delete --exclude " $OSYNC_DIR " --exclude-from " $STATE_DIR /slave-deleted-list " --include-from " $STATE_DIR /master-deleted-list " $MASTER_SYNC_DIR / $SLAVE_SYNC_DIR / > /dev/shm/osync_deletition_on_slave_$SCRIPT_PID 2>& 1 &
2013-07-16 21:06:26 +00:00
child_pid = $!
WaitForTaskCompletition $child_pid $SOFT_MAX_EXEC_TIME 0
if [ $? != 0 ]
then
LogError "Deletition on slave failed."
return 1
fi
if [ " $VERBOSE_LOGS " = = "yes" ]
then
Log " List:\n $( cat /dev/shm/osync_deletition_on_slave_$SCRIPT_PID ) "
fi
2013-07-16 11:55:15 +00:00
Log "Propagating deletitions to master replica."
2013-07-16 21:33:30 +00:00
rsync $DRY_OPTION -rlptgodEui $MASTER_DELETE --delete --exclude " $OSYNC_DIR " --exclude-from " $STATE_DIR /master-deleted-list " --include-from " $STATE_DIR /slave-deleted-list " $SLAVE_SYNC_DIR / $MASTER_SYNC_DIR / > /dev/shm/osync_deletition_on_master_$SCRIPT_PID 2>& 1 &
2013-07-16 21:06:26 +00:00
child_pid = $!
WaitForTaskCompletition $child_pid $SOFT_MAX_EXEC_TIME 0
if [ $? != 0 ]
then
LogError "Deletition on master failed."
return 1
fi
if [ " $VERBOSE_LOGS " = = "yes" ]
then
Log " List:\n $( cat /dev/shm/osync_deletition_on_master_$SCRIPT_PID ) "
fi
2013-07-15 22:10:23 +00:00
2013-07-16 11:55:15 +00:00
Log "Creating new master replica file list."
2013-07-16 21:06:26 +00:00
rsync -rlptgodE --exclude " $OSYNC_DIR " --list-only $MASTER_SYNC_DIR / | grep "^-\|^d" | awk '{print $5}' | grep -v " ^\. $" > /dev/shm/osync_master-tree-before_$SCRIPT_PID &
child_pid = $!
WaitForTaskCompletition $child_pid $SOFT_MAX_EXEC_TIME 0
retval = $?
if [ $retval = = 0 ] && [ -f /dev/shm/osync_master-tree-before_$SCRIPT_PID ]
then
mv /dev/shm/osync_master-tree-before_$SCRIPT_PID $STATE_DIR /master-tree-before
else
LogError "Cannot create slave file list."
return 1
fi
2013-07-16 11:55:15 +00:00
Log "Creating new slave replica file list."
2013-07-16 21:06:26 +00:00
rsync -rlptgodE --exclude " $OSYNC_DIR " --list-only $SLAVE_SYNC_DIR / | grep "^-\|^d" | awk '{print $5}' | grep -v " ^\. $" > /dev/shm/osync_slave-tree-before_$SCRIPT_PID &
child_pid = $!
WaitForTaskCompletition $child_pid $SOFT_MAX_EXEC_TIME 0
retval = $?
if [ $retval = = 0 ] && [ -f /dev/shm/osync_slave-tree-before_$SCRIPT_PID ]
then
mv /dev/shm/osync_slave-tree-before_$SCRIPT_PID $STATE_DIR /slave-tree-before
else
LogError "Cannot create slave file list."
return 1
fi
2013-07-15 22:10:23 +00:00
Log "Finished synchronization task."
2013-06-18 11:34:14 +00:00
}
2013-07-15 22:10:23 +00:00
function SoftDelete
2013-06-18 11:34:14 +00:00
{
2013-07-16 11:55:15 +00:00
if [ " $CONFLICT_BACKUP " != "no" ]
then
if [ -d $MASTER_BACKUP_DIR ]
then
Log " Removing backups older than $CONFLICT_BACKUP_DAYS days on master replica. "
find $MASTER_BACKUP_DIR / -ctime +$CONFLICT_BACKUP_DAYS | xargs rm -rf
fi
if [ -d $SLAVE_BACKUP_DIR ]
then
Log " Removing backups older than $CONFLICT_BACKUP_DAYS days on slave replica. "
find $SLAVE_BACKUP_DIR / -ctime +$CONFLICT_BACKUP_DAYS | xargs rm -rf
fi
fi
if [ " $SOFT_DELETE " != "no" ]
then
if [ -d $MASTER_DELETE_DIR ]
then
Log " Removing soft deleted items older than $SOFT_DELETE_DAYS days on master replica. "
find $MASTER_DELETE_DIR / -ctime +$SOFT_DELETE_DAYS | xargs rm -rf
fi
if [ -d $SLAVE_DELETE_DIR ]
then
Log " Removing soft deleted items older than $SOFT_DELETE_DAYS days on slave replica. "
find $SLAVE_DELETE_DIR / -ctime +$SOFT_DELETE_DAYS | xargs rm -rf
fi
fi
2013-07-15 22:10:23 +00:00
}
function Init
{
# Set error exit code if a piped command fails
set -o pipefail
set -o errtrace
trap TrapStop SIGINT SIGQUIT
if [ " $DEBUG " = = "yes" ]
2013-06-18 11:34:14 +00:00
then
2013-07-15 22:10:23 +00:00
trap 'TrapError ${LINENO} $?' ERR
2013-06-18 11:34:14 +00:00
fi
2013-07-15 22:10:23 +00:00
2013-07-16 11:55:15 +00:00
LOG_FILE = /var/log/osync_$OSYNC_VERSION -$SYNC_ID .log
2013-07-15 22:10:23 +00:00
MAIL_ALERT_MSG = " Warning: Execution of osync instance $OSYNC_ID (pid $SCRIPT_PID ) as $LOCAL_USER @ $LOCAL_HOST produced errors. "
STATE_DIR = " $MASTER_SYNC_DIR / $OSYNC_DIR /state "
## Working directories to keep backups of updated / deleted files
MASTER_BACKUP_DIR = " $MASTER_SYNC_DIR / $OSYNC_DIR /backups "
MASTER_DELETE_DIR = " $MASTER_SYNC_DIR / $OSYNC_DIR /deleted "
SLAVE_BACKUP_DIR = " $SLAVE_SYNC_DIR / $OSYNC_DIR /backups "
SLAVE_DELETE_DIR = " $SLAVE_SYNC_DIR / $OSYNC_DIR /deleted "
2013-07-16 11:55:15 +00:00
## Runner definition
if [ " $REMOTE_SYNC " = = "yes" ]
then
RUNNER = " $( which ssh) $SSH_COMP -i $SSH_RSA_PRIVATE_KEY $REMOTE_USER @ $REMOTE_HOST -p $REMOTE_PORT "
else
RUNNER = ""
fi
2013-07-16 21:06:26 +00:00
## Dryrun option
if [ $dryrun -eq 1 ]
then
DRY_OPTION = --dry-run
DRY_WARNING = "/!\ DRY RUN"
2013-07-16 21:33:30 +00:00
else
DRY_OPTION =
fi
## Rsync options
RSYNC_OPTS = rlptgodEui
## Conflict options
if [ " $CONFLICT_BACKUP " != "no" ]
then
MASTER_CONFLICT = "--backup --backup-dir=" $MASTER_BACKUP_DIR "
SLAVE_CONFLICT = "--backup --backup-dir=" $SLAVE_BACKUP_DIR "
else
MASTER_CONFLICT =
SLAVE_CONFLICT =
fi
## Soft delete options
if [ " $SOFT_DELETE " != "no" ]
then
MASTER_DELETE = " --backup --backup-dir= $MASTER_DELETE_DIR "
SLAVE_DELETE = " --backup --backup-dir= $SLAVE_DELETE_DIR "
else
MASTER_DELETE =
SLAVE_DELETE =
2013-07-16 21:06:26 +00:00
fi
2013-06-18 11:34:14 +00:00
}
2013-07-15 22:10:23 +00:00
function Main
{
CreateDirs
Sync
}
function Usage
2013-06-18 11:34:14 +00:00
{
2013-07-15 22:10:23 +00:00
echo " Osync $OSYNC_VERSION $OSYNC_BUILD "
echo ""
echo "usage: osync /path/to/conf.file [--dry] [--silent]"
echo ""
echo "--dry: will run osync without actuallyv doing anything; just testing"
echo "--silent: will run osync without any output to stdout, usefull for cron jobs"
exit 128
}
# Comand line argument flags
dryrun = 0
silent = 0
# Alert flags
soft_alert_total = 0
error_alert = 0
2013-07-16 21:06:26 +00:00
soft_stop = 0
2013-07-15 22:10:23 +00:00
if [ $# -eq 0 ]
then
Usage
exit
fi
for i in " $@ "
do
case $i in
--dry)
dryrun = 1
; ;
--silent)
silent = 1
; ;
--help| -h)
Usage
; ;
esac
done
CheckEnvironment
if [ $? = = 0 ]
then
if [ " $1 " != "" ]
2013-06-18 11:34:14 +00:00
then
2013-07-15 22:10:23 +00:00
LoadConfigFile $1
if [ $? = = 0 ]
then
Init
DATE = $( date)
2013-07-16 11:55:15 +00:00
Log "-----------------------------------------------------------"
2013-07-16 21:06:26 +00:00
Log " $DRY_WARNING $DATE - Osync v $OSYNC_VERSION script begin. "
2013-07-16 11:55:15 +00:00
Log "-----------------------------------------------------------"
2013-07-15 22:10:23 +00:00
CheckMasterSlaveDirs
if [ $? = = 0 ]
2013-06-18 11:34:14 +00:00
then
2013-07-16 11:55:15 +00:00
RunBeforeHook
Main
SoftDelete
RunAfterHook
2013-07-15 22:10:23 +00:00
CleanUp
2013-06-18 11:34:14 +00:00
fi
2013-07-15 22:10:23 +00:00
else
LogError "Configuration file could not be loaded."
exit 1
2013-06-18 11:34:14 +00:00
fi
2013-07-15 22:10:23 +00:00
else
LogError "No configuration file provided."
exit 1
2013-06-18 11:34:14 +00:00
fi
2013-07-15 22:10:23 +00:00
else
LogError "Environment not suitable to run osync."
fi
if [ $error_alert -ne 0 ]
then
SendAlert
LogError "Osync finished with errros."
exit 1
else
Log "Osync script finished."
exit 0
fi