From 019db978d82d850925abaf2651b4ef549ec0f987 Mon Sep 17 00:00:00 2001 From: Prasanna Kumar Kalever Date: Wed, 25 Oct 2017 21:48:00 +0530 Subject: extras: add script for replace node $ for i in {1..3}; do echo "block${i}:"; gluster-block create test/block$i ha 3 192.168.124.208,192.168.124.8,192.168.124.179 1MiB --json-pretty; done block1: { "IQN":"iqn.2016-12.org.gluster-block:ccc8f04b-1498-4c55-b27b-a1c500799d7b", "PORTAL(S)":[ "192.168.124.208:3260", "192.168.124.8:3260", "192.168.124.179:3260" ], "RESULT":"SUCCESS" } block2: { "IQN":"iqn.2016-12.org.gluster-block:a081f36d-ba9a-4679-a7d5-a6c9b5add2c0", "PORTAL(S)":[ "192.168.124.208:3260", "192.168.124.8:3260", "192.168.124.179:3260" ], "RESULT":"SUCCESS" } block3: { "IQN":"iqn.2016-12.org.gluster-block:53525e2d-c69d-4770-a645-f60847b9190d", "PORTAL(S)":[ "192.168.124.208:3260", "192.168.124.8:3260", "192.168.124.179:3260" ], "RESULT":"SUCCESS" } $ gluster-block list test --json-pretty{ "blocks":[ "block1", "block2", "block3" ], "RESULT":"SUCCESS" } $ ./replace-node.sh help Usage: ./replace-node.sh ${MOUNTPOINT} ${OLDNODE} ${NEWNODE} $ ./replace-node.sh /mnt/test 192.168.124.179 192.168.124.128 Fuse mount point, does not have directory '/mnt/test/block-meta/' Usage: ./replace-node.sh ${MOUNTPOINT} ${OLDNODE} ${NEWNODE} $ mount.glusterfs localhost:/test /mnt/test $ ./replace-node.sh /mnt/test/ 192.168.124.179 192.168.124.128 blockname: block1 create on '192.168.124.128' success replace on '192.168.124.208' success replace on '192.168.124.8' success delete on '192.168.124.179' success ------------------------------------- blockname: block2 create on '192.168.124.128' success replace on '192.168.124.208' success replace on '192.168.124.8' success delete on '192.168.124.179' success ------------------------------------- blockname: block3 create on '192.168.124.128' success replace on '192.168.124.208' success replace on '192.168.124.8' success delete on '192.168.124.179' success ------------------------------------- Change-Id: I68ce36063accfdc1f56c8f160b8c4dd4ca58afe7 Signed-off-by: Prasanna Kumar Kalever --- extras/replace-node.sh | 550 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 550 insertions(+) create mode 100755 extras/replace-node.sh diff --git a/extras/replace-node.sh b/extras/replace-node.sh new file mode 100755 index 0000000..d9f3a74 --- /dev/null +++ b/extras/replace-node.sh @@ -0,0 +1,550 @@ +#!/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} -- cgit