This commit is contained in:
Shadowigor 2016-08-28 17:50:53 +02:00
commit dba871e9bf
20 changed files with 393 additions and 473 deletions

View File

@ -6,12 +6,25 @@ KNOWN ISSUES
RECENT CHANGES
--------------
- Logs sent by mail are easier to read
- Better subject (currently running or finished run)
- Fixed bogus double log sent in alert mails
- Made unix signals posix compliant
- Config file upgrade script now updates header
! test if waitfortaskcompletion kill self works okay with osync
- Improved batch runner
- Made keep logging value configurable and not mandatory
- Fixed handling of processes in uninterruptible sleep state
! update doc on sudoers paths
- Parallelized sync functions
#TODO: explain bandwidth parameter, and CONFLICT_PREVALANCE option
- Rewrite sync resume process
! Remove conflict prevalance
- !doc about bandwidth
- Added options to ignore permissions, ownership and groups
- Refactored WaitFor... functions into one
- Improved execution speed
- Rewrite sync resume process
- Added parallel execution for most secondary fuctions
- Lowered sleep time in wait functions
- Removed trivial sleep and forking in remote deletion code, send the whole function to background instead
@ -20,7 +33,9 @@ RECENT CHANGES
- Added KillAllChilds function to accept multiple pids
- Improved logging
XX xxx 2016: osync v1.1.2 released
28 Aug 2016: osync v1.1.2 released
- Renamed sync.conf to sync.conf.example (thanks to https://github.com/hortimech)
- Fixed RunAfterHook may be executed twice
- Fixed soft deletion when SUDO_EXEC is enabled
06 Aug 2016: osync v1.1.1 released

View File

@ -1,4 +1,4 @@
Coding style used for my bash projects (v2.1 Oct 2015)
Coding style used for my bash projects (v2.3 Sep 2016)
++++++ Header
@ -8,7 +8,7 @@ Always use the following header
#!/usr/bin/env bash
PROGRAM="program-name" # Long description
AUTHOR="(C) 20XX-20YY by Orsiris \"Ozy\" de Jong"
AUTHOR="(C) 20XX-20YY by Orsiris de Jong"
CONTACT="http://www.example.com me@example.com"
PROGRAM_BUILD=YYYYMMDDVV
@ -23,8 +23,8 @@ YYYYMMDDVV (Year, Month, Day, Revision): Example: 2015012402 = 2nd revision of 2
Change old scripts with
for i in $(grep -r '#!/bin/bash' * |cut -f1 -d':'); do sed -i 's&#!/bin/bash&#!/usr/bin/env bash&g' $i; done
type instead of type -p for bash test (other shells don't know -p)
++++++ Indentation
Using tabs
@ -38,59 +38,78 @@ Some command # comment
++++++ Work comments
Whenever there is some idea to postpone, use #TODO[-version]:[dev-name:] some remark
A marker must be left where on the line a dev is working (when the work isn't finished). Marker is #WIP:dev-name: some remark
Whenever there is some idea to postpone, use #TODO(priority):[dev-name:] some remark
Priority can be critical, high, medium, low, verylow. No release can happen if there are TODOs other than low or verylow.
Example: #TODO(high):deajan: need to do something
A "work in progress" marker must be left on the line a dev is working when it's work isn't finished). Marker is #WIP:dev-name: some remark
dev-name is mandatory if more than one person is coding
Example: #TODO-v2.1:deajan: need to do something
Example: #WIP:deajan: missing function something
++++++ Variables
All local variables are lowercase, separated by _ (ex: low_wait)
All global variables full upercase, separated by _ (ex: EXEC_TIME)
All environment variables (verbose, silent, debug, etc) have prefix _ and are full upercase, separated by _ (ex: _PARANOIA_DEBUG)
All local variables names have each first letter of the words uppercase and all others lowercase, except for the first word where all letters are lowercase
Example: someLongVariable
All global variables are full upercase, separated by _
Example: EXEC_TIME
All environment variables (verbose, silent, debug, etc) have prefix _ and are full upercase, separated by _
Example: _PARANOIA_DEBUG
++++++ Functions
Every word in a function begins with an uppercase (ex: SomeFunctionDoesThings)
All function names should begin with an uppercase letter for every word, the other letters should be lowercase
Example: SomeFunctionThatRocks
Define functions this way. Use sed ':a;N;$!ba;s/\n{\n/ {\n/g' to adapt when opening bracket is on a new line.
function something {
Bash does not provide any checks against missing function arguments. Also, missing quotes can lead to an inconsistent number of arguments.
Most functions should have a first line that calls the special function __CheckArguments, which checks the number of given arguments for a function in order
to find possible problems. Number of arguments are given as first argument to __CheckArguments. May be a number or a range, eg 0-2 if the function takes optional arguments.
__CheckArguments will only trigger when the script is launched with _PARANOIA_DEBUG=yes. Also, it will only exist in the debug version.
Use the following convention for function definition:
function SomeFunction {
__CheckArguments 0 $# ${FUNCNAME[0]} "$@" #__WITH_PARANOIA_DEBUG
...
}
If function has some arguments, use local variable names that are more readable than $1...$n. Explain via comments what those variables contain if needed.
Use sed ':a;N;$!ba;s/\n{\n/ {\n/g' to convert functions that have opening brackets on a new line.
function anotherthing {
local var_name="${1}"
local other_var_name="${2}" # This variable contains stuff
If the function has arguments, use local variable names that are more readable than $1...$n. Explain via comments what those variables contain if needed.
Declare arguments before launching __CheckArguments:
function AnotherFunction {
local varName="${1}"
local otherVarName="${2}" # This variable contains stuff
__CheckArguments 2 $# ${FUNCNAME[0]} "$@" #__WITH_PARANOIA_DEBUG
...
}
Functions should always have return status
function thirdthing {
some_command
function RandomFunction {
...
return $?
}
++++++ Sub functions
When a function is a subroutine of another function, it is called _SomethingAsSubFunction
When a function is a subroutine of another function, it is called _SomethingAsSubFunction:
Example:
++++++ Function argument check
function _ApplyLocally
function _ApplyRemotely
function Apply
Bash does not provide any checks against missing function arguments. Also, missing quotes can lead to an inconsistent number of arguments.
Every function call will be checked by __CheckArguments which takes the number of arguments, $# (the real number of args given), the parent function name and the parent function's arguments.
__CheckArguments will trigger a critical error if number of arguments if incorrect. This will also prevent silent typo errors.
Ex:
++++++ For and While statements
function Something {
local some="${1}"
local other="${2}"
local args="${3}"
__CheckArguments 3 $# $FUNCNAME "$*"
For and while statements will have the "do" part on the first line.
Example:
__CheckArguments will only trigger if script is called with DEBUG=yes
Also, with PARANOIA_DEBUG=yes, __CheckArguments will recount all arguments given by "$*" and compare. This can mislead if arguments contain spaces.
for i in "${var[@]}"; do
...
done
while [ $i -eq 1 ]; do
...
done
++++++ If statements
@ -106,7 +125,7 @@ fi
A logging function is available with the following levels of logging:
- DEBUG: Only log this when DEBUG flas is set in program. Any command forged for eval should be logged by this.
- DEBUG: Only log this when DEBUG flas is set in program. Any command forged for eval instruction should be logged by this.
- NOTICE: Standard messages
- WARN: Requires attention
- ERROR: Program produced an error but continues execution
@ -128,7 +147,7 @@ cmd=$SSH_CMD' "some; commands \"'$VARIABLE'\" some; other; commands" > some_file
++++++ File variables
All eval cmd should exit their content to a file called "$RUNDIR/osync.$FUNCNAME.$SCRIPT_PID"
Dots are used instead of '_' so variables can be separated with a forbidden char in variables, so they get detected.
Dots are used instead of '_' so variables can be separated with a forbidden char in variable names, so the separtors apply as wished.
++++++ Finding code errors
@ -154,3 +173,11 @@ function FunctionName {
#__ENDFUNC
These functions are inserted into code that has placeholders like #__FUNC:FuncName
+++++++ Exit codes
Normal exit code = 0
Run with errors exit code = 1
Run with warnings exit code = 2
Wrong shell exit code = 127
Usage function exit code = 128

View File

@ -19,6 +19,9 @@ Osync provides the following capabilities
- Batch runner for multiple sync tasks with rerun option for failed sync tasks
- ACL synchronization
osync is a state synchronizer. This means that it doesn't have to monitor files for changes. Instead, it compares replica lists between runs.
A full run takes about 2 seconds on a local-local replication and about 10 seconds on a local-remote replication.
Disabling some features file like attributes preservation and disk space checks may speed up execution.
osync uses a initiator / target sync schema. It can sync local to local or local to remote directories. By definition, initiator replica is always a local directory on the system osync runs on.
osync uses pidlocks to prevent multiple concurrent sync processes on/to the same initiator / target replica.
You may launch concurrent sync processes on the same system but only for different initiator replicas.

View File

@ -1,13 +1,13 @@
#!/usr/bin/env bash
#TODO(critical): handle conflict prevalance, especially in sync_attrs function
#TODO(critical): test new WaitForTaskCompletion behavior with self=true
#TODO(critical): writelockfiles remote does not shut execution
PROGRAM="osync" # Rsync based two way sync engine with fault tolerance
AUTHOR="(C) 2013-2016 by Orsiris de Jong"
CONTACT="http://www.netpower.fr/osync - ozy@netpower.fr"
PROGRAM_VERSION=1.2-dev-parallel
PROGRAM_BUILD=2016081902
PROGRAM_BUILD=2016082201
IS_STABLE=no
# Function Name Is parallel #__WITH_PARANOIA_DEBUG
@ -47,7 +47,7 @@ IS_STABLE=no
#### MINIMAL-FUNCTION-SET BEGIN ####
## FUNC_BUILD=2016081805
## FUNC_BUILD=2016082204
## BEGIN Generic functions for osync & obackup written in 2013-2016 by Orsiris de Jong - http://www.netpower.fr - ozy@netpower.fr
## type -p does not work on platforms other than linux (bash). If if does not work, always assume output is not a zero exitcode
@ -230,7 +230,7 @@ function KillChilds {
# Try to kill nicely, if not, wait 15 seconds to let Trap actions happen before killing
if ( [ "$self" == true ] && kill -0 $pid > /dev/null 2>&1); then
Logger "Sending SIGTERM to process [$pid]." "DEBUG"
kill -s SIGTERM "$pid"
kill -s TERM "$pid"
if [ $? != 0 ]; then
sleep 15
Logger "Sending SIGTERM to process [$pid] failed." "DEBUG"
@ -646,29 +646,6 @@ function WaitForTaskCompletion {
while [ ${#pidsArray[@]} -gt 0 ]; do
newPidsArray=()
for pid in "${pidsArray[@]}"; do
if kill -0 $pid > /dev/null 2>&1; then
# Handle uninterruptible sleep state or zombies by ommiting them from running process array (How to kill that is already dead ? :)
#TODO(high): have this tested on *BSD, Mac & Win
pidState=$(ps -p$pid -o state= 2 > /dev/null)
if [ "$pidState" != "D" ] && [ "$pidState" != "Z" ]; then
newPidsArray+=($pid)
fi
else
# pid is dead, get it's exit code from wait command
wait $pid
retval=$?
if [ $retval -ne 0 ]; then
errorcount=$((errorcount+1))
Logger "${FUNCNAME[0]} called by [$caller_name] finished monitoring [$pid] with exitcode [$result]." "DEBUG"
if [ "$WAIT_FOR_TASK_COMPLETION" == "" ]; then
WAIT_FOR_TASK_COMPLETION="$pid:$result"
else
WAIT_FOR_TASK_COMPLETION=";$pid:$result"
fi
fi
fi
done
Spinner
if [ $counting == true ]; then
@ -708,6 +685,30 @@ function WaitForTaskCompletion {
fi
fi
for pid in "${pidsArray[@]}"; do
if kill -0 $pid > /dev/null 2>&1; then
# Handle uninterruptible sleep state or zombies by ommiting them from running process array (How to kill that is already dead ? :)
#TODO(high): have this tested on *BSD, Mac & Win
pidState=$(ps -p$pid -o state= 2 > /dev/null)
if [ "$pidState" != "D" ] && [ "$pidState" != "Z" ]; then
newPidsArray+=($pid)
fi
else
# pid is dead, get it's exit code from wait command
wait $pid
retval=$?
if [ $retval -ne 0 ]; then
errorcount=$((errorcount+1))
Logger "${FUNCNAME[0]} called by [$caller_name] finished monitoring [$pid] with exitcode [$result]." "DEBUG"
if [ "$WAIT_FOR_TASK_COMPLETION" == "" ]; then
WAIT_FOR_TASK_COMPLETION="$pid:$result"
else
WAIT_FOR_TASK_COMPLETION=";$pid:$result"
fi
fi
fi
done
pidsArray=("${newPidsArray[@]}")
sleep $SLEEP_TIME
done
@ -1037,7 +1038,7 @@ function CheckConnectivity3rdPartyHosts {
for i in $REMOTE_3RD_PARTY_HOSTS
do
eval "$PING_CMD $i > /dev/null 2>&1" &
WaitForTaskCompletion $! 10 360 ${FUNCNAME[0]} true $KEEP_LOGGING
WaitForTaskCompletion $! 180 360 ${FUNCNAME[0]} true $KEEP_LOGGING
if [ $? != 0 ]; then
Logger "Cannot ping 3rd party host $i" "NOTICE"
else
@ -1417,9 +1418,7 @@ function TrapQuit {
exitcode=2 # Warning exit code must not force daemon mode to quit
else
UnlockReplicas
if [ "$RUN_AFTER_CMD_ON_ERROR" == "yes" ]; then
RunAfterHook
fi
RunAfterHook
CleanUp
Logger "$PROGRAM finished." "NOTICE"
exitcode=0
@ -1541,15 +1540,16 @@ function CheckReplicaPaths {
local pids
# Use direct comparaison before having a portable realpath implementation
#INITIATOR_SYNC_DIR_CANN=$(realpath "${INITIATOR[1]}") #TODO(verylow): investigate realpath & readlink issues on MSYS and busybox here
#TARGET_SYNC_DIR_CANN=$(realpath "${TARGET[1]})
#if [ "$REMOTE_OPERATION" != "yes" ]; then
# if [ "$INITIATOR_SYNC_DIR_CANN" == "$TARGET_SYNC_DIR_CANN" ]; then
# Logger "Master directory [${INITIATOR[1]}] cannot be the same as target directory." "CRITICAL"
# exit 1
# fi
#fi
if [ "$REMOTE_OPERATION" != "yes" ]; then
if [ "${INITIATOR[1]}" == "${TARGET[1]}" ]; then
Logger "Initiator and target path [${INITIATOR[1]}] cannot be the same." "CRITICAL"
exit 1
fi
fi
_CheckReplicaPathsLocal "${INITIATOR[1]}" &
pids="$!"
@ -2887,10 +2887,10 @@ function Init {
# Do not use exit and quit traps if osync runs in monitor mode
if [ $sync_on_changes -eq 0 ]; then
trap TrapStop SIGINT SIGHUP SIGTERM SIGQUIT
trap TrapStop INT HUP TERM QUIT
trap TrapQuit EXIT
else
trap TrapQuit SIGTERM EXIT SIGHUP SIGQUIT
trap TrapQuit TERM EXIT HUP QUIT
fi
local uri

View File

@ -1,13 +1,13 @@
#!/usr/bin/env bash
#TODO(critical): handle conflict prevalance, especially in sync_attrs function
#TODO(critical): test new WaitForTaskCompletion behavior with self=true
#TODO(critical): writelockfiles remote does not shut execution
PROGRAM="osync" # Rsync based two way sync engine with fault tolerance
AUTHOR="(C) 2013-2016 by Orsiris de Jong"
CONTACT="http://www.netpower.fr/osync - ozy@netpower.fr"
PROGRAM_VERSION=1.2-dev-parallel
PROGRAM_BUILD=2016081902
PROGRAM_BUILD=2016082201
IS_STABLE=no
# Function Name Is parallel #__WITH_PARANOIA_DEBUG
@ -99,9 +99,7 @@ function TrapQuit {
exitcode=2 # Warning exit code must not force daemon mode to quit
else
UnlockReplicas
if [ "$RUN_AFTER_CMD_ON_ERROR" == "yes" ]; then
RunAfterHook
fi
RunAfterHook
CleanUp
Logger "$PROGRAM finished." "NOTICE"
exitcode=0
@ -223,15 +221,16 @@ function CheckReplicaPaths {
local pids
# Use direct comparaison before having a portable realpath implementation
#INITIATOR_SYNC_DIR_CANN=$(realpath "${INITIATOR[1]}") #TODO(verylow): investigate realpath & readlink issues on MSYS and busybox here
#TARGET_SYNC_DIR_CANN=$(realpath "${TARGET[1]})
#if [ "$REMOTE_OPERATION" != "yes" ]; then
# if [ "$INITIATOR_SYNC_DIR_CANN" == "$TARGET_SYNC_DIR_CANN" ]; then
# Logger "Master directory [${INITIATOR[1]}] cannot be the same as target directory." "CRITICAL"
# exit 1
# fi
#fi
if [ "$REMOTE_OPERATION" != "yes" ]; then
if [ "${INITIATOR[1]}" == "${TARGET[1]}" ]; then
Logger "Initiator and target path [${INITIATOR[1]}] cannot be the same." "CRITICAL"
exit 1
fi
fi
_CheckReplicaPathsLocal "${INITIATOR[1]}" &
pids="$!"
@ -1569,10 +1568,10 @@ function Init {
# Do not use exit and quit traps if osync runs in monitor mode
if [ $sync_on_changes -eq 0 ]; then
trap TrapStop SIGINT SIGHUP SIGTERM SIGQUIT
trap TrapStop INT HUP TERM QUIT
trap TrapQuit EXIT
else
trap TrapQuit SIGTERM EXIT SIGHUP SIGQUIT
trap TrapQuit TERM EXIT HUP QUIT
fi
local uri

View File

@ -1,9 +1,13 @@
#### MINIMAL-FUNCTION-SET BEGIN ####
## FUNC_BUILD=2016081806
## BEGIN Generic functions for osync & obackup written in 2013-2016 by Orsiris de Jong - http://www.netpower.fr - ozy@netpower.fr
## FUNC_BUILD=2016082801
## BEGIN Generic bash functions written in 2013-2016 by Orsiris de Jong - http://www.netpower.fr - ozy@netpower.fr
## To use in a program, define the following variables:
## PROGRAM=program-name
## INSTANCE_ID=program-instance-name
## _DEBUG=yes/no
## type -p does not work on platforms other than linux (bash). If if does not work, always assume output is not a zero exitcode
if ! type "$BASH" > /dev/null; then
echo "Please run this script only with bash shell. Tested on bash >= 3.2"
exit 127
@ -28,6 +32,9 @@ fi
ERROR_ALERT=0
WARN_ALERT=0
# Current log
CURRENT_LOG=
## allow function call checks #__WITH_PARANOIA_DEBUG
if [ "$_PARANOIA_DEBUG" == "yes" ];then #__WITH_PARANOIA_DEBUG
_DEBUG=yes #__WITH_PARANOIA_DEBUG
@ -49,6 +56,10 @@ SCRIPT_PID=$$
LOCAL_USER=$(whoami)
LOCAL_HOST=$(hostname)
if [ "$PROGRAM" == "" ]; then
PROGRAM="ofunctions"
fi
## Default log file until config file is loaded
if [ -w /var/log ]; then
LOG_FILE="/var/log/$PROGRAM.log"
@ -89,6 +100,7 @@ function _Logger {
local evalue="${3}" # What to log to stderr
echo -e "$lvalue" >> "$LOG_FILE"
CURRENT_LOG="$CURRENT_LOG"$'\n'"$lvalue"
if [ "$_LOGGER_STDERR" -eq 1 ]; then
cat <<< "$evalue" 1>&2
@ -183,7 +195,7 @@ function KillChilds {
# Try to kill nicely, if not, wait 15 seconds to let Trap actions happen before killing
if ( [ "$self" == true ] && kill -0 $pid > /dev/null 2>&1); then
Logger "Sending SIGTERM to process [$pid]." "DEBUG"
kill -s SIGTERM "$pid"
kill -s TERM "$pid"
if [ $? != 0 ]; then
sleep 15
Logger "Sending SIGTERM to process [$pid] failed." "DEBUG"
@ -220,11 +232,14 @@ function KillAllChilds {
# osync/obackup/pmocr script specific mail alert function, use SendEmail function for generic mail sending
function SendAlert {
__CheckArguments 0 $# ${FUNCNAME[0]} "$@" #__WITH_PARANOIA_DEBUG
local runAlert="${1:-false}" # Specifies if current message is sent while running or at the end of a run
__CheckArguments 0-1 $# ${FUNCNAME[0]} "$@" #__WITH_PARANOIA_DEBUG
local mail_no_attachment=
local attachment_command=
local subject=
local body=
# Windows specific settings
local encryption_string=
@ -253,7 +268,8 @@ function SendAlert {
else
mail_no_attachment=0
fi
MAIL_ALERT_MSG="$MAIL_ALERT_MSG"$'\n\n'$(tail -n 50 "$LOG_FILE")
body="$MAIL_ALERT_MSG"$'\n\n'"$CURRENT_LOG"
if [ $ERROR_ALERT -eq 1 ]; then
subject="Error alert for $INSTANCE_ID"
elif [ $WARN_ALERT -eq 1 ]; then
@ -262,11 +278,17 @@ function SendAlert {
subject="Alert for $INSTANCE_ID"
fi
if [ $runAlert == true ]; then
subject="Currently runing - $subject"
else
subject="Fnished run - $subject"
fi
if [ "$mail_no_attachment" -eq 0 ]; then
attachment_command="-a $ALERT_LOG_FILE"
fi
if type mutt > /dev/null 2>&1 ; then
echo "$MAIL_ALERT_MSG" | $(type -p mutt) -x -s "$subject" $DESTINATION_MAILS $attachment_command
echo "$body" | $(type -p mutt) -x -s "$subject" $DESTINATION_MAILS $attachment_command
if [ $? != 0 ]; then
Logger "Cannot send alert mail via $(type -p mutt) !!!" "WARN"
else
@ -283,10 +305,10 @@ function SendAlert {
else
attachment_command=""
fi
echo "$MAIL_ALERT_MSG" | $(type -p mail) $attachment_command -s "$subject" $DESTINATION_MAILS
echo "$body" | $(type -p mail) $attachment_command -s "$subject" $DESTINATION_MAILS
if [ $? != 0 ]; then
Logger "Cannot send alert mail via $(type -p mail) with attachments !!!" "WARN"
echo "$MAIL_ALERT_MSG" | $(type -p mail) -s "$subject" $DESTINATION_MAILS
echo "$body" | $(type -p mail) -s "$subject" $DESTINATION_MAILS
if [ $? != 0 ]; then
Logger "Cannot send alert mail via $(type -p mail) without attachments !!!" "WARN"
else
@ -300,7 +322,7 @@ function SendAlert {
fi
if type sendmail > /dev/null 2>&1 ; then
echo -e "Subject:$subject\r\n$MAIL_ALERT_MSG" | $(type -p sendmail) $DESTINATION_MAILS
echo -e "Subject:$subject\r\n$body" | $(type -p sendmail) $DESTINATION_MAILS
if [ $? != 0 ]; then
Logger "Cannot send alert mail via $(type -p sendmail) !!!" "WARN"
else
@ -323,7 +345,7 @@ function SendAlert {
if [ "$SMTP_USER" != "" ] && [ "$SMTP_USER" != "" ]; then
auth_string="-auth -user \"$SMTP_USER\" -pass \"$SMTP_PASSWORD\""
fi
$(type mailsend.exe) -f $SENDER_MAIL -t "$DESTINATION_MAILS" -sub "$subject" -M "$MAIL_ALERT_MSG" -attach "$attachment" -smtp "$SMTP_SERVER" -port "$SMTP_PORT" $encryption_string $auth_string
$(type mailsend.exe) -f $SENDER_MAIL -t "$DESTINATION_MAILS" -sub "$subject" -M "$body" -attach "$attachment" -smtp "$SMTP_SERVER" -port "$SMTP_PORT" $encryption_string $auth_string
if [ $? != 0 ]; then
Logger "Cannot send mail via $(type mailsend.exe) !!!" "WARN"
else
@ -339,7 +361,7 @@ function SendAlert {
else
SMTP_OPTIONS=""
fi
$(type -p sendemail) -f $SENDER_MAIL -t "$DESTINATION_MAILS" -u "$subject" -m "$MAIL_ALERT_MSG" -s $SMTP_SERVER $SMTP_OPTIONS > /dev/null 2>&1
$(type -p sendemail) -f $SENDER_MAIL -t "$DESTINATION_MAILS" -u "$subject" -m "$body" -s $SMTP_SERVER $SMTP_OPTIONS > /dev/null 2>&1
if [ $? != 0 ]; then
Logger "Cannot send alert mail via $(type -p sendemail) !!!" "WARN"
else
@ -350,7 +372,7 @@ function SendAlert {
# pfSense specific
if [ -f /usr/local/bin/mail.php ]; then
echo "$MAIL_ALERT_MSG" | /usr/local/bin/mail.php -s="$subject"
echo "$body" | /usr/local/bin/mail.php -s="$subject"
if [ $? != 0 ]; then
Logger "Cannot send alert mail via /usr/local/bin/mail.php (pfsense) !!!" "WARN"
else
@ -569,6 +591,8 @@ function joinString {
# Time control function for background processes, suitable for multiple synchronous processes
# Fills a global variable called WAIT_FOR_TASK_COMPLETION that contains list of failed pids in format pid1:result1;pid2:result2
# Warning: Don't imbricate this function into another run if you plan to use the global variable output
#TODO check missing local values used here
function WaitForTaskCompletion {
local pids="${1}" # pids to wait for, separated by semi-colon
local soft_max_time="${2}" # If program with pid $pid takes longer than $soft_max_time seconds, will log a warning, unless $soft_max_time equals 0.
@ -599,29 +623,6 @@ function WaitForTaskCompletion {
while [ ${#pidsArray[@]} -gt 0 ]; do
newPidsArray=()
for pid in "${pidsArray[@]}"; do
if kill -0 $pid > /dev/null 2>&1; then
# Handle uninterruptible sleep state or zombies by ommiting them from running process array (How to kill that is already dead ? :)
#TODO(high): have this tested on *BSD, Mac & Win
pidState=$(ps -p$pid -o state= 2 > /dev/null)
if [ "$pidState" != "D" ] && [ "$pidState" != "Z" ]; then
newPidsArray+=($pid)
fi
else
# pid is dead, get it's exit code from wait command
wait $pid
retval=$?
if [ $retval -ne 0 ]; then
errorcount=$((errorcount+1))
Logger "${FUNCNAME[0]} called by [$caller_name] finished monitoring [$pid] with exitcode [$result]." "DEBUG"
if [ "$WAIT_FOR_TASK_COMPLETION" == "" ]; then
WAIT_FOR_TASK_COMPLETION="$pid:$result"
else
WAIT_FOR_TASK_COMPLETION=";$pid:$result"
fi
fi
fi
done
Spinner
if [ $counting == true ]; then
@ -643,7 +644,7 @@ function WaitForTaskCompletion {
if [ $soft_alert -eq 0 ] && [ $soft_max_time -ne 0 ]; then
Logger "Max soft execution time exceeded for task [$caller_name] with pids [$(joinString , ${pidsArray[@]})]." "WARN"
soft_alert=1
SendAlert
SendAlert true
fi
if [ $exec_time -gt $hard_max_time ] && [ $hard_max_time -ne 0 ]; then
@ -656,12 +657,37 @@ function WaitForTaskCompletion {
Logger "Could not stop task with pid [$pid]." "ERROR"
fi
done
SendAlert
SendAlert true
errrorcount=$((errorcount+1))
fi
fi
for pid in "${pidsArray[@]}"; do
if kill -0 $pid > /dev/null 2>&1; then
# Handle uninterruptible sleep state or zombies by ommiting them from running process array (How to kill that is already dead ? :)
#TODO(high): have this tested on *BSD, Mac & Win
pidState=$(ps -p$pid -o state= 2 > /dev/null)
if [ "$pidState" != "D" ] && [ "$pidState" != "Z" ]; then
newPidsArray+=($pid)
fi
else
# pid is dead, get it's exit code from wait command
wait $pid
retval=$?
if [ $retval -ne 0 ]; then
errorcount=$((errorcount+1))
Logger "${FUNCNAME[0]} called by [$caller_name] finished monitoring [$pid] with exitcode [$retval]." "DEBUG"
if [ "$WAIT_FOR_TASK_COMPLETION" == "" ]; then
WAIT_FOR_TASK_COMPLETION="$pid:$retval"
else
WAIT_FOR_TASK_COMPLETION=";$pid:$retval"
fi
fi
fi
done
pidsArray=("${newPidsArray[@]}")
# Trivial wait time for bash to not eat up all CPU
sleep $SLEEP_TIME
done
@ -675,6 +701,66 @@ function WaitForTaskCompletion {
fi
}
# Take a list of commands to run, runs them sequentially with numberOfProcesses commands simultaneously runs
# Returns the number of non zero exit codes from commands
function ParallelExec {
local numberOfProcesses="${1}" # Number of simultaneous commands to run
local commandsArg="${2}" # Semi-colon separated list of commands
local pid
local runningPids=0
local counter=0
local commandsArray
local pidsArray
local newPidsArray
local retval
local retvalAll=0
local pidState
local commandsArrayPid
IFS=';' read -r -a commandsArray <<< "$commandsArg"
Logger "Runnning ${#commandsArray[@]} commands in $numberOfProcesses simultaneous processes." "DEBUG"
while [ $counter -lt "${#commandsArray[@]}" ] || [ ${#pidsArray[@]} -gt 0 ]; do
while [ $counter -lt "${#commandsArray[@]}" ] && [ ${#pidsArray[@]} -lt $numberOfProcesses ]; do
Logger "Running command [${commandsArray[$counter]}]." "DEBUG"
eval "${commandsArray[$counter]}" &
pid=$!
pidsArray+=($pid)
commandsArrayPid[$pid]="${commandsArray[$counter]}"
counter=$((counter+1))
done
newPidsArray=()
for pid in "${pidsArray[@]}"; do
# Handle uninterruptible sleep state or zombies by ommiting them from running process array (How to kill that is already dead ? :)
if kill -0 $pid > /dev/null 2>&1; then
pidState=$(ps -p$pid -o state= 2 > /dev/null)
if [ "$pidState" != "D" ] && [ "$pidState" != "Z" ]; then
newPidsArray+=($pid)
fi
else
# pid is dead, get it's exit code from wait command
wait $pid
retval=$?
if [ $retval -ne 0 ]; then
Logger "Command [${commandsArrayPid[$pid]}] failed with exit code [$retval]." "ERROR"
retvalAll=$((retvalAll+1))
fi
fi
done
pidsArray=("${newPidsArray[@]}")
# Trivial wait time for bash to not eat up all CPU
sleep $SLEEP_TIME
done
return $retvalAll
}
function CleanUp {
__CheckArguments 0 $# ${FUNCNAME[0]} "$@" #__WITH_PARANOIA_DEBUG
@ -968,7 +1054,7 @@ function CheckConnectivityRemoteHost {
if [ "$REMOTE_HOST_PING" != "no" ] && [ "$REMOTE_OPERATION" != "no" ]; then
eval "$PING_CMD $REMOTE_HOST > /dev/null 2>&1" &
WaitForTaskCompletion $! 10 180 ${FUNCNAME[0]} true $KEEP_LOGGING
WaitForTaskCompletion $! 60 180 ${FUNCNAME[0]} true $KEEP_LOGGING
if [ $? != 0 ]; then
Logger "Cannot ping $REMOTE_HOST" "ERROR"
return 1
@ -1013,12 +1099,15 @@ function __CheckArguments {
# Checks the number of arguments of a function and raises an error if some are missing
if [ "$_DEBUG" == "yes" ]; then
local number_of_arguments="${1}" # Number of arguments the tested function should have
local number_of_given_arguments="${2}" # Number of arguments that have been passed
local function_name="${3}" # Function name that called __CheckArguments
local numberOfArguments="${1}" # Number of arguments the tested function should have, can be a number of a range, eg 0-2 for zero to two arguments
local numberOfGivenArguments="${2}" # Number of arguments that have been passed
local functionName="${3}" # Function name that called __CheckArguments
local minArgs
local maxArgs
if [ "$_PARANOIA_DEBUG" == "yes" ]; then
Logger "Entering function [$function_name]." "DEBUG"
Logger "Entering function [$functionName]." "DEBUG"
fi
# All arguments of the function to check are passed as array in ${4} (the function call waits for $@)
@ -1026,23 +1115,31 @@ function __CheckArguments {
# In order to avoid this, we need to iterate over ${4} and count
local iterate=4
local fetch_arguments=1
local arg_list=""
while [ $fetch_arguments -eq 1 ]; do
local fetchArguments=1
local argList=""
local countedArguments
while [ $fetchArguments -eq 1 ]; do
cmd='argument=${'$iterate'}'
eval $cmd
if [ "$argument" = "" ]; then
fetch_arguments=0
fetchArguments=0
else
arg_list="$arg_list [Argument $(($iterate-3)): $argument]"
argList="$arg_list [Argument $(($iterate-3)): $argument]"
iterate=$(($iterate+1))
fi
done
local counted_arguments=$((iterate-4))
countedArguments=$((iterate-4))
if [ $counted_arguments -ne $number_of_arguments ]; then
Logger "Function $function_name may have inconsistent number of arguments. Expected: $number_of_arguments, count: $counted_arguments, bash seen: $number_of_given_arguments. see log file." "ERROR"
Logger "Arguments passed: $arg_list" "ERROR"
if [ $(IsNumeric "$numberOfArguments") -eq 1 ]; then
minArgs=$numberOfArguments
maxArgs=$numberOfArguments
else
IFS='-' read minArgs maxArgs <<< "$numberOfArguments"
fi
if ! ([ $countedArguments -ge $minArgs ] && [ $countedArguments -le $maxArgs ]); then
Logger "Function $functionName may have inconsistent number of arguments. Expected min: $minArgs, max: $maxArgs, count: $countedArguments, bash seen: $numberOfGivenArguments. see log file." "ERROR"
Logger "Arguments passed: $argList" "ERROR"
fi
fi
}
@ -1286,7 +1383,6 @@ function InitLocalOSSettings {
function InitRemoteOSSettings {
__CheckArguments 0 $# ${FUNCNAME[0]} "$@" #__WITH_PARANOIA_DEBUG
#TODO: fix add -E when both initiator and targets don't run MacOSX and PRESERVE_EXECUTABILITY=yes
## MacOSX does not use the -E parameter like Linux or BSD does (-E is mapped to extended attrs instead of preserve executability)
if [ "$PRESERVE_EXECUTABILITY" != "no" ];then
if [ "$LOCAL_OS" != "MacOSX" ] && [ "$REMOTE_OS" != "MacOSX" ]; then

View File

@ -1,9 +1,18 @@
#!/usr/bin/env bash
# osync shunit2 tests
# modify ctime on ext4
debugfs -w -R 'set_inode_field /tmp/foo ctime 201001010101' /dev/sda1
echo > /proc/sys/vm/drop_caches
# Test dir
TMP="/tmp/osync_tests"
# SSH port used for remote tests
SSH_PORT=49999
SSH_PORT=22
INITIATOR_DIR="init"
TARGET_DIR="targ"
# Get dir the tests are stored in
TEST_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
@ -11,8 +20,8 @@ cd "$TEST_DIR"
OSYNC_EXECUTABLE="$(dirname $TEST_DIR)//osync.sh"
declare -A sandbox_osync
#sandbox_osync[quickLocal]="--master=master --slave=slave"
#sandbox_osync[quickRemote]="--master=master --slave=ssh://localhost//tmp/osync_tests/quickRemote/slave"
sandbox_osync[quickLocal]="--initiator=$INITIATOR_DIR --target=$TARGET_DIR"
#sandbox_osync[quickRemote]="--initiator=$INITIATOR_DIR --slave=ssh://localhost:$SSH_PORT/$TMP/$TARGET_DIR"
#sandbox_osync[local]="conf/local.conf"
#sandbox_osync[remote]="conf/remote.conf"
@ -34,8 +43,8 @@ prepareSandbox()
rm -rf "$TMP/$1"
mkdir -p "$TMP/$1"
pushd "$TMP/$1" >/dev/null
mkdir master
mkdir slave
mkdir "$INITIATOR_DIR"
mkdir "$TARGET_DIR"
mkdir expected
popd >/dev/null
}

54
dev/tests/run_tests.sh Executable file
View File

@ -0,0 +1,54 @@
#!/usr/bin/env bash
# osync test suite 2016081901
DEV_DIR="/home/git/osync/dev"
OSYNC_EXECUTABLE="n_osync.sh"
INITIATOR_DIR="/opt/osync/initiator"
TARGET_DIR="/opt/osync/target"
OSYNC_STATE_DIR=".osync_workdir/state"
function CreateReplicas () {
if [ -d "$INITIATOR_DIR" ]; then
rm -rf "$INITIATOR_DIR"
fi
mkdir -p "$INITIATOR_DIR"
if [ -d "$TARGET_DIR" ]; then
rm -rf "$TARGET_DIR"
fi
mkdir -p "$TARGET_DIR"
}
function oneTimeSetUp () {
source "$DEV_DIR/ofunctions.sh"
if grep "^IS_STABLE=YES" "$DEV_DIR/$OSYNC_EXECUTABLE" > /dev/null; then
IS_STABLE=yes
else
IS_STABLE=no
sed -i 's/^IS_STABLE=no/IS_STABLE=yes/' "$DEV_DIR/$OSYNC_EXECUTABLE"
fi
}
function oneTimeTearDown () {
if [ "$IS_STABLE" == "no" ]; then
sed -i 's/^IS_STABLE=yes/IS_STABLE=no/' "$DEV_DIR/$OSYNC_EXECUTABLE"
fi
}
function test_osync_quicksync_local () {
CreateReplicas
cd "$DEV_DIR"
./n_osync.sh --initiator="$INITIATOR_DIR" --target="$TARGET_DIR" > /dev/null
assertEquals "Return code" "0" $?
[ -d "$INITIATOR_DIR/$OSYNC_STATE_DIR" ]
assertEquals "Initiator state dir exists" "0" $?
[ -d "$TARGET_DIR/$OSYNC_STATE_DIR" ]
assertEquals "Target state dir exists" "0" $?
}
. ./shunit2/shunit2

View File

@ -1,20 +1,20 @@
#!/usr/bin/env bash
#TODO(critical): handle conflict prevalance, especially in sync_attrs function
#TODO(critical): test new WaitForTaskCompletion behavior with self=true
#TODO(critical): writelockfiles remote does not shut execution
PROGRAM="osync" # Rsync based two way sync engine with fault tolerance
AUTHOR="(C) 2013-2016 by Orsiris de Jong"
CONTACT="http://www.netpower.fr/osync - ozy@netpower.fr"
PROGRAM_VERSION=1.2-dev-parallel
PROGRAM_BUILD=2016081902
PROGRAM_BUILD=2016082201
IS_STABLE=no
#### MINIMAL-FUNCTION-SET BEGIN ####
## FUNC_BUILD=2016081805
## FUNC_BUILD=2016082204
## BEGIN Generic functions for osync & obackup written in 2013-2016 by Orsiris de Jong - http://www.netpower.fr - ozy@netpower.fr
## type -p does not work on platforms other than linux (bash). If if does not work, always assume output is not a zero exitcode
@ -184,7 +184,7 @@ function KillChilds {
# Try to kill nicely, if not, wait 15 seconds to let Trap actions happen before killing
if ( [ "$self" == true ] && kill -0 $pid > /dev/null 2>&1); then
Logger "Sending SIGTERM to process [$pid]." "DEBUG"
kill -s SIGTERM "$pid"
kill -s TERM "$pid"
if [ $? != 0 ]; then
sleep 15
Logger "Sending SIGTERM to process [$pid] failed." "DEBUG"
@ -594,29 +594,6 @@ function WaitForTaskCompletion {
while [ ${#pidsArray[@]} -gt 0 ]; do
newPidsArray=()
for pid in "${pidsArray[@]}"; do
if kill -0 $pid > /dev/null 2>&1; then
# Handle uninterruptible sleep state or zombies by ommiting them from running process array (How to kill that is already dead ? :)
#TODO(high): have this tested on *BSD, Mac & Win
pidState=$(ps -p$pid -o state= 2 > /dev/null)
if [ "$pidState" != "D" ] && [ "$pidState" != "Z" ]; then
newPidsArray+=($pid)
fi
else
# pid is dead, get it's exit code from wait command
wait $pid
retval=$?
if [ $retval -ne 0 ]; then
errorcount=$((errorcount+1))
Logger "${FUNCNAME[0]} called by [$caller_name] finished monitoring [$pid] with exitcode [$result]." "DEBUG"
if [ "$WAIT_FOR_TASK_COMPLETION" == "" ]; then
WAIT_FOR_TASK_COMPLETION="$pid:$result"
else
WAIT_FOR_TASK_COMPLETION=";$pid:$result"
fi
fi
fi
done
Spinner
if [ $counting == true ]; then
@ -656,6 +633,30 @@ function WaitForTaskCompletion {
fi
fi
for pid in "${pidsArray[@]}"; do
if kill -0 $pid > /dev/null 2>&1; then
# Handle uninterruptible sleep state or zombies by ommiting them from running process array (How to kill that is already dead ? :)
#TODO(high): have this tested on *BSD, Mac & Win
pidState=$(ps -p$pid -o state= 2 > /dev/null)
if [ "$pidState" != "D" ] && [ "$pidState" != "Z" ]; then
newPidsArray+=($pid)
fi
else
# pid is dead, get it's exit code from wait command
wait $pid
retval=$?
if [ $retval -ne 0 ]; then
errorcount=$((errorcount+1))
Logger "${FUNCNAME[0]} called by [$caller_name] finished monitoring [$pid] with exitcode [$result]." "DEBUG"
if [ "$WAIT_FOR_TASK_COMPLETION" == "" ]; then
WAIT_FOR_TASK_COMPLETION="$pid:$result"
else
WAIT_FOR_TASK_COMPLETION=";$pid:$result"
fi
fi
fi
done
pidsArray=("${newPidsArray[@]}")
sleep $SLEEP_TIME
done
@ -975,7 +976,7 @@ function CheckConnectivity3rdPartyHosts {
for i in $REMOTE_3RD_PARTY_HOSTS
do
eval "$PING_CMD $i > /dev/null 2>&1" &
WaitForTaskCompletion $! 10 360 ${FUNCNAME[0]} true $KEEP_LOGGING
WaitForTaskCompletion $! 180 360 ${FUNCNAME[0]} true $KEEP_LOGGING
if [ $? != 0 ]; then
Logger "Cannot ping 3rd party host $i" "NOTICE"
else
@ -1310,9 +1311,7 @@ function TrapQuit {
exitcode=2 # Warning exit code must not force daemon mode to quit
else
UnlockReplicas
if [ "$RUN_AFTER_CMD_ON_ERROR" == "yes" ]; then
RunAfterHook
fi
RunAfterHook
CleanUp
Logger "$PROGRAM finished." "NOTICE"
exitcode=0
@ -1429,15 +1428,16 @@ function CheckReplicaPaths {
local pids
# Use direct comparaison before having a portable realpath implementation
#INITIATOR_SYNC_DIR_CANN=$(realpath "${INITIATOR[1]}") #TODO(verylow): investigate realpath & readlink issues on MSYS and busybox here
#TARGET_SYNC_DIR_CANN=$(realpath "${TARGET[1]})
#if [ "$REMOTE_OPERATION" != "yes" ]; then
# if [ "$INITIATOR_SYNC_DIR_CANN" == "$TARGET_SYNC_DIR_CANN" ]; then
# Logger "Master directory [${INITIATOR[1]}] cannot be the same as target directory." "CRITICAL"
# exit 1
# fi
#fi
if [ "$REMOTE_OPERATION" != "yes" ]; then
if [ "${INITIATOR[1]}" == "${TARGET[1]}" ]; then
Logger "Initiator and target path [${INITIATOR[1]}] cannot be the same." "CRITICAL"
exit 1
fi
fi
_CheckReplicaPathsLocal "${INITIATOR[1]}" &
pids="$!"
@ -2746,10 +2746,10 @@ function Init {
# Do not use exit and quit traps if osync runs in monitor mode
if [ $sync_on_changes -eq 0 ]; then
trap TrapStop SIGINT SIGHUP SIGTERM SIGQUIT
trap TrapStop INT HUP TERM QUIT
trap TrapQuit EXIT
else
trap TrapQuit SIGTERM EXIT SIGHUP SIGQUIT
trap TrapQuit TERM EXIT HUP QUIT
fi
local uri

View File

@ -2,7 +2,7 @@
###### osync - Rsync based two way sync engine with fault tolerance
###### (C) 2013-2016 by Orsiris de Jong (www.netpower.fr)
###### osync v1.1x / v1.2x config file rev 2016080902
###### osync v1.1x / v1.2x config file rev 2016081901
## ---------- GENERAL OPTIONS
@ -80,7 +80,7 @@ REMOTE_3RD_PARTY_HOSTS="www.kernel.org www.google.com"
PRESERVE_PERMISSIONS=yes
PRESERVE_OWNER=yes
PRESERVE_GROUP=yes
## Does not work and will be ignored on MacOS X
## On MACOS X, does not work and will be ignored
PRESERVE_EXECUTABILITY=yes
## Preserve ACLS. Make sure source and target FS can manage same ACLs or you'll get loads of errors.
@ -104,6 +104,9 @@ RSYNC_COMPRESS=yes
SOFT_MAX_EXEC_TIME=7200
HARD_MAX_EXEC_TIME=10600
## Log a message every KEEP_LOGGING seconds just to know the task is still alive
KEEP_LOGGING=1801
## Minimum time (in seconds) in file monitor /daemon mode between modification detection and sync task in order to let copy operations finish.
MIN_WAIT=60

View File

@ -1,143 +0,0 @@
#!/usr/bin/env bash
###### Osync - Rsync based two way sync engine with fault tolerance
###### (L) 2013-2014 by Orsiris "Ozy" de Jong (www.netpower.fr)
###### Config file rev 2611201401
## ---------- GENERAL OPTIONS
## Sync job identification
SYNC_ID="sync_test"
## Directories to synchronize. Master must be on the system Osync runs on. Slave can be either a local directory, or a remote one.
MASTER_SYNC_DIR="master"
SLAVE_SYNC_DIR="slave"
#SLAVE_SYNC_DIR="ssh://backupuser@yourhost.old:22//home/git/osync/dir2"
## If slave replica is a remote directory, you must specify a RSA key (please use full path). Please see documentation for further information.
#SSH_RSA_PRIVATE_KEY="/home/backupuser/.ssh/id_rsa"
## Create sync directories if they do not exist
CREATE_DIRS=no
## Log file location. Leaving this empty will create a logfile at /var/log/osync_version_SYNC_ID.log (or current directory if /var/log doesn't exist)
LOGFILE=""
## List of directories to exclude from sync on both sides (rsync patterns, wildcards work).
## Paths are relative to sync dirs. List elements are separated by a semicolon.
RSYNC_EXCLUDE_PATTERN=""
#RSYNC_EXCLUDE_PATTERN="tmp;archives"
## File that contains the list of directories or files to exclude from sync on both sides. Leave this empty if you don't want to use an exclusion file.
## This file has to be in the same directory as the config file
## Paths are relative to sync dirs. One element per line.
RSYNC_EXCLUDE_FROM=""
#RSYNC_EXCLUDE_FROM="exclude.list"
## List elements separator char. You may set an alternative separator char for your directories lists above.
PATH_SEPARATOR_CHAR=";"
## Generate an alert if master or slave replicas have less free space than given value in KB.
MINIMUM_SPACE=10240
## Bandwidth limit Kbytes / second. Leave 0 to disable limitation
BANDWIDTH=0
## If enabled, synchronization on remote system will be processed as superuser. See documentation for /etc/sudoers file configuration.
SUDO_EXEC=no
## Paranoia option. Don't change this unless you read the documentation.
RSYNC_EXECUTABLE=rsync
## ---------- REMOTE SYNC OPTIONS
## ssh compression should be used unless your remote connection is good enough (LAN)
SSH_COMPRESSION=yes
## Check for connectivity to remote host before launching remote sync task. Be sure the hosts responds to ping. Failing to ping will stop sync.
REMOTE_HOST_PING=no
## Check for internet access by pinging one or more 3rd party hosts before remote sync task. Leave empty if you don't want this check to be be performed. Failing to ping will stop sync.
## If you use this function, you should set more than one 3rd party host, and be sure you can ping them.
## Be aware some DNS like opendns redirect false hostnames. Also, this adds an extra execution time of a bit less than a minute.
REMOTE_3RD_PARTY_HOSTS=""
## Remote rsync executable path. Leave this empty in most cases
RSYNC_REMOTE_PATH=""
## ---------- MISC OPTIONS
## Preserve ACLS. Make sure source and target FS can manage same ACLs or you'll get loads of errors.
PRESERVE_ACL=no
## Preserve Xattr. Make sure source and target FS can manage same Xattrs or you'll get loads of errors.
PRESERVE_XATTR=no
## Transforms symlinks into referent files/dirs
COPY_SYMLINKS=no
## Treat symlinked dirs as dirs. CAUTION: This also follows symlinks outside of the replica root.
KEEP_DIRLINKS=no
## Preserve hard links. Make sure source and target FS can manage hard links or you will lose them.
PRESERVE_HARDLINKS=no
## Let RSYNC compress file transfers. Do not use this if both master and slave replicas are on local system. Also, do not use this if you already enabled SSH compression.
RSYNC_COMPRESS=yes
## Maximum execution time (in seconds) for sync process. Soft exec time only generates a warning. Hard exec time will generate a warning and stop sync process.
SOFT_MAX_EXEC_TIME=7200
HARD_MAX_EXEC_TIME=10600
## Minimum time (in seconds) in file monitor /daemon mode between modification detection and sync task in order to let copy operations finish.
MIN_WAIT=60
## ---------- BACKUP AND DELETION OPTIONS
## Enabling this option will keep a backup of a file on the target replica if it gets updated from the source replica. Backups will be made to .osync_workdir/backups
CONFLICT_BACKUP=yes
## Keep multiple backup versions of the same file. Warning, This can be very space consuming.
CONFLICT_BACKUP_MULTIPLE=no
## Osync will clean backup files after a given number of days. Setting this to 0 will disable cleaning and keep backups forever. Warning: This can be very space consuming.
CONFLICT_BACKUP_DAYS=30
## If the same file exists on both replicas, newer version will be synced. However, if both files have the same timestamp but differ, CONFILCT_PREVALANCE sets winner replica.
CONFLICT_PREVALANCE=master
## On deletion propagation to the target replica, a backup of the deleted files can be kept. Deletions will be kept in .osync_workdir/deleted
SOFT_DELETE=yes
## Osync will clean deleted files after a given number of days. Setting this to 0 will disable cleaning and keep deleted files forever. Warning: This can be very space consuming.
SOFT_DELETE_DAYS=30
## ---------- RESUME OPTIONS
## Try to resume an aborted sync task
RESUME_SYNC=yes
## Number maximum resume tries before initiating a fresh sync.
RESUME_TRY=2
## When a pidlock exists on slave replica that does not correspond to master's sync-id, force pidlock removal. Be careful with this option if you have multiple masters.
FORCE_STRANGER_LOCK_RESUME=no
## Keep partial uploads that can be resumed on next run, experimental feature
PARTIAL=no
## ---------- ALERT OPTIONS
## List of alert mails separated by spaces
DESTINATION_MAILS="your@alert.tld"
## Windows (MSYS environment) only mail options (used with sendemail.exe from Brandon Zehm)
SENDER_MAIL="alert@your.system.tld"
SMTP_SERVER=smtp.your.isp.tld
SMTP_USER=
SMTP_PASSWORD=
## ---------- EXECUTION HOOKS
## Commands can will be run before and / or after sync process (remote execution will only happen if REMOTE_SYNC is set).
LOCAL_RUN_BEFORE_CMD=""
LOCAL_RUN_AFTER_CMD=""
REMOTE_RUN_BEFORE_CMD=""
REMOTE_RUN_AFTER_CMD=""
## Max execution time of commands before they get force killed. Leave 0 if you don't wan't this to happen. Time is specified in seconds.
MAX_EXEC_TIME_PER_CMD_BEFORE=0
MAX_EXEC_TIME_PER_CMD_AFTER=0
## Stops Osync execution if one of the above commands fail
STOP_ON_CMD_ERROR=yes

View File

@ -1,143 +0,0 @@
#!/usr/bin/env bash
###### Osync - Rsync based two way sync engine with fault tolerance
###### (L) 2013-2014 by Orsiris "Ozy" de Jong (www.netpower.fr)
###### Config file rev 2611201401
## ---------- GENERAL OPTIONS
## Sync job identification
SYNC_ID="sync_test"
## Directories to synchronize. Master must be on the system Osync runs on. Slave can be either a local directory, or a remote one.
MASTER_SYNC_DIR="master"
SLAVE_SYNC_DIR="ssh://localhost//tmp/osync_tests/remote/slave"
#SLAVE_SYNC_DIR="ssh://backupuser@yourhost.old:22//home/git/osync/dir2"
## If slave replica is a remote directory, you must specify a RSA key (please use full path). Please see documentation for further information.
#SSH_RSA_PRIVATE_KEY="/home/backupuser/.ssh/id_rsa"
## Create sync directories if they do not exist
CREATE_DIRS=yes
## Log file location. Leaving this empty will create a logfile at /var/log/osync_version_SYNC_ID.log (or current directory if /var/log doesn't exist)
LOGFILE=""
## List of directories to exclude from sync on both sides (rsync patterns, wildcards work).
## Paths are relative to sync dirs. List elements are separated by a semicolon.
RSYNC_EXCLUDE_PATTERN=""
#RSYNC_EXCLUDE_PATTERN="tmp;archives"
## File that contains the list of directories or files to exclude from sync on both sides. Leave this empty if you don't want to use an exclusion file.
## This file has to be in the same directory as the config file
## Paths are relative to sync dirs. One element per line.
RSYNC_EXCLUDE_FROM=""
#RSYNC_EXCLUDE_FROM="exclude.list"
## List elements separator char. You may set an alternative separator char for your directories lists above.
PATH_SEPARATOR_CHAR=";"
## Generate an alert if master or slave replicas have less free space than given value in KB.
MINIMUM_SPACE=10240
## Bandwidth limit Kbytes / second. Leave 0 to disable limitation
BANDWIDTH=0
## If enabled, synchronization on remote system will be processed as superuser. See documentation for /etc/sudoers file configuration.
SUDO_EXEC=no
## Paranoia option. Don't change this unless you read the documentation.
RSYNC_EXECUTABLE=rsync
## ---------- REMOTE SYNC OPTIONS
## ssh compression should be used unless your remote connection is good enough (LAN)
SSH_COMPRESSION=yes
## Check for connectivity to remote host before launching remote sync task. Be sure the hosts responds to ping. Failing to ping will stop sync.
REMOTE_HOST_PING=no
## Check for internet access by pinging one or more 3rd party hosts before remote sync task. Leave empty if you don't want this check to be be performed. Failing to ping will stop sync.
## If you use this function, you should set more than one 3rd party host, and be sure you can ping them.
## Be aware some DNS like opendns redirect false hostnames. Also, this adds an extra execution time of a bit less than a minute.
REMOTE_3RD_PARTY_HOSTS=""
## Remote rsync executable path. Leave this empty in most cases
RSYNC_REMOTE_PATH=""
## ---------- MISC OPTIONS
## Preserve ACLS. Make sure source and target FS can manage same ACLs or you'll get loads of errors.
PRESERVE_ACL=no
## Preserve Xattr. Make sure source and target FS can manage same Xattrs or you'll get loads of errors.
PRESERVE_XATTR=no
## Transforms symlinks into referent files/dirs
COPY_SYMLINKS=no
## Treat symlinked dirs as dirs. CAUTION: This also follows symlinks outside of the replica root.
KEEP_DIRLINKS=no
## Preserve hard links. Make sure source and target FS can manage hard links or you will lose them.
PRESERVE_HARDLINKS=no
## Let RSYNC compress file transfers. Do not use this if both master and slave replicas are on local system. Also, do not use this if you already enabled SSH compression.
RSYNC_COMPRESS=yes
## Maximum execution time (in seconds) for sync process. Soft exec time only generates a warning. Hard exec time will generate a warning and stop sync process.
SOFT_MAX_EXEC_TIME=7200
HARD_MAX_EXEC_TIME=10600
## Minimum time (in seconds) in file monitor /daemon mode between modification detection and sync task in order to let copy operations finish.
MIN_WAIT=60
## ---------- BACKUP AND DELETION OPTIONS
## Enabling this option will keep a backup of a file on the target replica if it gets updated from the source replica. Backups will be made to .osync_workdir/backups
CONFLICT_BACKUP=yes
## Keep multiple backup versions of the same file. Warning, This can be very space consuming.
CONFLICT_BACKUP_MULTIPLE=no
## Osync will clean backup files after a given number of days. Setting this to 0 will disable cleaning and keep backups forever. Warning: This can be very space consuming.
CONFLICT_BACKUP_DAYS=30
## If the same file exists on both replicas, newer version will be synced. However, if both files have the same timestamp but differ, CONFILCT_PREVALANCE sets winner replica.
CONFLICT_PREVALANCE=master
## On deletion propagation to the target replica, a backup of the deleted files can be kept. Deletions will be kept in .osync_workdir/deleted
SOFT_DELETE=yes
## Osync will clean deleted files after a given number of days. Setting this to 0 will disable cleaning and keep deleted files forever. Warning: This can be very space consuming.
SOFT_DELETE_DAYS=30
## ---------- RESUME OPTIONS
## Try to resume an aborted sync task
RESUME_SYNC=yes
## Number maximum resume tries before initiating a fresh sync.
RESUME_TRY=2
## When a pidlock exists on slave replica that does not correspond to master's sync-id, force pidlock removal. Be careful with this option if you have multiple masters.
FORCE_STRANGER_LOCK_RESUME=no
## Keep partial uploads that can be resumed on next run, experimental feature
PARTIAL=no
## ---------- ALERT OPTIONS
## List of alert mails separated by spaces
DESTINATION_MAILS="your@alert.tld"
## Windows (MSYS environment) only mail options (used with sendemail.exe from Brandon Zehm)
SENDER_MAIL="alert@your.system.tld"
SMTP_SERVER=smtp.your.isp.tld
SMTP_USER=
SMTP_PASSWORD=
## ---------- EXECUTION HOOKS
## Commands can will be run before and / or after sync process (remote execution will only happen if REMOTE_SYNC is set).
LOCAL_RUN_BEFORE_CMD=""
LOCAL_RUN_AFTER_CMD=""
REMOTE_RUN_BEFORE_CMD=""
REMOTE_RUN_AFTER_CMD=""
## Max execution time of commands before they get force killed. Leave 0 if you don't wan't this to happen. Time is specified in seconds.
MAX_EXEC_TIME_PER_CMD_BEFORE=0
MAX_EXEC_TIME_PER_CMD_AFTER=0
## Stops Osync execution if one of the above commands fail
STOP_ON_CMD_ERROR=yes