From 8a088d92ccb96995e17f5d55e6da988de052e64f Mon Sep 17 00:00:00 2001 From: deajan Date: Sat, 26 Sep 2015 13:30:55 +0200 Subject: [PATCH] Successfully tested upgrade script --- CHANGELOG.md | 4 +- upgrade-v1.0x-v1.1x.sh | 346 +++++++++++++++++++++++++++++++++++++++++ upgrade.sh | 94 ----------- 3 files changed, 348 insertions(+), 96 deletions(-) create mode 100755 upgrade-v1.0x-v1.1x.sh delete mode 100755 upgrade.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index d7b8f3e..36920d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,11 +12,11 @@ KNOWN ISSUES RECENT CHANGES -------------- -! Check for deletion failed list file before trying to copy it back +! Check for deletion failed list file before trying to copy it back (normally empty file is created anyway) - Passed shellCheck.net - Simplified EscapeSpaces to simple bash substitution - Corrected a lot of minor warnings in order to make code more bullet proof -- Added basic v1.0x to v1.1 upgrade script +- Added v1.0x to v1.1 upgrade script - Added (much) more verbose debugging (and possibility to remove debug code to gain speed) - Force tree function to overwrite earlier tree files - Add Logger DEBUG to all eval statements diff --git a/upgrade-v1.0x-v1.1x.sh b/upgrade-v1.0x-v1.1x.sh new file mode 100755 index 0000000..3404d5a --- /dev/null +++ b/upgrade-v1.0x-v1.1x.sh @@ -0,0 +1,346 @@ +#!/bin/bash + +PROGRAM="Osync instance upagrade script" # Rsync based two way sync engine with fault tolerance +AUTHOR="(L) 2015 by Orsiris \"Ozy\" de Jong" +CONTACT="http://www.netpower.fr/osync - ozy@netpower.fr" +PROGRAM_VERSION="1.0x to v1.1" +PROGRAM_BUILD=2015092501 + +function Init { + OSYNC_DIR=".osync_workdir" + STATE_DIR="state" + + TREE_CURRENT_FILENAME="-tree-current-$SYNC_ID" + TREE_AFTER_FILENAME="-tree-after-$SYNC_ID" + TREE_AFTER_FILENAME_NO_SUFFIX="-tree-after-$SYNC_ID" + DELETED_LIST_FILENAME="-deleted-list-$SYNC_ID" + FAILED_DELETE_LIST_FILENAME="-failed-delete-$SYNC_ID" + + if [ "${SLAVE_SYNC_DIR:0:6}" == "ssh://" ]; then + REMOTE_SYNC="yes" + + # remove leadng 'ssh://' + uri=${SLAVE_SYNC_DIR#ssh://*} + if [[ "$uri" == *"@"* ]]; then + # remove everything after '@' + REMOTE_USER=${uri%@*} + else + REMOTE_USER=$LOCAL_USER + fi + + if [ "$SSH_RSA_PRIVATE_KEY" == "" ]; then + SSH_RSA_PRIVATE_KEY=~/.ssh/id_rsa + fi + + # remove everything before '@' + _hosturiandpath=${uri#*@} + # remove everything after first '/' + _hosturi=${_hosturiandpath%%/*} + if [[ "$_hosturi" == *":"* ]]; then + REMOTE_PORT=${_hosturi##*:} + else + REMOTE_PORT=22 + fi + REMOTE_HOST=${_hosturi%%:*} + + # remove everything before first '/' + SLAVE_SYNC_DIR=${_hosturiandpath#*/} + fi + + SSH_CMD="$(type -p ssh) $SSH_COMP -i $SSH_RSA_PRIVATE_KEY $REMOTE_USER@$REMOTE_HOST -p $REMOTE_PORT" +} + +function Usage { + echo "$PROGRAM $PROGRAM_VERSION $PROGRAM_BUILD" + echo $AUTHOR + echo $CONTACT + echo "" + echo "This script migrates osync v1.0x setups to v1.1 by updating state filenames and config files." + echo "" + echo "Usage: upgrade.sh /path/to/config_file.conf" + echo "Usage: upgrade.sh --master=/path/to/master/replica --slave=/path/to/local/slave/replica --sync-id=existing_id" + echo "Usage: upgrade.sh --master=/path/to/master/replica --slave=ssh://[backupuser]@remotehost.com[:portnumber]//path/to/slave/replica --sync-id=existing_id --rsakey=/path/to/rsa/key" + echo "" + echo "If config file is provided, the config file itself and both replicas from config file will be updated." + echo "If no config file provided, assume you run the update script just like any other quicksync task." + echo "If sync-id is not specified, it will assume handling a quicksync task." + exit 128 +} + +function CheckEnvironment { + if [ "$REMOTE_SYNC" == "yes" ]; then + if ! type -p ssh > /dev/null 2>&1 + then + Logger "ssh not present. Cannot start sync." "CRITICAL" + return 1 + fi + fi + + if ! type -p rsync > /dev/null 2>&1 + then + Logger "rsync not present. Sync cannot start." "CRITICAL" + return 1 + fi +} + +function LoadConfigFile { + local config_file="${1}" + + if [ ! -f "$config_file" ]; then + echo "Cannot load configuration file [$config_file]. Sync cannot start." + exit 1 + elif [[ "$1" != *".conf" ]]; then + echo "Wrong configuration file supplied [$config_file]. Sync cannot start." + exit 1 + else + egrep '^#|^[^ ]*=[^;&]*' "$config_file" > "./osync.$FUNCNAME.$SCRIPT_PID" + # Shellcheck source=./sync.conf + source "./osync.$FUNCNAME.$SCRIPT_PID" + fi +} + +function _RenameStateFilesLocal { + local state_dir="${1}" # Absolute path to statedir + local rewrite=false + + echo "Rewriting state files in [$state_dir]." + + # Make sure there is no ending slash + state_dir="${state_dir%/}/" + + if [ -f "$state_dir""master"$TREE_CURRENT_FILENAME ]; then + mv -f "$state_dir""master"$TREE_CURRENT_FILENAME "$state_dir""initiator"$TREE_CURRENT_FILENAME + if [ $? != 0 ]; then + echo "Error while rewriting "$state_dir"master"$TREE_CURRENT_FILENAME + else + rewrite=true + fi + fi + if [ -f "$state_dir""master"$TREE_AFTER_FILENAME ]; then + mv -f "$state_dir""master"$TREE_AFTER_FILENAME "$state_dir""initiator"$TREE_AFTER_FILENAME + if [ $? != 0 ]; then + echo "Error while rewriting "$state_dir"master"$TREE_AFTER_FILENAME + else + rewrite=true + fi + fi + if [ -f "$state_dir""master"$DELETED_LIST_FILENAME ]; then + mv -f "$state_dir""master"$DELETED_LIST_FILENAME "$state_dir""initiator"$DELETED_LIST_FILENAME + if [ $? != 0 ]; then + echo "Error while rewriting "$state_dir"master"$DELETED_LIST_FILENAME + else + rewrite=true + fi + rewrite=true + fi + if [ -f "$state_dir""master"$FAILED_DELETE_LIST_FILENAME ]; then + mv -f "$state_dir""master"$FAILED_DELETE_LIST_FILENAME "$state_dir""initiator"$FAILED_DELETE_LIST_FILENAME + if [ $? != 0 ]; then + echo "Error while rewriting "$state_dir"master"$FAILED_DELETE_LIST_FILENAME + else + rewrite=true + fi + fi + + if [ -f "$state_dir""master"$TREE_CURRENT_FILENAME"-dry" ]; then + mv -f "$state_dir""master"$TREE_CURRENT_FILENAME"-dry" "$state_dir""initiator"$TREE_CURRENT_FILENAME"-dry" + if [ $? != 0 ]; then + echo "Error while rewriting "$state_dir"master"$TREE_CURRENT_FILENAME"-dry" + else + rewrite=true + fi + fi + if [ -f "$state_dir""master"$TREE_AFTER_FILENAME"-dry" ]; then + mv -f "$state_dir""master"$TREE_AFTER_FILENAME"-dry" "$state_dir""initiator"$TREE_AFTER_FILENAME"-dry" + if [ $? != 0 ]; then + echo "Error while rewriting "$state_dir""master"$TREE_AFTER_FILENAME" + else + rewrite=true + fi + fi + if [ -f "$state_dir""master"$DELETED_LIST_FILENAME"-dry" ]; then + mv -f "$state_dir""master"$DELETED_LIST_FILENAME"-dry" "$state_dir""initiator"$DELETED_LIST_FILENAME"-dry" + if [ $? != 0 ]; then + echo "Error while rewriting "$state_dir"master"$DELETED_LIST_FILENAME"-dry" + else + rewrite=true + fi + fi + if [ -f "$state_dir""master"$FAILED_DELETE_LIST_FILENAME"-dry" ]; then + mv -f "$state_dir""master"$FAILED_DELETE_LIST_FILENAME"-dry" "$state_dir""initiator"$FAILED_DELETE_LIST_FILENAME"-dry" + if [ $? != 0 ]; then + echo "Error while rewriting "$state_dir"master"$FAILED_DELETE_LIST_FILENAME"-dry" + else + rewrite=true + fi + fi + + if [ -f "$state_dir""slave"$TREE_CURRENT_FILENAME ]; then + mv -f "$state_dir""slave"$TREE_CURRENT_FILENAME "$state_dir""target"$TREE_CURRENT_FILENAME + if [ $? != 0 ]; then + echo "Error while rewriting "$state_dir"slave"$TREE_CURRENT_FILENAME + else + rewrite=true + fi + fi + if [ -f "$state_dir""slave"$TREE_AFTER_FILENAME ]; then + mv -f "$state_dir""slave"$TREE_AFTER_FILENAME "$state_dir""target"$TREE_AFTER_FILENAME + if [ $? != 0 ]; then + echo "Error while rewriting "$state_dir"slave"$TREE_AFTER_FILENAME + else + rewrite=true + fi + fi + if [ -f "$state_dir""slave"$DELETED_LIST_FILENAME ]; then + mv -f "$state_dir""slave"$DELETED_LIST_FILENAME "$state_dir""target"$DELETED_LIST_FILENAME + if [ $? != 0 ]; then + echo "Error while rewriting "$state_dir"slave"$DELETED_LIST_FILENAME + else + rewrite=true + fi + fi + if [ -f "$state_dir""slave"$FAILED_DELETE_LIST_FILENAME ]; then + mv -f "$state_dir""slave"$FAILED_DELETE_LIST_FILENAME "$state_dir""target"$FAILED_DELETE_LIST_FILENAME + if [ $? != 0 ]; then + echo "Error while rewriting "$state_dir"slave"$FAILED_DELETE_LIST_FILENAME + else + rewrite=true + fi + fi + + if [ -f "$state_dir""slave"$TREE_CURRENT_FILENAME"-dry" ]; then + mv -f "$state_dir""slave"$TREE_CURRENT_FILENAME"-dry" "$state_dir""target"$TREE_CURRENT_FILENAME"-dry" + if [ $? != 0 ]; then + echo "Error while rewriting "$state_dir"slave"$TREE_CURRENT_FILENAME"-dry" + else + rewrite=true + fi + fi + if [ -f "$state_dir""slave"$TREE_AFTER_FILENAME"-dry" ]; then + mv -f "$state_dir""slave"$TREE_AFTER_FILENAME"-dry" "$state_dir""target"$TREE_AFTER_FILENAME"-dry" + if [ $? != 0 ]; then + echo "Error while rewriting "$state_dir"slave"$TREE_AFTER_FILENAME"-dry" + else + rewrite=true + fi + fi + if [ -f "$state_dir""slave"$DELETED_LIST_FILENAME"-dry" ]; then + mv -f "$state_dir""slave"$DELETED_LIST_FILENAME"-dry" "$state_dir""target"$DELETED_LIST_FILENAME"-dry" + if [ $? != 0 ]; then + echo "Error while rewriting "$state_dir"slave"$DELETED_LIST_FILENAME"-dry" + else + rewrite=true + fi + fi + if [ -f "$state_dir""slave"$FAILED_DELETE_LIST_FILENAME"-dry" ]; then + mv -f "$state_dir""slave"$FAILED_DELETE_LIST_FILENAME"-dry" "$state_dir""target"$FAILED_DELETE_LIST_FILENAME"-dry" + if [ $? != 0 ]; then + echo "Error while rewriting "$state_dir"slave"$FAILED_DELETE_LIST_FILENAME"-dry" + else + rewrite=true + fi + fi + } + +function _RenameStateFilesRemote { + + echo "Connecting remotely to rewrite state files in [$1]." + +$SSH_CMD state_dir="${1}" DELETED_LIST_FILENAME="$DELETED_LIST_FILENAME" FAILED_DELETE_LIST_FILENAME="$FAILED_DELETE_LIST_FILENAME" 'bash -x -s' << 'ENDSSH' + + # Make sure there is no ending slash + state_dir="${state_dir%/}/" + + if [ -f "$state_dir""master"$DELETED_LIST_FILENAME ]; then + mv -f "$state_dir""master"$DELETED_LIST_FILENAME "$state_dir""initiator"$DELETED_LIST_FILENAME + if [ $? != 0 ]; then + echo "Error while rewriting "$state_dir"master"$DELETED_LIST_FILENAME + else + rewrite=true + fi + fi + if [ -f "$state_dir""master"$FAILED_DELETE_LIST_FILENAME ]; then + mv -f "$state_dir""master"$FAILED_DELETE_LIST_FILENAME "$state_dir""initiator"$FAILED_DELETE_LIST_FILENAME + if [ $? != 0 ]; then + echo "Error while rewriting "$state_dir"master"$FAILED_DELETE_LIST_FILENAME + else + rewrite=true + fi + fi + if [ -f "$state_dir""master"$FAILED_DELETE_LIST_FILENAME"-dry" ]; then + mv -f "$state_dir""master"$FAILED_DELETE_LIST_FILENAME"-dry" "$state_dir""initiator"$FAILED_DELETE_LIST_FILENAME"-dry" + if [ $? != 0 ]; then + echo "Error while rewriting "$state_dir"master"$FAILED_DELETE_LIST_FILENAME"-dry" + else + rewrite=true + fi + fi +ENDSSH + } + +function RenameStateFiles { + _RenameStateFilesLocal "$MASTER_SYNC_DIR/$OSYNC_DIR/$STATE_DIR" + if [ "$REMOTE_SYNC" != "yes" ]; then + _RenameStateFilesLocal "$SLAVE_SYNC_DIR/$OSYNC_DIR/$STATE_DIR" + else + _RenameStateFilesRemote "$SLAVE_SYNC_DIR/$OSYNC_DIR/$STATE_DIR" + fi +} + +function RewriteConfigFiles { + local config_file="${1}" + + if ! grep "MASTER_SYNC_DIR=" "$config_file" > /dev/null; then + echo "Config file $config_file does not seem like an osync v1.0x file." + exit + fi + + echo "Rewriting config file $config_file" + + #TODO: exclude occurences between doublequotes + + sed -i 's/MASTER_SYNC_DIR/INITIATOR_SYNC_DIR/g' "$config_file" + sed -i 's/SLAVE_SYNC_DIR/TARGET_SYNC_DIR/g' "$config_file" + sed -i 's/CONFLICT_PREVALANCE=master/CONFLICT_PREVALANCE=initiator/g' "$config_file" + sed -i 's/CONFLICT_PREVALANCE=slave/CONFLICT_PREVALANCE=target/g' "$config_file" +} + +_QUICKSYNC=0 + +for i in "$@" +do + case $i in + --master=*) + no_maxtime=1 + MASTER_SYNC_DIR=${i##*=} + QUICK_SYNC=$(($_QUICKSYNC + 1)) + ;; + --slave=*) + SLAVE_SYNC_DIR=${i##*=} + QUICK_SYNC=$(($_QUICKSYNC + 1)) + ;; + --rsakey=*) + SSH_RSA_PRIVATE_KEY=${i##*=} + ;; + --sync-id=*) + SYNC_ID=${i##*=} + ;; + esac +done + +if [ $_QUICKSYNC -eq 2 ]; then + Init + REPLICA_DIR=${i##*=} + RenameStateFiles + +elif [ "$1" != "" ] && [ -f "$1" ] && [ -w "$1" ]; then + CONF_FILE="$1" + # Make sure there is no ending slash + CONF_FILE="${CONF_FILE%/}" + LoadConfigFile "$CONF_FILE" + Init + RewriteConfigFiles "$CONF_FILE" + RenameStateFiles +else + Usage +fi diff --git a/upgrade.sh b/upgrade.sh deleted file mode 100755 index 00f11e3..0000000 --- a/upgrade.sh +++ /dev/null @@ -1,94 +0,0 @@ -#!/bin/bash - -PROGRAM="Osync instance upagrade script" # Rsync based two way sync engine with fault tolerance -AUTHOR="(L) 2015 by Orsiris \"Ozy\" de Jong" -CONTACT="http://www.netpower.fr/osync - ozy@netpower.fr" -PROGRAM_VERSION="1.0x to v1.1" -PROGRAM_BUILD=2015091801 - -function Init { - TREE_CURRENT_FILENAME="-tree-current-$SYNC_ID" - TREE_AFTER_FILENAME="-tree-after-$SYNC_ID" - TREE_AFTER_FILENAME_NO_SUFFIX="-tree-after-$SYNC_ID" - DELETED_LIST_FILENAME="-deleted-list-$SYNC_ID$" - FAILED_DELETE_LIST_FILENAME="-failed-delete-$SYNC_ID" -} - -function Usage { - echo "DEV VERSION !!! DO NOT USE" - - echo "$PROGRAM $PROGRAM_VERSION $PROGRAM_BUILD" - echo $AUTHOR - echo $CONTACT - echo "" - echo "This script migrates osync v1.0x setups to v1.1 by updating state filenames and config files." - echo "" - echo "Usage: migrate.sh /path/to/config_file.conf" - echo "Usage: migrate.sh --replica=/path/to/replica --sync-id=someid" - echo "" - echo "This script must be run manually on all replicas. If slave replica is remote, must be run locally on slave system." - echo "If sync-id is not specified, it will assume handling a quicksync task." - echo "Config files must also be updated if they exist." - - exit 1 -} - -function RenameStateFiles { - local state_dir="${1}" # Absolute path to statedir - - # Make sure there is no ending slash - state_dir="${state_dir%/}/" - - mv -f "$state_dir""master"$TREE_CURRENT_FILENAME "$state_dir""initiator"$TREE_CURRENT_FILENAME - mv -f "$state_dir""master"$TREE_AFTER_FILENAME "$state_dir""initiator"$TREE_AFTER_FILENAME - mv -f "$state_dir""master"$DELETED_LIST_FILENAME "$state_dir""initiator"$DELETED_LIST_FILENAME - mv -f "$state_dir""master"$FAILED_DELETE_LIST_FILENAME "$state_dir""initiator"$FAILED_DELETE_LIST_FILENAME - - mv -f "$state_dir""master"$TREE_CURRENT_FILENAME"-dry" "$state_dir""initiator"$TREE_CURRENT_FILENAME"-dry" - mv -f "$state_dir""master"$TREE_AFTER_FILENAME"-dry" "$state_dir""initiator"$TREE_AFTER_FILENAME"-dry" - mv -f "$state_dir""master"$DELETED_LIST_FILENAME"-dry" "$state_dir""initiator"$DELETED_LIST_FILENAME"-dry" - mv -f "$state_dir""master"$FAILED_DELETE_LIST_FILENAME"-dry" "$state_dir""initiator"$FAILED_DELETE_LIST_FILENAME"-dry" - - mv -f "$state_dir""target"$TREE_CURRENT_FILENAME "$state_dir""target"$TREE_CURRENT_FILENAME - mv -f "$state_dir""target"$TREE_AFTER_FILENAME "$state_dir""target"$TREE_AFTER_FILENAME - mv -f "$state_dir""target"$DELETED_LIST_FILENAME "$state_dir""target"$DELETED_LIST_FILENAME - mv -f "$state_dir""target"$FAILED_DELETE_LIST_FILENAME "$state_dir""target"$FAILED_DELETE_LIST_FILENAME - - mv -f "$state_dir""target"$TREE_CURRENT_FILENAME"-dry" "$state_dir""target"$TREE_CURRENT_FILENAME"-dry" - mv -f "$state_dir""target"$TREE_AFTER_FILENAME"-dry" "$state_dir""target"$TREE_AFTER_FILENAME"-dry" - mv -f "$state_dir""target"$DELETED_LIST_FILENAME"-dry" "$state_dir""target"$DELETED_LIST_FILENAME"-dry" - mv -f "$state_dir""target"$FAILED_DELETE_LIST_FILENAME"-dry" "$state_dir""target"$FAILED_DELETE_LIST_FILENAME"-dry" - } - -function RewriteConfigFiles { - local config_file="${1}" - - #TODO: exclude occurences between doublequotes - - sed -i 's/master/initiator/g' "$config_file" - sed -i 's/MASTER/INITIATOR/g' "$config_file" - sed -i 's/slave/target/g' "$config_file" - sed -i 's/SLAVE/TARGET/g' "$config_file" -} - -parameter="$1" -second_param="$2" - -if [ "${parameter:0,10}" == "--replica=" ]; then - if [ "${second_param:0,10}" == "--sync-id=" ]; then - $SYNC_ID=${second_param##*=} - else - $SYNC_ID="quicksync task" - fi - Init - REPLICA_DIR=${i##*=} - RenameStateFiles "$REPLICA_DIR" - -elif [ "$parameter" != "" ] && [ -d "$parameter" ] && [ -w "$parameter" ]; then - CONF_DIR="$parameter" - # Make sure there is no ending slash - CONF_DIR="${CONF_DIR%/}" - RewriteConfigFiles "$CONF_DIR" -else - Usage -fi