402 lines
12 KiB
Bash
402 lines
12 KiB
Bash
#!/bin/bash
|
|
|
|
if [ `id -u` -ne 0 ];then
|
|
echo "only a user with the root permission can run this script."
|
|
exit 1
|
|
fi
|
|
|
|
declare -r SCRIPT_PATH=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd)
|
|
declare -r SCRIPT_NAME=$0
|
|
echo "SCRIPT_PATH : ${SCRIPT_PATH}"
|
|
declare PACKAGE_PATH=`dirname ${SCRIPT_PATH}`
|
|
declare USER_NAME=""
|
|
declare HOST_IPS=""
|
|
declare HOST_IPS_ARR=""
|
|
declare HOST_IPS_ARRAY=""
|
|
declare HOST_NAMES=""
|
|
declare HOST_NAMES_ARRAY=
|
|
declare USER_GROUP="dbgrp"
|
|
declare PORT="20050"
|
|
declare XML_DIR=${SCRIPT_PATH}/one_master_one_slave_template.xml
|
|
declare INSTALL_PATH=""
|
|
declare SYSTEM_ARCH=""
|
|
declare SYSTEM_NAME=""
|
|
declare PASSWORD=""
|
|
|
|
function print_help()
|
|
{
|
|
echo "Usage: $0 [OPTION]
|
|
-?|--help show help information
|
|
-U|--user_name cluster user
|
|
-H|--host_ip intranet ip address of the host in the backend storage network(host1,host2)
|
|
-G|--user_grp group of the cluster user(default value dbgrp)
|
|
-p|--port database server port(default value 20050)
|
|
-D|--install_location installation directory of the openGauss program(default value ~/cluser)
|
|
-X|--xml_location cluster xml configuration file path
|
|
"
|
|
}
|
|
|
|
function die()
|
|
{
|
|
echo -e "\033[31merror:\033[0m $1"
|
|
exit 1
|
|
}
|
|
|
|
function warn()
|
|
{
|
|
echo -e "\033[33mwarnning:\033[0m $1"
|
|
sleep 2s
|
|
}
|
|
|
|
function info()
|
|
{
|
|
echo -e "\033[32minfo:\033[0m $1"
|
|
}
|
|
|
|
function expect_ssh()
|
|
{
|
|
/usr/bin/expect <<-EOF
|
|
set timeout -1
|
|
spawn $1
|
|
expect {
|
|
"*yes/no" { send "yes\r"; exp_continue }
|
|
"*assword:" { send "$2\r"; exp_continue }
|
|
"*$3*" { exit }
|
|
}
|
|
expect eof
|
|
EOF
|
|
if [ $? == 0 ]
|
|
then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
function expect_hostname()
|
|
{
|
|
expect <<EOF > expectFile
|
|
set timeout -1
|
|
spawn $1
|
|
expect {
|
|
"*yes/no" { send "yes\r"; exp_continue }
|
|
"*assword:" {send "$2\r"; exp_continue}
|
|
}
|
|
EOF
|
|
if [ $? == 0 ]
|
|
then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
|
|
function main()
|
|
{
|
|
while [ $# -gt 0 ]
|
|
do
|
|
case "$1" in
|
|
-h|--help)
|
|
print_help
|
|
exit 1
|
|
;;
|
|
-U|--user_name)
|
|
if [ "$2"X = X ]
|
|
then
|
|
die "no cluster user values"
|
|
fi
|
|
USER_NAME=$2
|
|
shift 2
|
|
;;
|
|
-G|--user_grp)
|
|
if [ "$2"X = X ]
|
|
then
|
|
die "no group values"
|
|
fi
|
|
USER_GROUP=$2
|
|
shift 2
|
|
;;
|
|
-H|--host_ip)
|
|
if [ "$2"X = X ]
|
|
then
|
|
die "no intranet ip address of the host values"
|
|
fi
|
|
HOST_IPS=$2
|
|
shift 2
|
|
HOST_IPS_ARR=${HOST_IPS//,/ }
|
|
HOST_IPS_ARRAY=(${HOST_IPS_ARR})
|
|
if [ ${#HOST_IPS_ARRAY[*]} != 2 ]
|
|
then
|
|
die "the current script can be installed only on two nodes, one active node and one standby node"
|
|
fi
|
|
;;
|
|
-X|--xml_location)
|
|
if [ "$2"X = X ]
|
|
then
|
|
die "no cluster xml configuration file values"
|
|
fi
|
|
XML_DIR=$2
|
|
shift 2
|
|
;;
|
|
-D|--install_location)
|
|
if [ "$2"X = X ]
|
|
then
|
|
die "no installation directory of the openGauss program values"
|
|
fi
|
|
INSTALL_PATH=$2
|
|
shift 2
|
|
;;
|
|
-p|--port)
|
|
if [ "$2"X = X ]
|
|
then
|
|
die "the port number cannot be empty."
|
|
fi
|
|
PORT=$2
|
|
shift 2
|
|
;;
|
|
-P|--password)
|
|
if [ "$2"X = X ]
|
|
then
|
|
die "the password cannot be empty."
|
|
fi
|
|
PASSWORD=$2
|
|
shift 2
|
|
;;
|
|
*)
|
|
echo "Internal Error: option processing error" 1>&2
|
|
echo "please input right paramtenter, the following command may help you"
|
|
echo "sh active_standby_nodes_install.sh --help or sh active_standby_nodes_install.sh -h"
|
|
exit 1
|
|
esac
|
|
done
|
|
|
|
if [ "${USER_NAME}"X == X ]
|
|
then
|
|
die "no cluster user values"
|
|
fi
|
|
|
|
if [ -z ${INSTALL_PATH} ]
|
|
then
|
|
INSTALL_PATH="/home/${USER_NAME}"
|
|
fi
|
|
|
|
if [ "${PASSWORD}"X == X ]
|
|
then
|
|
echo "please enter the password of the root user&the password of a common user(the two passwords must be the same)"
|
|
echo -n "password:"
|
|
read PASSWORD
|
|
while [ -z ${PASSWORD} ]
|
|
do
|
|
echo "the value cannot be null, please enter the password again"
|
|
echo -n "password:"
|
|
read PASSWORD
|
|
done
|
|
fi
|
|
|
|
if [ "${HOST_IPS}"X == X ]
|
|
then
|
|
die "no intranet ip address values"
|
|
else
|
|
len=${#HOST_IPS_ARRAY[*]}
|
|
index=0
|
|
while [ ${index} -lt ${len} ]
|
|
do
|
|
expect_hostname "ssh ${HOST_IPS_ARRAY[${index}]} hostname" ${PASSWORD}
|
|
if [ $? == 0 ]
|
|
then
|
|
expectResult=`tail -1 expectFile|head -1| tr -d "\r"| tr -d "\n"`
|
|
if [ -z ${expectResult} ]
|
|
then
|
|
die "failed to obtain the hostname based on the ip address of ${HOST_IPS_ARRAY[${index}]}."
|
|
fi
|
|
HOST_NAMES_ARRAY[${index}]=${expectResult}
|
|
else
|
|
die "failed to obtain the hostname based on the ip address of ${HOST_IPS_ARRAY[${index}]}."
|
|
fi
|
|
index=$[ ${index} + 1 ]
|
|
done
|
|
fi
|
|
rm -rf expectFile
|
|
HOST_NAMES="${HOST_NAMES_ARRAY[0]},${HOST_NAMES_ARRAY[1]}"
|
|
SYSTEM_ARCH=`uname -m`
|
|
SYSTEM_NAME=`cat /etc/*-release | grep '^ID=".*'|awk -F "[=\"]" '{print $3}'`
|
|
if [ "${SYSTEM_NAME}" == "openEuler" ] && [ "${SYSTEM_ARCH}" == "aarch64" ]
|
|
then
|
|
info "the current system environment is openEuler + arm"
|
|
elif [ "${SYSTEM_NAME}" == "openEuler" ] && [ "${SYSTEM_ARCH}" == "x86_64" ]
|
|
then
|
|
info "the current system environment is openEuler + x86"
|
|
elif [ "${SYSTEM_NAME}" == "centos" ] && [ "${SYSTEM_ARCH}" == "x86_64" ]
|
|
then
|
|
info "the current system environment is CentOS + x86"
|
|
elif [ "${SYSTEM_NAME}" == "redhat" ] && [ "${SYSTEM_ARCH}" == "x86_64" ]
|
|
then
|
|
info "the current system environment is redhat + x86"
|
|
elif [ "${SYSTEM_NAME}" == "redhat" ] && [ "${SYSTEM_ARCH}" == "aarch64" ]
|
|
then
|
|
info "the current system environment is redhat + arm"
|
|
elif [ "${SYSTEM_NAME}" == "kylin" ] && [ "${SYSTEM_ARCH}" == "x86_64" ]
|
|
then
|
|
info "the current system environment is kylin + x86"
|
|
elif [ "${SYSTEM_NAME}" == "kylin" ] && [ "${SYSTEM_ARCH}" == "aarch64" ]
|
|
then
|
|
info "the current system environment is kylin + arm"
|
|
else
|
|
warn "the current system environment is ${SYSTEM_NAME} + ${SYSTEM_ARCH}, \
|
|
you are advised to use the centos, openEuler, redhat, or kylin system. because OpenGauss may not adapt to the current system."
|
|
fi
|
|
info "installation parameter verification completed."
|
|
}
|
|
|
|
function checks()
|
|
{
|
|
system_arch=`uname -m`
|
|
system_name=`cat /etc/*-release | grep '^ID=".*'|awk -F "[=\"]" '{print $3}'`
|
|
if [ ${system_arch} != "$8" -o ${system_name} != "$9" ]
|
|
then
|
|
warn "inconsistency between the system and the execution machine"
|
|
fi
|
|
|
|
egrep "^$3" /etc/group >& /dev/null
|
|
if [ $? != 0 ];then
|
|
groupadd $3
|
|
fi
|
|
egrep "^$4" /etc/passwd >& /dev/null
|
|
if [ $? != 0 ];then
|
|
useradd -g $3 -d /home/$4 -m -s /bin/bash $4 2>/dev/null
|
|
if [ $? != 0 ]
|
|
then
|
|
die "failed to create the user on the node $2."
|
|
fi
|
|
expect_ssh "passwd $4" "$5" "passwd:"
|
|
if [ $? != 0 ]
|
|
then
|
|
die "an error occurred when setting the user password on the node $2"
|
|
fi
|
|
fi
|
|
|
|
sed -i "s/SELINUX=.*/SELINUX=disabled/g" /etc/selinux/config && firewall-cmd --permanent --add-port="$6/tcp" && firewall-cmd --reload
|
|
if [ $? != 0 ]
|
|
then
|
|
warn "some errors occur during system environment setting on host $2"
|
|
fi
|
|
|
|
umask 0022
|
|
INSTALL_PATH=$7
|
|
if [ ! -e ${INSTALL_PATH} ]
|
|
then
|
|
mkdir -p ${INSTALL_PATH}
|
|
else
|
|
rm -rf ${INSTALL_PATH}/*
|
|
fi
|
|
chmod -R 755 ${INSTALL_PATH}/
|
|
chown -R $4:$3 ${INSTALL_PATH}/
|
|
if [ -f /${10} ]
|
|
then
|
|
mv /${10} $(eval echo ~$4)/
|
|
fi
|
|
echo "check end"
|
|
}
|
|
|
|
function pre_checks()
|
|
{
|
|
if [ ${#HOST_IPS_ARRAY[*]} == 0 ]
|
|
then
|
|
die "the number of internal IP addresses of the host is incorrect."
|
|
fi
|
|
localips=`/sbin/ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v inet6|awk '{print $2}'|tr -d "addr:"`
|
|
for ip in ${HOST_IPS_ARRAY[@]}
|
|
do
|
|
info "start to check the installation environment of host ${ip}."
|
|
sleep 2s
|
|
# standby node
|
|
if [[ $localips != *${ip}* ]]
|
|
then
|
|
sshcmd="scp ${SCRIPT_PATH}/${SCRIPT_NAME} root@${ip}:/"
|
|
expect_ssh "${sshcmd}" "${PASSWORD}" "100%"
|
|
if [ $? != 0 ]
|
|
then
|
|
die "an error occurred when copying the script to the target host ${ip}."
|
|
fi
|
|
sshcmd="ssh ${ip} \"sh /${SCRIPT_NAME} inner ${ip} ${USER_GROUP} ${USER_NAME} ${PASSWORD} ${PORT} ${INSTALL_PATH} ${SYSTEM_ARCH} ${SYSTEM_NAME} ${SCRIPT_NAME}\""
|
|
expect_ssh "${sshcmd}" "${PASSWORD}" "check end"
|
|
if [ $? != 0 ]
|
|
then
|
|
die "an error occurred during the pre-installation check on the target host ${ip}."
|
|
fi
|
|
else
|
|
# local
|
|
checks "" ${ip} ${USER_GROUP} ${USER_NAME} ${PASSWORD} ${PORT} ${INSTALL_PATH} ${SYSTEM_ARCH} ${SYSTEM_NAME} ${SCRIPT_NAME}
|
|
if [ $? != 0 ]
|
|
then
|
|
die "an error occurred during the pre-installation check on the target host ${ip}."
|
|
fi
|
|
fi
|
|
info "succeeded in checking the installation environment of host ${ip}."
|
|
done
|
|
return 0
|
|
}
|
|
|
|
function xmlconfig()
|
|
{
|
|
info "start to automatically configure the installation file."
|
|
install_localtion=${INSTALL_PATH//\//\\\/}
|
|
if [ -e ${XML_DIR} ]
|
|
then
|
|
sed 's/@{nodeNames}/'${HOST_NAMES}'/g' ${XML_DIR} |
|
|
sed 's/@{backIpls}/'${HOST_IPS}'/g' |
|
|
sed 's/@{clusterName}/'${USER_NAME}'/g' |
|
|
sed 's/@{port}/'${PORT}'/g' |
|
|
sed 's/@{installPath}/'${install_localtion}'/g' |
|
|
sed 's/@{nodeName1}/'${HOST_NAMES_ARRAY[0]}'/g' |
|
|
sed 's/@{backIp1}/'${HOST_IPS_ARRAY[0]}'/g' |
|
|
sed 's/@{nodeName2}/'${HOST_NAMES_ARRAY[1]}'/g' |
|
|
sed 's/@{backIp2}/'${HOST_IPS_ARRAY[1]}'/g' > $(eval echo ~${USER_NAME})/one_master_one_slave.xml
|
|
else
|
|
die "cannot find one_master_one_slave_template.xml in ${XML_DIR}"
|
|
fi
|
|
cat $(eval echo ~${USER_NAME})/one_master_one_slave.xml
|
|
info "the installation file is automatically configured"
|
|
return 0
|
|
}
|
|
|
|
function install()
|
|
{
|
|
info "preparing for preinstallation"
|
|
home_path=$(eval echo ~${USER_NAME})
|
|
export LD_LIBRARY_PATH="${PACKAGE_PATH}/script/gspylib/clib:"$LD_LIBRARY_PATH
|
|
sshcmd="python3 "${PACKAGE_PATH}"/script/gs_preinstall -U "${USER_NAME}" \
|
|
-G "${USER_GROUP}" -X "${home_path}"/one_master_one_slave.xml --sep-env-file="${home_path}"/env_master_slave"
|
|
info "cmd \"${sshcmd}\""
|
|
expect_ssh "${sshcmd}" "${PASSWORD}" "Preinstallation succeeded"
|
|
if [ $? != 0 ]
|
|
then
|
|
die "preinstall failed."
|
|
fi
|
|
info "preinstallation succeeded."
|
|
chmod 755 ${home_path}'/one_master_one_slave.xml'
|
|
chown ${USER_NAME}:${USER_GROUP} ${home_path}'/one_master_one_slave.xml'
|
|
info "start the installation."
|
|
su - ${USER_NAME} -c"source ${home_path}/env_master_slave;gs_install -X ${home_path}/one_master_one_slave.xml;gs_om -t status --detail"
|
|
if [ $? -ne 0 ]
|
|
then
|
|
die "install failed."
|
|
else
|
|
info "install success."
|
|
fi
|
|
exit 0
|
|
}
|
|
|
|
if [ $1 == "inner" ]
|
|
then
|
|
checks $@
|
|
else
|
|
main $@
|
|
pre_checks
|
|
xmlconfig
|
|
install
|
|
fi
|
|
exit 0
|
|
|