#!/usr/bin/env bash #************************************************************************# # # # Copyright (c) 2017 Red Hat, Inc. # # This file is part of gluster-block. # # # # This file is licensed to you under your choice of the GNU Lesser # # General Public License, version 3 or any later version (LGPLv3 or # # later), or the GNU General Public License, version 2 (GPLv2), in all # # cases as published by the Free Software Foundation. # # # #************************************************************************# # How to run this script: # # ---------------------- # # $ ./replace-node.sh ${MOUNTPOINT} ${OLDNODE} ${NEWNODE} # # # #************************************************************************# LOGDIR="/var/log/gluster-block/" function schedule_terminate () { echo -e "\nholdon! we have received signal, this program will be terminated in the next safe point ..\n" printLog "Terminating script in the signal handler..." SAFE_EXIT=1 fdClose ${fd} } function getAvailableFd() { for i in {1..65536}; do if [ ! -e /proc/$$/fd/${i} ]; then echo ${i}; return 0; fi done return 1; } function fdOpen() { local fd=${1} local path=${2} # open in read mode eval "exec ${fd}<${path}" } function fdClose() { local fd=${1} eval "exec ${fd}>&-" } function printLog() { local msg=${1} echo "[$(date -u +'%Y-%m-%d %I:%M:%S')] ${msg}" >> ${LOGDIR}/gluster-block-replace.log } function readMetaInfo() { while read line; do METADATA+=(["$(echo ${line} | cut -d: -f1)"]=$(echo ${line} | cut -d' ' -f2 | tr -d " \n")) done < ${1} } function isStrPartOfArray() { local args=("${@}") local str=${args[0]} local array=${args[@]:1} for i in ${array[@]}; do if [ "${str}" == "${i}" ]; then return 0; fi done return 1; } function isStatusValid() { local status=${1} case "${status}" in "CONFIGSUCCESS" | "CLEANUPINPROGRESS" | "AUTHENFORCEING" | "AUTHENFORCED" | "AUTHENFORCEFAIL" | "AUTHCLEARENFORCED" | "AUTHCLEARENFORCEING" | "AUTHCLEARENFORCEFAIL") return 0; ;; esac return 1; } function getValidHosts() { eval "declare -A metadata="${1#*=} local validHostsArr=() local commonKeys=(VOLUME GBID SIZE HA ENTRYCREATE PASSWORD) for index in ${!metadata[@]}; do isStrPartOfArray "${index}" "${commonKeys[@]}" ret=$? if [[ ${ret} -ne 0 ]]; then isStatusValid ${metadata["${index}"]} ret=$? if [[ ${ret} -ne 1 ]]; then validHostsArr+=("${index}") fi fi done unset metadata echo "${validHostsArr[@]}" # return } function runCreate() { eval "declare -A metadata="${1#*=} local block_name=${2} local old_node=${3} local new_node=${4} local iqn_prefix="iqn.2016-12.org.gluster-block" local gbid=${metadata["GBID"]} local hosts=( $(getValidHosts "$(declare -p metadata)") ) local cmd="targetcli < /tmp/gb_create parseCreateOutput "$(declare -p METADATA)" ${BLOCKNAME} ${NEWNODE} && echo "${OLDNODE}: CLEANUPSUCCESS" >> "${DIR}/${BLOCKNAME}" && echo "${NEWNODE}: CONFIGSUCCESS" >> "${DIR}/${BLOCKNAME}" ret=$? if [[ ${ret} -eq 0 ]]; then echo "create on '${NEWNODE}' success" printLog "INFO: create of ${BLOCKNAME} on ${NEWNODE} success" else echo "create on '${NEWNODE}' failed" printLog "ERROR: create of ${BLOCKNAME} on ${NEWNODE} failed" printLog "INFO: skipping replace and delete for ${BLOCKNAME}" echo "-------------------------------------" # unset variables unset HOSTS unset METADATA releaseLockExit ${fd} continue; fi for NODE in ${HOSTS[@]}; do if [[ "${NODE}" != "${OLDNODE}" ]]; then REPLACEOUT=$(ssh root@${NODE} "$(declare -f runReplace); runReplace '$(declare -p METADATA)' ${OLDNODE} ${NEWNODE}") parseReplaceOutput "${REPLACEOUT}" ${BLOCKNAME} ${OLDNODE} ${NEWNODE} ret=$? if [[ ${ret} -eq 0 ]]; then echo "replace on '${NODE}' success" printLog "INFO: replace of ${BLOCKNAME} on ${NODE} success" # TODO: update metadata once we have a relevant meta status flag else echo "replace on '${NODE}' failed" printLog "ERROR: replace of ${BLOCKNAME} on ${NODE} failed" fi unset REPLACEOUT fi done DELETEOUT=$(ssh root@${OLDNODE} "$(declare -f runDelete); runDelete '$(declare -p METADATA)' ${BLOCKNAME}") parseDeleteOutput "${DELETEOUT}" ${BLOCKNAME} ${METADATA["GBID"]} ret=$? if [[ ${ret} -eq 0 ]]; then echo "delete on '${OLDNODE}' success" printLog "INFO: delete of ${BLOCKNAME} on ${OLDNODE} success" else echo "delete on '${OLDNODE}' failed" printLog "ERROR: delete of ${BLOCKNAME} on ${OLDNODE} failed" fi unset DELETEOUT echo "-------------------------------------" # unset variables unset HOSTS unset METADATA releaseLockExit ${fd} done printLog "Finished replace node job, mount-point=${MOUNTPOINT} old-node=${OLDNODE} new-node=${NEWNODE}" fdClose ${fd}