More and more refactoring

This commit is contained in:
deajan 2015-09-10 21:42:11 +02:00
parent 5370f203b8
commit 8f373258ad
2 changed files with 162 additions and 38 deletions

View File

@ -25,19 +25,21 @@ Transform old shell scripts using unexpand command
++++ Comments ++++ Comments
# Some comment Some command # comment
## Some important comment for the next function ## Some comment on a new line
################################################# Some separation ################################################# Some separation
++++ Todo comments ++++ Work comments
Whenever there is some idea to postpone, use #TODO: (exact match for searches) Whenever there is some idea to postpone, use #TODO: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
dev-name is mandatory if more than one person is coding
++++ Variables ++++ Variables
All local variables are lowercase, separated by _ (ex: low_wait) All local variables are lowercase, separated by _ (ex: low_wait)
All global variables full upercase, separated by _ (ex: EXEC_TIME) All global variables full upercase, separated by _ (ex: EXEC_TIME)
All instance variables (verbose, silent, etc) have prefix _ and are full upercase, separated by _ (ex: _VERBOSE_INSTANCE) All environment variables (verbose, silent, debug, etc) have prefix _ and are full upercase, separated by _ (ex: _PARANOIA_DEBUG)
++++ Functions ++++ Functions

188
osync.sh
View File

@ -4,7 +4,7 @@ PROGRAM="Osync" # Rsync based two way sync engine with fault tolerance
AUTHOR="(L) 2013-2015 by Orsiris \"Ozy\" de Jong" AUTHOR="(L) 2013-2015 by Orsiris \"Ozy\" de Jong"
CONTACT="http://www.netpower.fr/osync - ozy@netpower.fr" CONTACT="http://www.netpower.fr/osync - ozy@netpower.fr"
PROGRAM_VERSION=1.1-unstable PROGRAM_VERSION=1.1-unstable
PROGRAM_BUILD=2015091002 PROGRAM_BUILD=2015091003
## type doesn't work on platforms other than linux (bash). If if doesn't work, always assume output is not a zero exitcode ## type doesn't work on platforms other than linux (bash). If if doesn't work, always assume output is not a zero exitcode
if ! type -p "$BASH" > /dev/null; then if ! type -p "$BASH" > /dev/null; then
@ -62,7 +62,7 @@ function Dummy {
sleep .1 sleep .1
} }
function _logger { function _Logger {
local value="${1}" # What to log local value="${1}" # What to log
echo -e "$value" >> "$LOG_FILE" echo -e "$value" >> "$LOG_FILE"
@ -72,7 +72,7 @@ function _logger {
} }
function Logger { function Logger {
local value="${1}" # What to log local value="${1}" # Sentence to log (in double quotes)
local level="${2}" # Log level: DEBUG, NOTICE, WARN, ERROR, CRITIAL local level="${2}" # Log level: DEBUG, NOTICE, WARN, ERROR, CRITIAL
# Special case in daemon mode we should timestamp instead of counting seconds # Special case in daemon mode we should timestamp instead of counting seconds
@ -83,22 +83,27 @@ function Logger {
fi fi
if [ "$level" == "CRITICAL" ]; then if [ "$level" == "CRITICAL" ]; then
_logger "$prefix\e[41m$value\e[0m" _Logger "$prefix\e[41m$value\e[0m"
ERROR_ALERT=1 ERROR_ALERT=1
return
elif [ "$level" == "ERROR" ]; then elif [ "$level" == "ERROR" ]; then
_logger "$prefix\e[91m$value\e[0m" _Logger "$prefix\e[91m$value\e[0m"
ERROR_ALERT=1 ERROR_ALERT=1
return
elif [ "$level" == "WARN" ]; then elif [ "$level" == "WARN" ]; then
_logger "$prefix\e[93m$value\e[0m" _Logger "$prefix\e[93m$value\e[0m"
return
elif [ "$level" == "NOTICE" ]; then elif [ "$level" == "NOTICE" ]; then
_logger "$prefix$value" _Logger "$prefix$value"
return
elif [ "$level" == "DEBUG" ]; then elif [ "$level" == "DEBUG" ]; then
if [ "$_DEBUG" == "yes" ]; then if [ "$_DEBUG" == "yes" ]; then
_logger "$prefix$value" _Logger "$prefix$value"
return
fi fi
else else
_logger "\e[41mLogger function called without proper loglevel.\e[0m" _Logger "\e[41mLogger function called without proper loglevel.\e[0m"
_logger "$prefix$value" _Logger "$prefix$value"
fi fi
} }
@ -918,13 +923,54 @@ function _LEGACY_CheckMasterSlaveDirs {
fi fi
} }
function CheckMinimumSpace { function _CheckDiskSpaceLocal {
local replica_path="${1}"
__CheckArguments 1 $# $FUNCNAME "$*"
Logger "Checking minimum disk space in [$replica_path]." "NOTICE"
local initiator_space=$(df -P "$replica_path" | tail -1 | awk '{print $4}')
if [ $initiator_space -lt $MINIMUM_SPACE ]; then
Logger "There is not enough free space on initiator [$initiator_space KB]." "WARN"
fi
}
function _CheckDiskSpaceRemote {
local replica_path="${1}"
__CheckArguments 1 $# $FUNCNAME "$*"
Logger "Checking minimum disk space on target [$replica_path]." "NOTICE"
CheckConnectivity3rdPartyHosts
CheckConnectivityRemoteHost
cmd="$SSH_CMD \"$COMMAND_SUDO df -P \\\"$replca_path\\\"\" > $RUN_DIR/osync_$FUNCNAME_$SCRIPT_PID 2>&1 &"
eval $cmd
WaitForTaskCompletion $! 0 1800
if [ $? != 0 ]; then
Logger "Cannot get free space on target [$replica_path]." "ERROR"
Logger "Command output:\n$(cat $RUN_DIR/osync_$FUNCNAME_$SCRIPT_PID)"
else
local target_space=$(cat $RUN_DIR/osync_$FUNCNAME_$SCRIPT_PID | tail -1 | awk '{print $4}')
if [ $target_space -lt $MINIMUM_SPACE ]; then
Logger "There is not enough free space on target [$replica_path]." "WARN"
fi
fi
}
function CheckDiskSpace {
_CheckDiskSpaceLocal "$INITIATOR_SYNC_DIR"
if [ "$REMOTE_SYNC" == "no" ]; then
_CheckDiskSpaceLocal "$TARGET_SYNC_DIR"
else
_CheckDiskSpaceRemote "$TARGET_SYNC_DIR"
fi
}
function _LEGAGY_CheckMinimumSpace {
Logger "Checking minimum disk space on initiator and target." "NOTICE" Logger "Checking minimum disk space on initiator and target." "NOTICE"
INITIATOR_SPACE=$(df -P "$INITIATOR_SYNC_DIR" | tail -1 | awk '{print $4}')
if [ $INITIATOR_SPACE -lt $MINIMUM_SPACE ]; then
Logger "There is not enough free space on initiator [$INITIATOR_SPACE KB]." "ERROR"
fi
if [ "$REMOTE_SYNC" == "yes" ]; then if [ "$REMOTE_SYNC" == "yes" ]; then
CheckConnectivity3rdPartyHosts CheckConnectivity3rdPartyHosts
@ -980,7 +1026,47 @@ function RsyncExcludeFrom {
fi fi
} }
function _WriteLockFilesLocal {
local lockfile="${1}"
__CheckArguments 1 $# $FUNCNAME "$*"
echo "$SCRIPT_PID@$SYNC_ID" > "$lockfile" #TODO: Determine best format for lockfile for v2
if [ $? != 0 ]; then
Logger "Could not create lock file [$lockfile]." "CRITICAL"
exit 1
else
Logger "Locked replica on [$lockfile]." "NOTICE"
fi
}
function _WriteLockFilesRemote {
local lockfile="${1}"
__CheckArguments 1 $# $FUNCNAME "$*"
CheckConnectivity3rdPartyHosts
CheckConnectivityRemoteHosts
cmd="$SSH_CMD \"echo $SCRIPT_PID@$SYNC_ID | $COMMAND_SUDO tee \\\"$lock_file\\\" > /dev/null \"" &
eval $cmd
WaitForTaskCompletion $? 0 1800
if [ $? != 0 ]; then
Logger "Could not set lock on remote target replica." "CRITICAL"
exit 1
else
Logger "Locked remote target replica." "NOTICE"
fi
}
function WriteLockFiles { function WriteLockFiles {
_WriteLockFilesLocal "$INITIATOR_LOCKFILE"
if [ "$REMOTE_SYNC" != "yes" ]; then
_WriteLockFilesLocal "$TARGET_LOCKFILE"
else
_WriteLockFilesRemote "$TARGET_LOCKFILE"
fi
}
function _LEGAGY_WriteLockFiles {
echo $SCRIPT_PID > "$INITIATOR_LOCK" echo $SCRIPT_PID > "$INITIATOR_LOCK"
if [ $? != 0 ]; then if [ $? != 0 ]; then
Logger "Could not set lock on initiator replica." "CRITICAL" Logger "Could not set lock on initiator replica." "CRITICAL"
@ -1012,12 +1098,50 @@ function WriteLockFiles {
fi fi
} }
function _CheckLocksLocal {
local lockfile="${1}"
__CheckArguments 1 $# $FUNCNAME "$*"
#WIP:deajan: Refactor here
}
function _CheckLocksRemote {
local lockfile="${1}"
__CheckArguments 1 $# $FUNCNAME "$*"
CheckConnectivity3rdPartyHosts
CheckConnectivityRemoteHosts
#WIP:deajan: Refactor here
}
function CheckLocks {
if [ $_NOLOCKS -eq 1 ]; then
return 0
fi
# Don't bother checking for locks when FORCE_UNLOCK is set
if [ $FORCE_UNLOCK -eq 1 ]; then
WriteLockFiles
if [ $? != 0 ]; then
exit 1
fi
fi
_CheckLocksLocal "$INITIATOR_LOCKFILE"
if [ "$REMOTE_SYNC" != "yes" ]; then
_CheckLocksLocal "$TARGET_LOCKFILE"
else
_CheckLocksRemote "$TARGET_LOCKFILE"
fi
}
function LockDirectories { function LockDirectories {
if [ $_NOLOCKS -eq 1 ]; then if [ $_NOLOCKS -eq 1 ]; then
return 0 return 0
fi fi
if [ $force_unlock -eq 1 ]; then # Don't bother checking for locks when FORCE_UNLOCK is set
if [ $FORCE_UNLOCK -eq 1 ]; then
WriteLockFiles WriteLockFiles
if [ $? != 0 ]; then if [ $? != 0 ]; then
exit 1 exit 1
@ -1026,8 +1150,8 @@ function LockDirectories {
Logger "Checking for replica locks." "NOTICE" Logger "Checking for replica locks." "NOTICE"
if [ -f "$INITIATOR_LOCK" ]; then if [ -f "$INITIATOR_LOCKFILE" ]; then
initiator_lock_pid=$(cat $INITIATOR_LOCK) initiator_lock_pid=$(cat $INITIATOR_LOCKFILE)
Logger "Master lock pid present: $initiator_lock_pid" "DEBUG" Logger "Master lock pid present: $initiator_lock_pid" "DEBUG"
ps -p$initiator_lock_pid > /dev/null 2>&1 ps -p$initiator_lock_pid > /dev/null 2>&1
if [ $? != 0 ]; then if [ $? != 0 ]; then
@ -1041,7 +1165,7 @@ function LockDirectories {
if [ "$REMOTE_SYNC" == "yes" ]; then if [ "$REMOTE_SYNC" == "yes" ]; then
CheckConnectivity3rdPartyHosts CheckConnectivity3rdPartyHosts
CheckConnectivityRemoteHost CheckConnectivityRemoteHost
eval "$SSH_CMD \"if [ -f \\\"$TARGET_LOCK\\\" ]; then cat \\\"$TARGET_LOCK\\\"; fi\" > $RUN_DIR/osync_remote_target_lock_$SCRIPT_PID" & eval "$SSH_CMD \"if [ -f \\\"$TARGET_LOCKFILE\\\" ]; then cat \\\"$TARGET_LOCKFILE\\\"; fi\" > $RUN_DIR/osync_remote_target_lock_$SCRIPT_PID" &
child_pid=$! child_pid=$!
WaitForTaskCompletion $child_pid 0 1800 WaitForTaskCompletion $child_pid 0 1800
if [ -f $RUN_DIR/osync_remote_target_lock_$SCRIPT_PID ]; then if [ -f $RUN_DIR/osync_remote_target_lock_$SCRIPT_PID ]; then
@ -1049,9 +1173,9 @@ function LockDirectories {
target_lock_id=$(cat $RUN_DIR/osync_remote_target_lock_$SCRIPT_PID | cut -d'@' -f2) target_lock_id=$(cat $RUN_DIR/osync_remote_target_lock_$SCRIPT_PID | cut -d'@' -f2)
fi fi
else else
if [ -f "$TARGET_LOCK" ]; then if [ -f "$TARGET_LOCKFILE" ]; then
target_lock_pid=$(cat "$TARGET_LOCK" | cut -d'@' -f1) target_lock_pid=$(cat "$TARGET_LOCKFILE" | cut -d'@' -f1)
target_lock_id=$(cat "$TARGET_LOCK" | cut -d'@' -f2) target_lock_id=$(cat "$TARGET_LOCKFILE" | cut -d'@' -f2)
fi fi
fi fi
@ -1839,8 +1963,8 @@ function Init {
INITIATOR_STATE_DIR="$INITIATOR_SYNC_DIR$OSYNC_DIR/state" INITIATOR_STATE_DIR="$INITIATOR_SYNC_DIR$OSYNC_DIR/state"
TARGET_STATE_DIR="$TARGET_SYNC_DIR$OSYNC_DIR/state" TARGET_STATE_DIR="$TARGET_SYNC_DIR$OSYNC_DIR/state"
STATE_DIR="$OSYNC_DIR/state" STATE_DIR="$OSYNC_DIR/state"
INITIATOR_LOCK="$INITIATOR_STATE_DIR/lock" INITIATOR_LOCKFILE="$INITIATOR_STATE_DIR/lock"
TARGET_LOCK="$TARGET_STATE_DIR/lock" TARGET_LOCKFILE="$TARGET_STATE_DIR/lock"
## Working directories to keep backups of updated / deleted files ## Working directories to keep backups of updated / deleted files
INITIATOR_BACKUP_DIR="$OSYNC_DIR/backups" INITIATOR_BACKUP_DIR="$OSYNC_DIR/backups"
@ -2141,7 +2265,7 @@ fi
stats=0 stats=0
PARTIAL=0 PARTIAL=0
force_unlock=0 FORCE_UNLOCK=0
no_maxtime=0 no_maxtime=0
# Alert flags # Alert flags
opts="" opts=""
@ -2183,7 +2307,7 @@ do
opts=$opts" --partial" opts=$opts" --partial"
;; ;;
--force-unlock) --force-unlock)
force_unlock=1 FORCE_UNLOCK=1
opts=$opts" --force-unlock" opts=$opts" --force-unlock"
;; ;;
--no-maxtime) --no-maxtime)
@ -2305,15 +2429,13 @@ then
HARD_MAX_EXEC_TIME=0 HARD_MAX_EXEC_TIME=0
fi fi
CheckReplicaPaths CheckReplicaPaths
CheckMinimumSpace CheckDiskSpace
RunBeforeHook
Main
if [ $? == 0 ]; then if [ $? == 0 ]; then
RunBeforeHook SoftDelete
Main
if [ $? == 0 ]; then
SoftDelete
fi
RunAfterHook
fi fi
RunAfterHook
fi fi
else else
Logger "Environment not suitable to run osync." "CRITICAL" Logger "Environment not suitable to run osync." "CRITICAL"