#!/bin/bash
#
# Copyright (c) 2010-2013 SUSE LLC, All Rights Reserved.
#
# Author: Xia Li <xli@suse.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of version 2 of the GNU General Public License as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it would be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# Further, this software is distributed without any warranty that it is
# free of the rightful claim of any third person regarding infringement
# or the like.  Any license provided herein, whether implied or
# otherwise, applies only to this software file.  Patent licenses, if
# any, provided herein do not apply to combinations of this program with
# other software, or any other product whatsoever.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write the Free Software Foundation,
# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
#

. /usr/lib/ha-cluster-functions

declare SEED_HOST
declare HOST_STATUS
declare HOST

usage()
{
	cat <<END
Usage: $0 [options] 

Options:
    -c <host>   IP address or hostname of cluster node which will be deleted
    -h,--help   Display this usage information
    -q          Be quiet (don't describe what's happening, just do it)
    -y          Answer "yes" to all prompts (use with care)

END
	exit 0
}

prompt()
{
	local msg=$1
	local default
	local tmp

	while [ -z "$default" ]; do
		read -e -p "  $msg " tmp
		[ -n "$tmp" ] && default=$tmp
	done

	echo $default
}

remove_ssh()
{
	[ -n "$SEED_HOST" ] || error "No existing IP/hostname specified (use -c option)"

	#check whether corosync has been started on local node
	systemctl -q is-active corosync.service
	local rc=$?
	[ $rc -ne 0 ] && error "Cluster is not active - can't execute removing action"

	remove_get_hostname
}

remove_get_hostname()
{
	#get the node name
	local nodename=`ssh root@$SEED_HOST "hostname" 2>/dev/null`
	if [ -z $nodename ]; then
		#0==disconnected 1==connected 2==connected through ipaddr
		HOST_STATUS=0

		echo $SEED_HOST |grep -E '^([0-9]+\.){3}[0-9]+$' >/dev/null
		local rc=$?
		if [ $rc -eq 0 ]; then
			#input the HOSTNAME
			warn "Could not connect to $SEED_HOST"
			nodename=$(prompt 'Please enter the hostname of the node to be removed : ' )
			[ -z "$nodename" ] && error 'Not input valid hostname'

			crm_node --list |grep -w $nodename >/dev/null
			[ $? -ne 0 ] && error "Specified node $nodename is \
									    			not configured in cluster, can not execute removing action"

			#try to use the host name to connect
			local node=`ssh root@$nodename "hostname" 2>/dev/null`
			if [ -n "$node" ]; then
				nodename=$node
				HOST_STATUS=1
				HOST=$nodename
			else
				HOST_STATUS=0
			fi
		else
			crm_node --list |grep -w $SEED_HOST >/dev/null
			[ $? -ne 0 ] && error "Specified node $SEED_HOST is \
														not configured in cluster, can not execute removing action"

			warn "Could not resolve hostname $SEED_HOST"
			ipaddr=$(prompt 'Please enter the IP address of the node to be removed (e.g: 192.168.0.1): ')
			[ -z "$ipaddr" ] && error 'Not input valid IP address'

			#try to use the IP address to connect
			nodename=`ssh root@$ipaddr "hostname" 2>/dev/null`
			if [ -z $nodename ] ; then
				HOST_STATUS=0;
				nodename=$SEED_HOST
			else
				if [ $nodename != $SEED_HOST ]; then
					warn "Specified IP address $ipaddr is node $nodename, not configured in cluster "
					warn "Try to remove node $SEED_HOST "
					nodename=$SEED_HOST
					HOST_STATUS=0;
				else
					HOST_STATUS=2;
					HOST=$ipaddr
				fi
			fi
		fi
	else
		HOST_STATUS=1
		HOST=$SEED_HOST
	fi

	SEED_HOST=$nodename
}

remove_cluster()
{
	if [ $HOST_STATUS -ne 0 ]; then
		status "Stopping the corosync service"
	
		invoke ssh root@$HOST "systemctl stop corosync" \
			|| error "stop the service corosync on $SEED_HOST failed"

		#delete the configure file from the node $SEED_HOST
		invoke ssh root@$HOST "bash -c \"rm -f $SYSCONFIG_SBD $CSYNC2_CFG \
				$COROSYNC_CONF $CSYNC2_KEY \
				&& rm -f /var/lib/heartbeat/crm/* /var/lib/pacemaker/cib/*\"" \
				|| error "Delete the configure files failed"
	else
		#check node status
		invoke crm_node --list |grep -w $SEED_HOST |grep "lost"
		if [ $? -ne 0 ]; then
						confirm 'The node has not been cleaned up... - remove it?' || return
		fi
	fi

	#execute the command : crm node delete $HOSTNAME
	status "Removing the node $SEED_HOST"
	
	invoke crm node delete $SEED_HOST
	local rc=$?
	# 0 == success
	[ $rc -ne 0 ] && error "Can not remove the node $SEED_HOST"
	
	#delete the line include the $SEED_HOST
	invoke sed -i /$SEED_HOST/d $CSYNC2_CFG \
		|| error "remove the node $SEED_HOST from file $CSYNC2_CFG failed"

	status "Propagating the files across the surviving nodes"
	# csync the file to all the node
	# `csync2 -R` is needed to remove old records from the database
	# for the host that's now gone.
	invoke csync2 -R && invoke csync2 -m $CSYNC2_CFG && invoke csync2 -f $CSYNC2_CFG && invoke csync2 -xv >/dev/null 2>&1 || error "Propagate the file $CYNC2_CFG failed"

	# Decrement expected_votes in corosync.conf
	# TODO(must): this is rather fragile (see related code in ha-cluster-join)
	local tmp_conf=${COROSYNC_CONF}.$$
	local new_quorum=$(awk -F[^0-9] '/^[[:space:]]*expected_votes/ { print $NF - 1 };' $COROSYNC_CONF)
	local two_node=0
	[ $new_quorum -eq 2 ] && two_node=1
	sed \
		-e 's/^\([[:space:]]*expected_votes:[[:space:]]*\).*/\1'$new_quorum'/' \
		-e 's/^\([[:space:]]*two_node:[[:space:]]*\).*/\1'$two_node'/' \
		$COROSYNC_CONF > $tmp_conf
	install_tmp $tmp_conf $COROSYNC_CONF
	invoke csync2 -m $COROSYNC_CONF
	invoke csync2 -f $COROSYNC_CONF
	invoke csync2 -xv $COROSYNC_CONF

	# Trigger corosync config reload to ensure expected_votes is propagated
	invoke corosync-cfgtool -R
}

remove_hostname_check()
{
	#check whether the specified node is exist at the cluster
	crm_node --list |grep -w $SEED_HOST >/dev/null
	local rc=$?
	if [ $rc -ne 0 ]; then
		error "Specified node $SEED_HOST is \
			not configured in cluster, can not execute removing action"
	fi

	#check whether the specified node is local node
	rc=`hostname`
	if [ "$rc" == "$SEED_HOST" ]; then
		error "Specified node $SEED_HOST is local host, \
			can note execute removing action on local host"
	fi
}
#------------------------------------------------------------------------------

# for --help option
[ "$1" == "--help" ] && usage

while getopts 'c:hqy' o; do
	case $o in
	c) SEED_HOST=$OPTARG;;
	h) usage;;
	q) BE_QUIET=true;;
	y) YES_TO_ALL=true;;
	*) usage;;
	esac
done

[ $OPTIND -eq 1 ] && usage

[ -n "$SEED_HOST" ] || _die "No existing IP/hostname specified (use -c option)"

init
remove_ssh
remove_hostname_check
remove_cluster

status "Done (log saved to $LOG_FILE)"
exit 0
