1243 lines
38 KiB
Bash
1243 lines
38 KiB
Bash
#!/bin/bash
|
|
# -*- coding:utf-8 -*-
|
|
#############################################################################
|
|
# Copyright (c): 2021, Huawei Tech. Co., Ltd.
|
|
# FileName : install.sh
|
|
# Version : V1.0.0
|
|
# Date : 2021-04-17
|
|
# Description : the script used to install the single cluster on one machine
|
|
#########################################
|
|
function check_passwd()
|
|
{
|
|
passwd=$1
|
|
local -i num=0
|
|
if [ -n "$(echo $passwd | grep -E --color '^(.*[a-z]+).*$')" ]
|
|
then
|
|
num=$[ ${num} + 1 ]
|
|
fi
|
|
if [ -n "$(echo $passwd | grep -E --color '^(.*[A-Z]).*$')" ]
|
|
then
|
|
num=$[ ${num} + 1 ]
|
|
fi
|
|
password_sepcical_char=('~' '!' '@' '#' '$' '%' '^' '&' '(' ')' '_' '-' '*'
|
|
'+' '=' '{' '[' ']' '}' '|' '\' ':' ';' '"' ',' "'" '.' '<' '.' '?' '/')
|
|
for element in ${password_sepcical_char[@]}
|
|
do
|
|
compare_str="${element}"
|
|
if [[ "${passwd}" =~ "${compare_str}" ]]
|
|
then
|
|
num=$[ ${num} + 1 ]
|
|
break
|
|
fi
|
|
done
|
|
|
|
if [ -n "$(echo $passwd | grep -E --color '^(.*[0-9]).*$')" ]
|
|
then
|
|
num=$[ ${num} + 1 ]
|
|
fi
|
|
if [ ${#passwd} -lt 8 ] || [ $num -lt 3 ] || [ ${#passwd} -gt 32 ]
|
|
then
|
|
return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
declare password=""
|
|
read -t 1 password
|
|
|
|
if [ "${password}" != "" ]
|
|
then
|
|
check_passwd "${password}"
|
|
if [ $? -ne 0 ]
|
|
then
|
|
echo -e "\033[31mthe password can contain only 8 to 32 characters
|
|
and at least three types of the following characters: uppercase letters, lowercase letters, digits, and special characters..\033[0m"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
declare user=$(whoami)
|
|
if [ X"$user" = X"root" ]; then
|
|
echo "error: can not install gauss with root"
|
|
exit 1
|
|
fi
|
|
|
|
declare root_path=$(cd $(dirname $0);pwd)
|
|
if [ -e "${root_path}/dependency" ]
|
|
then
|
|
export LD_LIBRARY_PATH="${root_path}"/dependency:$LD_LIBRARY_PATH
|
|
fi
|
|
|
|
declare data_path=""
|
|
declare app_path=""
|
|
declare env_file=~/.bashrc
|
|
declare mode_type="single"
|
|
declare -a localips
|
|
declare -a localhosts
|
|
declare -a remoteips
|
|
declare -i port=5432
|
|
declare ssl="off"
|
|
declare init_parameters=""
|
|
declare init_show_parameters=""
|
|
declare config_parameters=""
|
|
declare password_check=""
|
|
declare nodename=""
|
|
declare action="start"
|
|
declare mode="-Z single_node"
|
|
declare -i replconninfo_flag=1
|
|
declare -i install_path_full_flag=1
|
|
declare -i data_full_flag=1
|
|
declare -i start=1
|
|
declare -i ulimit_flag=1
|
|
declare -i interactive_passwd_flag=1
|
|
declare log_path=""
|
|
declare guc_file=""
|
|
declare log_file="${root_path}/install.log"
|
|
declare cert_path=""
|
|
declare client_ip=""
|
|
|
|
|
|
if [ -e "${log_file}" ]
|
|
then
|
|
cat /dev/null > "${log_file}"
|
|
else
|
|
touch "${log_file}"
|
|
fi
|
|
|
|
if [ $? -ne 0 ]
|
|
then
|
|
echo "error: failed to create the log file."
|
|
exit 1
|
|
fi
|
|
|
|
# obtain all IP addresses of the local host.
|
|
declare -i ipindex=0
|
|
for localip in $(/sbin/ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v ::1|awk '{print $2}'| awk -F "addr:" '{print $NF}')
|
|
do
|
|
localips[ipindex]=${localip}
|
|
ipindex=$[ ${ipindex} + 1 ]
|
|
done
|
|
if [ ${#localips[*]} -eq 0 ]
|
|
then
|
|
die "the ip address of the machine is not detected."
|
|
fi
|
|
|
|
function usage()
|
|
{
|
|
echo "
|
|
Usage: $0 [OPTION]
|
|
Arguments:
|
|
-D|--data-path data path
|
|
-R|--app-path app directory
|
|
-P|--gsinit-parameter initializing database parameters
|
|
-C|--dn-guc database configuration parameters
|
|
-m|--mode database installation mode, only three modes are supported: single、primary、and standby, default single
|
|
-l|--log-path global log configuration path
|
|
-f|--guc-file global GUC configuration file
|
|
-n|--nodename node name (the default value is same with mode)
|
|
-h|--help show this help, then exit
|
|
--env-sep-file detach environment variable files
|
|
--start indicates whether to start the cluster.
|
|
--ulimit indicates whether to set the maximum number of open files
|
|
--cert-path SSL certificate path, if this parameter is used, SSL will be on.
|
|
--ssl-client-ip client ip address, the parameter modification takes effect only when the SSL switch is turned on.
|
|
"
|
|
}
|
|
|
|
function info()
|
|
{
|
|
echo "$1" >> "${log_file}"
|
|
echo -e "\033[32minfo:\033[0m$1"
|
|
}
|
|
|
|
function log()
|
|
{
|
|
echo "$1" >> "${log_file}"
|
|
echo "$1"
|
|
}
|
|
|
|
function die()
|
|
{
|
|
echo "$1" >> "${log_file}"
|
|
echo -e "\033[31m$1\033[0m"
|
|
exit 1
|
|
}
|
|
|
|
function warn()
|
|
{
|
|
echo "$1" >> "${log_file}"
|
|
echo -e "\033[33m$1\033[0m"
|
|
}
|
|
|
|
function security_check()
|
|
{
|
|
if [[ "$1" == *[\(\)\{\}\[\]\<\>\`\\\*\!\|\;\&\$\~\?]* ]];then
|
|
die "$1 contain illegal characters."
|
|
fi
|
|
}
|
|
|
|
function path_security_check()
|
|
{
|
|
if [[ "$1" == *[\(\)\{\}\[\]\<\>\`\\\ \*\!\|\;\&\$\~\?]* ]];then
|
|
die "$1 contain illegal characters."
|
|
fi
|
|
}
|
|
|
|
function hide_password()
|
|
{
|
|
tmppassword=""
|
|
stty -echo
|
|
if [ $1 -eq 0 ]
|
|
then
|
|
read -p "please input database password:" password
|
|
else
|
|
read -p "please retry input database password:" password_check
|
|
fi
|
|
stty echo
|
|
}
|
|
|
|
# check if it has read/write/execute permission.
|
|
function check_red_permission()
|
|
{
|
|
if [ ! -r "$1" ]
|
|
then
|
|
die "the user does not have the read permission on the directory/file $1."
|
|
fi
|
|
}
|
|
function check_write_permission()
|
|
{
|
|
if [ ! -w "$1" ]
|
|
then
|
|
die "the user does not have the write permission on the directory/file $1."
|
|
fi
|
|
}
|
|
function check_execute_permission()
|
|
{
|
|
if [ ! -x "$1" ]
|
|
then
|
|
die "the user does not have the execute permission on the directory/file $1."
|
|
fi
|
|
}
|
|
|
|
# check whether the path exists.
|
|
function check_path()
|
|
{
|
|
if echo "$1"|grep -Eq "^/{1,}$"; then
|
|
die "path cannot be / "
|
|
fi
|
|
path_security_check "$1"
|
|
if [ -e "$1" ]
|
|
then
|
|
if [ -f "$1" ]
|
|
then
|
|
die "the path $1 already exists and it is a file."
|
|
fi
|
|
if [[ -n $(ls -A "$1") && "$2" = "install" ]]
|
|
then
|
|
install_path_full_flag=0
|
|
elif [[ -n $(ls -A "$1") && "$2" = "data" ]]
|
|
then
|
|
data_full_flag=0
|
|
fi
|
|
else
|
|
mkdir -p "$1"
|
|
chmod 700 "$1"
|
|
fi
|
|
check_red_permission "$1"
|
|
check_write_permission "$1"
|
|
check_execute_permission "$1"
|
|
}
|
|
|
|
# check whether the IPV4 address is valid.
|
|
function is_valid_ipv4()
|
|
{
|
|
local ip=$1
|
|
local ret=1
|
|
if [[ "$ip" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]
|
|
then
|
|
# use dots (.) to convert the data into an array to facilitate the following judgment.
|
|
ip=(${ip//\./ })
|
|
[[ ${ip[0]} -le 255 && ${ip[1]} -le 255 && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
|
|
ret=$?
|
|
fi
|
|
return $ret
|
|
}
|
|
|
|
# check whether the IPV6 address is valid.
|
|
function is_valid_ipv6()
|
|
{
|
|
parameter_ip=$1
|
|
if [[ "$1" =~ fe80.* ]]
|
|
then
|
|
if [ -z $(echo "$1" | grep %) ]
|
|
then
|
|
die "the local ipv6 address needs to be added with % and the network adapter name(such as fe80*%eth0)."
|
|
fi
|
|
parameter_ip=${parameter_ip%\%*}
|
|
fi
|
|
local ip=${parameter_ip}
|
|
local ret=1
|
|
if [[ "$ip" =~ ([a-f0-9]{1,4}(:[a-f0-9]{1,4}){7}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){0,7}::[a-f0-9]{0,4}(:[a-f0-9]{1,4}){0,7}) ]]
|
|
then
|
|
ret=0
|
|
fi
|
|
return $ret
|
|
}
|
|
|
|
# check whether the local host port is occupied
|
|
# check whether the entered ip address is the same as the ip address of the host
|
|
# identify the ip address of the remote host and add it to the configuration file later.
|
|
function check_conf_paramters()
|
|
{
|
|
replconninfo=$(echo $1 | grep "replconninfo")
|
|
port_flag=$(echo $1 | grep "port")
|
|
if [ "${replconninfo}" != "" ]
|
|
then
|
|
replconninfo_flag=0
|
|
remote_port_flag=$(echo "$1" | grep "remoteport")
|
|
if [ -z "${remote_port_flag}" ]
|
|
then
|
|
die "replconninfo need parameter of 'remoteport'."
|
|
fi
|
|
# prevent repeated port identification and remove remoteport.
|
|
parameter=$(echo "$1" | sed 's/remoteport//g' | sed "s/remoteport//g" | sed "s#'##g" | sed 's#"##g')
|
|
localhost_flag=$(echo "${parameter}" | grep "localhost")
|
|
if [ "${localhost_flag}" = "" ]
|
|
then
|
|
die "replconninfo need parameter of 'localhost.'"
|
|
fi
|
|
remotehost_flag=$(echo "${parameter}" | grep "remotehost")
|
|
if [ "${remotehost_flag}" = "" ]
|
|
then
|
|
die "replconninfo need parameter of 'remotehost'."
|
|
fi
|
|
localport_flag=$(echo "${parameter}" | grep "localport")
|
|
if [ "${localport_flag}" = "" ]
|
|
then
|
|
die "replconninfo need parameter of 'localport'."
|
|
fi
|
|
|
|
# init parameters
|
|
parameter=$(echo "$1" | sed "s/remoteport//g" | sed "s#'##g" | sed 's#"##g')
|
|
parameter_array=(${parameter//=/ })
|
|
len=${#parameter_array[*]}
|
|
if [[ "${localhost_flag}" != "" || "${localport_flag}" != "" || "${remote_port_flag}" != "" || "${remotehost_flag}" != "" ]]
|
|
then
|
|
index=0
|
|
while [ ${index} -lt $[ ${len} + 1 ] ]
|
|
do
|
|
key=${parameter_array[${index}]}
|
|
if [ "${key}" = "localhost" ]
|
|
then
|
|
index=$[ ${index} + 1 ]
|
|
value=${parameter_array[${index}]}
|
|
check_value=${value}
|
|
is_valid_ipv4 "$value"
|
|
if [ $? -ne 0 ]
|
|
then
|
|
is_valid_ipv6 "$value"
|
|
if [ $? -ne 0 ]
|
|
then
|
|
is_valid_ipv6 "$value"
|
|
die "the local ip address ${value} is not standard."
|
|
fi
|
|
if [[ "$value" =~ fe80.* ]]
|
|
then
|
|
check_value=${check_value%\%*}
|
|
fi
|
|
fi
|
|
res=$(echo "${localips[@]}" | grep -wq "${check_value}" && echo "yes" || echo "no")
|
|
if [ "${res}" = "no" ]
|
|
then
|
|
die "the ip address of the network adapter is inconsistent with that of the host ${value}"
|
|
else
|
|
res=$(echo "${localhosts[@]}" | grep -wq "${check_value}" && echo "yes" || echo "no")
|
|
if [ "${res}" = "no" ]
|
|
then
|
|
localhostscount=${#localhosts[*]}
|
|
localhosts[localhostscount]=${value}
|
|
fi
|
|
fi
|
|
elif [ "${key}" = "remotehost" ]
|
|
then
|
|
index=$[ ${index} + 1 ]
|
|
value=${parameter_array[${index}]}
|
|
is_valid_ipv4 "$value"
|
|
if [ $? -ne 0 ]
|
|
then
|
|
is_valid_ipv6 "$value"
|
|
if [ $? -ne 0 ]
|
|
then
|
|
die "the remote ip address ${value} is not standard."
|
|
fi
|
|
fi
|
|
res=$(echo "${remoteips[@]}" | grep -wq "${value}" && echo "yes" || echo "no")
|
|
if [ "${res}" = "no" ]
|
|
then
|
|
remoteipcount=${#remoteips[*]}
|
|
remoteips[remoteipcount]=${value}
|
|
fi
|
|
elif [ "${key}" = "localport" ]
|
|
then
|
|
index=$[ ${index} + 1 ]
|
|
value=${parameter_array[${index}]}
|
|
if [[ ${value} -lt 1024 || ${value} -gt 65535 ]]
|
|
then
|
|
die "the port number must be between 1024 and 65535."
|
|
fi
|
|
netstat | grep "${value}"
|
|
if [ $? -eq 0 ]
|
|
then
|
|
die "the port ${value} is already in use"
|
|
fi
|
|
elif [ "${key}" = "remoteport" ]
|
|
then
|
|
index=$[ ${index} + 1 ]
|
|
value=${parameter_array[${index}]}
|
|
if [[ ${value} -lt 1024 || ${value} -gt 65535 ]]
|
|
then
|
|
die "the port number must be between 1024 and 65535."
|
|
fi
|
|
netstat | grep "${value}"
|
|
if [ $? -eq 0 ]
|
|
then
|
|
die "the port ${value} is already in use"
|
|
fi
|
|
fi
|
|
index=$[ ${index} + 1 ]
|
|
done
|
|
fi
|
|
elif [ "${port_flag}" != "" ]
|
|
then
|
|
parameter=$1
|
|
parameter_array=(${parameter//=/ })
|
|
|
|
if [ ${#parameter_array[*]} -eq 2 ]
|
|
then
|
|
value=${parameter_array[1]}
|
|
if [[ ${value} -lt 1024 || ${value} -gt 65535 ]]
|
|
then
|
|
die "the port number must be between 1024 and 65535."
|
|
fi
|
|
netstat | grep "${value}"
|
|
if [ $? -eq 0 ]
|
|
then
|
|
die "the port ${value} is already in use"
|
|
fi
|
|
port=${value}
|
|
fi
|
|
fi
|
|
config_parameters="${config_parameters} -c \"$1\""
|
|
}
|
|
|
|
# check whether the database password is normal and empty.
|
|
function check_init_paramters()
|
|
{
|
|
parameter=$(echo "$1" | sed "s#'##g" | sed 's#"##g')
|
|
interactive_passwd=$(echo "${parameter}" | grep "\-W")
|
|
if [ "${interactive_passwd}" != "" ]
|
|
then
|
|
interactive_passwd_flag=0
|
|
fi
|
|
passwd_flag=$(echo "${parameter}" | grep -E "\-w\s+|\-\-pwpasswd=")
|
|
if [ "${passwd_flag}" != "" ]
|
|
then
|
|
pwpasswd_flag=$(echo "${parameter}" | grep -E "\-\-pwpasswd=")
|
|
if [ "${pwpasswd_flag}" != "" ]
|
|
then
|
|
parameter=$(echo "${parameter}" | sed "s/--pwpasswd=/--pwpasswd /g")
|
|
fi
|
|
parameter_array=(${parameter// / })
|
|
len=${#parameter_array[*]}
|
|
index=0
|
|
while [ ${index} -lt $[ ${len} + 1 ] ]
|
|
do
|
|
key=${parameter_array[${index}]}
|
|
if [[ "${key}" = "-w" || "${key}" = "--pwpasswd" ]]
|
|
then
|
|
index=$[ ${index} + 1 ]
|
|
password=${parameter_array[${index}]}
|
|
check_passwd $password
|
|
if [ $? -ne 0 ]
|
|
then
|
|
die "the password can contain only 8 to 32 characters
|
|
and at least three types of the following characters: uppercase letters, lowercase letters, digits, and special characters."
|
|
fi
|
|
fi
|
|
index=$[ ${index} + 1 ]
|
|
done
|
|
init_show_parameters="${init_show_parameters} ""-w ******"
|
|
else
|
|
init_show_parameters="${init_show_parameters} "$1
|
|
fi
|
|
init_parameters="${init_parameters} "$1
|
|
}
|
|
|
|
function check_os()
|
|
{
|
|
if [ ${ulimit_flag} -eq 0 ]
|
|
then
|
|
ulimit -SHn 1000000
|
|
if [ $? -ne 0 ]
|
|
then
|
|
echo "error: failed to set the maximum number of open files, an exception occurs when the ulimit -SHn 1000000 command is executed.."
|
|
exit 1
|
|
fi
|
|
sed -i "/.*ulimit\\s*-SHn/d" ${env_file}
|
|
echo "ulimit -SHn 1000000" >> ${env_file}
|
|
fi
|
|
# check shm
|
|
local shared_buffers=1073741824 # 1G
|
|
local shmmax=$(cat /proc/sys/kernel/shmmax)
|
|
env test ${shared_buffers} -gt ${shmmax} && echo "shared_buffers(1073741824) must be less than shmmax($shmmax), Please check it (vim /proc/sys/kernel/shmmax)." && exit 1
|
|
local shmall=$(cat /proc/sys/kernel/shmall)
|
|
local pagesize=$(getconf PAGESIZE)
|
|
|
|
if [ $((${shmall}/1024/1024/1024*${pagesize})) -ne 0 ]; then
|
|
if [ $((${shared_buffers}/1024/1024/1024-${shmall}/1024/1024/1024*${pagesize})) -gt 0 ]; then
|
|
die "the usage of the device [Shared_buffers] space(1073741824) cannot be greater than shmall*PAGESIZE($shmall*$pagesize), Please check it (vim /proc/sys/kernel/shmmall)."
|
|
fi
|
|
fi
|
|
# check sem
|
|
local -a sem
|
|
local -i index=0
|
|
local max_connection=5000
|
|
local conn_floor
|
|
for line in $(cat /proc/sys/kernel/sem)
|
|
do
|
|
sem[index]=${line}
|
|
index=$[ ${index} + 1 ]
|
|
done
|
|
if [ ${sem[0]} -lt 17 ]
|
|
then
|
|
die "the maximum number of SEMMSL is not correct, please change it (/proc/sys/kernel/sem)), ensure that the value of first sem is greater than 17."
|
|
fi
|
|
let conn_floor=(${max_connection}+150)/16
|
|
if [ ${sem[3]} -lt ${conn_floor} ]
|
|
then
|
|
die "the maximum number of SEMMNI is not correct, please change it (/proc/sys/kernel/sem)), ensure that the value of fourth sem is greater than 320."
|
|
fi
|
|
|
|
let conn_floor=${conn_floor}*17
|
|
if [ ${sem[1]} -lt ${conn_floor} ]
|
|
then
|
|
die "the maximum number of SEMMNS is not correct, please change it (/proc/sys/kernel/sem)), ensure that the value of second sem is greater than 5500."
|
|
fi
|
|
info "[check install env and os setting success.]"
|
|
}
|
|
|
|
function check()
|
|
{
|
|
if [[ "${mode_type}" != "single" && ""${replconninfo_flag} -ne 0 ]]
|
|
then
|
|
die "the parameter -C|--dn-guc["replconninfo='value'"] can not be empty."
|
|
fi
|
|
}
|
|
|
|
function decompress()
|
|
{
|
|
cd $root_path
|
|
# get OS distributed version.
|
|
kernel=""
|
|
if [ -f "/etc/euleros-release" ]
|
|
then
|
|
kernel=$(cat /etc/euleros-release | awk -F ' ' '{print $1}' | tr a-z A-Z)
|
|
if [ "${kernel}" = "EULEROS" ]
|
|
then
|
|
kernel="EULER"
|
|
fi
|
|
elif [ -f "/etc/openEuler-release" ]
|
|
then
|
|
kernel=$(cat /etc/openEuler-release | awk -F ' ' '{print $1}')
|
|
elif [ -f "/etc/centos-release" ]
|
|
then
|
|
kernel=$(cat /etc/centos-release | awk -F ' ' '{print $1}')
|
|
else
|
|
kernel=$(lsb_release -d | awk -F ' ' '{print $2}')
|
|
fi
|
|
log "kernel: ${kernel}"
|
|
|
|
# detect platform information.
|
|
platform=32
|
|
bit=$(getconf LONG_BIT)
|
|
if [ "$bit" -eq 64 ]
|
|
then
|
|
platform=64
|
|
fi
|
|
platform_arch=$(uname -p)
|
|
bin_name="openGauss-Lite.*-${kernel}-${platform_arch}"
|
|
bin_res=$(ls -a | grep -E "${bin_name}.bin")
|
|
if [ "${bin_res}" = "" ]
|
|
then
|
|
die "can not find suitable bin file, expected bin file is ${bin_name}.bin"
|
|
fi
|
|
log "bin file: ${bin_res}"
|
|
|
|
bin_name=$(echo "$bin_res" | sed 's/.bin//g')
|
|
sha_res=$(ls -a | grep -E "${bin_name}.sha256")
|
|
if [ "${sha_res}" = "" ]
|
|
then
|
|
die "can not find suitable verification file, expected bin file is ${bin_name}.sha256"
|
|
fi
|
|
log "verification file: ${sha_res}"
|
|
sha256sum "${bin_name}.bin" | awk -F" " '{print $1}' > "${bin_name}-check.sha256"
|
|
if [ $? -ne 0 ]
|
|
then
|
|
die "check integrality of bin file failed"
|
|
fi
|
|
sha_res=$(sha256sum -t ${bin_name}.sha256 | awk -F" " '{print $1}')
|
|
check_res=$(sha256sum -t ${bin_name}-check.sha256 | awk -F" " '{print $1}')
|
|
if [ "${sha_res}" != "${check_res}" ]
|
|
then
|
|
die "computed checksum did not match"
|
|
fi
|
|
rm -rf "${bin_name}-check.sha256"
|
|
cp ${bin_res} ${app_path} && cp version.cfg ${app_path}
|
|
if [ $? -ne 0 ]
|
|
then
|
|
die "copy binary files *.bin and version.cfg to install path error"
|
|
fi
|
|
cd ${app_path}
|
|
tar -zxf ${bin_name}.bin
|
|
if [ $? -ne 0 ]
|
|
then
|
|
die "decompress binary files (*.bin) error"
|
|
fi
|
|
rm -rf ./*.bin
|
|
}
|
|
|
|
function set_environment()
|
|
{
|
|
if [ "$2" = "app" ]
|
|
then
|
|
# set GAUSSHOME
|
|
sed -i "/.*export\\s*GAUSSHOME=/d" ${env_file}
|
|
echo "export GAUSSHOME=${app_path}" >> ${env_file}
|
|
# set PATH and LD_LIBRARY_PATH
|
|
sed -i "/.*export\\s*PATH=/d" ${env_file}
|
|
echo "export PATH=${app_path}/bin:"'$PATH' >> ${env_file}
|
|
log "export PATH=${app_path}/bin:$PATH >> ${env_file}"
|
|
sed -i "/.*export\\s*LD_LIBRARY_PATH=/d" ${env_file}
|
|
echo "export LD_LIBRARY_PATH=${app_path}/lib:"'$LD_LIBRARY_PATH' >> ${env_file}
|
|
log "export LD_LIBRARY_PATH=${app_path}/lib:$LD_LIBRARY_PATH >> ${env_file}"
|
|
info "[set GAUSSHOME environment variables success.]"
|
|
elif [ "$2" = "data" ]
|
|
then
|
|
# set GAUSSDATA
|
|
sed -i "/.*export\\s*GAUSSDATA=/d" ${env_file}
|
|
echo "export GAUSSDATA=${data_path}" >> ${env_file}
|
|
info "[set GAUSSDATA environment variables success.]"
|
|
elif [ "$2" = "log" ]
|
|
then
|
|
# set GAUSSLOG
|
|
sed -i "/.*export\\s*GAUSSLOG=/d" ${env_file}
|
|
echo "export GAUSSLOG=${log_path}" >> ${env_file}
|
|
info "[set GAUSSLOG environment variables success.]"
|
|
fi
|
|
}
|
|
|
|
function init_db()
|
|
{
|
|
cd ${app_path}/bin
|
|
if [ ! -e gs_initdb ]
|
|
then
|
|
die "no gauss installation file is found in app-path. check the installation directory."
|
|
fi
|
|
|
|
info "cmd : gs_initdb -D ${data_path} --nodename=${nodename} ${init_show_parameters}"
|
|
./gs_initdb -D ${data_path} --nodename=${nodename} ${init_parameters} | tee -a ${log_file}
|
|
if [ ${PIPESTATUS[0]} -ne 0 ]
|
|
then
|
|
die "[init primary datanode failed.]"
|
|
else
|
|
log "[init primary datanode success.]"
|
|
fi
|
|
}
|
|
|
|
function config_db()
|
|
{
|
|
cd ${app_path}/bin
|
|
if [ ! -e gs_guc ]
|
|
then
|
|
die "no gauss installation file is found in app-path. check the installation directory."
|
|
fi
|
|
cmd="./gs_guc set -D ${data_path} ${config_parameters} -c \"application_name='${nodename}'\" "
|
|
info "cmd : ${cmd}"
|
|
eval ${cmd} | tee -a ${log_file}
|
|
if [ ${PIPESTATUS[0]} -ne 0 ]
|
|
then
|
|
die "config datanode failed, pleae check whether the database is instantiated properly."
|
|
fi
|
|
listen_host_flag=$(echo ${config_parameters} | grep "listen_addresses")
|
|
if [ "${listen_host_flag}" = "" ]
|
|
then
|
|
localhostscount=${#localhosts[*]}
|
|
index=0
|
|
if [ ${localhostscount} -eq 0 ]
|
|
then
|
|
sed -i "/^#listen_addresses/c\listen_addresses = 'localhost,${localips[0]}'" ${data_path}/postgresql.conf
|
|
log "sed -i /^#listen_addresses/c\listen_addresses = 'localhost,${localips[0]}' ${data_path}/postgresql.conf"
|
|
else
|
|
listen_addresses=""
|
|
while [ ${index} -lt ${localhostscount} ]
|
|
do
|
|
listen_addresses="${listen_addresses}"",""${localhosts[${index}]}"
|
|
index=$[ $index + 1 ]
|
|
done
|
|
sed -i "/^#listen_addresses/c\listen_addresses = 'localhost ${listen_addresses}'" ${data_path}/postgresql.conf
|
|
log "sed -i /^#listen_addresses/c\listen_addresses = 'localhost ${listen_addresses}' ${data_path}/postgresql.conf"
|
|
fi
|
|
|
|
fi
|
|
|
|
remote_read_mode_flag=$(echo ${config_parameters} | grep "remote_read_mode")
|
|
if [ "${remote_read_mode_flag}" = "" ]
|
|
then
|
|
sed -i "/.*remote_read_mode = non_authentication/d" ${data_path}/postgresql.conf
|
|
echo "remote_read_mode = non_authentication" | tee -a ${data_path}/postgresql.conf
|
|
log "echo remote_read_mode = non_authentication | tee -a ${data_path}/postgresql.conf"
|
|
fi
|
|
|
|
mask_length=32
|
|
localhostscount=${#localhosts[*]}
|
|
index=0
|
|
if [ ${localhostscount} -eq 0 ]
|
|
then
|
|
is_valid_ipv6 localips[0]
|
|
if [ $? -eq 0 ]
|
|
then
|
|
mask_length=128
|
|
fi
|
|
sed -i "/.*host\\s*all\\s*all\\s*${localips[0]}\/${mask_length}\\s*trust/d" ${data_path}/pg_hba.conf
|
|
echo "host all all ${localips[0]}/${mask_length} trust" | tee -a ${data_path}/pg_hba.conf
|
|
log "echo host all all ${localips[0]}/${mask_length} trust | tee -a ${data_path}/pg_hba.conf"
|
|
else
|
|
while [ ${index} -lt ${localhostscount} ]
|
|
do
|
|
is_valid_ipv6 ${localhosts[${index}]}
|
|
if [ $? -eq 0 ]
|
|
then
|
|
mask_length=128
|
|
else
|
|
mask_length=32
|
|
fi
|
|
sed -i "/.*host\\s*all\\s*${user}\\s*${localhosts[${index}]}\/${mask_length}\\s*trust/d" ${data_path}/pg_hba.conf
|
|
echo "host all ${user} ${localhosts[${index}]}/${mask_length} trust" | tee -a ${data_path}/pg_hba.conf
|
|
log "echo host all ${user} ${localhosts[${index}]}/${mask_length} trust | tee -a ${data_path}/pg_hba.conf"
|
|
index=$[ $index + 1 ]
|
|
done
|
|
fi
|
|
|
|
if [ "${mode_type}" != "single" ]
|
|
then
|
|
remoteipcount=${#remoteips[*]}
|
|
index=0
|
|
while [ ${index} -lt ${remoteipcount} ]
|
|
do
|
|
is_valid_ipv6 ${remoteips[${index}]}
|
|
if [ $? -eq 0 ]
|
|
then
|
|
mask_length=128
|
|
else
|
|
mask_length=32
|
|
fi
|
|
sed -i "/.*host\\s*all\\s*${user}\\s*${remoteips[${index}]}\/${mask_length}\\s*trust/d" ${data_path}/pg_hba.conf
|
|
echo "host all ${user} ${remoteips[${index}]}/${mask_length} trust" | tee -a ${data_path}/pg_hba.conf
|
|
log "echo host all ${user} ${remoteips[${index}]}/${mask_length} trust | tee -a ${data_path}/pg_hba.conf"
|
|
index=$[ $index + 1 ]
|
|
done
|
|
fi
|
|
log "[config datanode success.]"
|
|
}
|
|
|
|
function guc_db()
|
|
{
|
|
cd ${app_path}/bin
|
|
if [ ! -e gs_guc ]
|
|
then
|
|
die "no gauss installation file is found in app-path. check the installation directory."
|
|
fi
|
|
guc_config_parameters=""
|
|
for line in $(cat ${guc_file} | sed '/^$/d')
|
|
do
|
|
guc_config_parameters="${guc_config_parameters}"" -c \"${line}\""
|
|
done
|
|
cmd="./gs_guc set -D ${data_path} ${guc_config_parameters}"
|
|
info "cmd : ${cmd}"
|
|
eval ${cmd} | tee -a ${log_file}
|
|
if [ ${PIPESTATUS[0]} -ne 0 ]
|
|
then
|
|
warn "guc config failed, you need to manually configure the GUC."
|
|
else
|
|
log "guc config success."
|
|
fi
|
|
}
|
|
|
|
function cert_db()
|
|
{
|
|
cd ${app_path}/bin
|
|
if [ ! -e gs_guc ]
|
|
then
|
|
die "no gauss installation file (gs_guc) is found in app-path,
|
|
check whether OpenGauss has been properly installed in the installation directory."
|
|
fi
|
|
for filename in server.crt server.key cacert.pem server.key.cipher server.key.rand
|
|
do
|
|
if ! cp ${cert_path}/${filename} ${data_path} ; then
|
|
die "copy ${cert_path}/${filename} to ${data_path} failed"
|
|
fi
|
|
done
|
|
guc_config_parameters=" -c \"ssl=on\" -c \"ssl_ciphers='ALL'\"
|
|
-c \"ssl_cert_file='server.crt'\" -c \"ssl_key_file='server.key'\"
|
|
-c \"ssl_ca_file='cacert.pem'\" "
|
|
cmd="./gs_guc set -D ${data_path} ${guc_config_parameters}"
|
|
info "the command of guc config is : ${cmd}"
|
|
eval ${cmd} | tee -a ${log_file}
|
|
if [ ${PIPESTATUS[0]} -ne 0 ]
|
|
then
|
|
die "guc config failed, execute cmd ${cmd} failed."
|
|
fi
|
|
|
|
if [ "${client_ip}" != "" ]
|
|
then
|
|
is_valid_ipv4 "${client_ip}"
|
|
if [ $? -ne 0 ]
|
|
then
|
|
is_valid_ipv6 "${client_ip}"
|
|
if [ $? -ne 0 ]
|
|
then
|
|
die "the client ip address ${client_ip} is invalid."
|
|
fi
|
|
fi
|
|
cmd="./gs_guc set -D ${data_path} \"-h hostssl all all ${client_ip}/32 cert\" "
|
|
info "the command of setting client ip is : ${cmd}"
|
|
eval ${cmd} | tee -a ${log_file}
|
|
if [ ${PIPESTATUS[0]} -ne 0 ]
|
|
then
|
|
warn "failed to configure the client IP address."
|
|
fi
|
|
fi
|
|
log "the ssl certificate of the database is configured successfully."
|
|
}
|
|
|
|
function start_db()
|
|
{
|
|
cd ${app_path}/bin
|
|
if [ ! -e gs_ctl ]
|
|
then
|
|
die "no gauss installation file is found in app-path, check the installation directory."
|
|
fi
|
|
info "cmd: gs_ctl ${action} -D ${data_path} ${mode} | tee -a ${log_file}"
|
|
./gs_ctl ${action} -D ${data_path} ${mode} | tee -a ${log_file}
|
|
if [ ${PIPESTATUS[0]} -ne 0 ]
|
|
then
|
|
die "start datanode failed, maybe the database not be properly installed. please refer to install.log for more detailed information."
|
|
else
|
|
log "start datanode success."
|
|
sleep 5s
|
|
eval "gs_ctl query -D ${data_path}"
|
|
fi
|
|
}
|
|
|
|
while [ $# -gt 0 ]
|
|
do
|
|
case "$1" in
|
|
-h|--help)
|
|
usage
|
|
exit 1
|
|
;;
|
|
-m|--mode)
|
|
if [ "$2" = "" ]
|
|
then
|
|
die "the parameter '-m|--mode' cannot be empty."
|
|
fi
|
|
mode_type=$2
|
|
if [[ "${mode_type}" != "single" && "${mode_type}" != "primary" && "${mode_type}" != "standby" ]]
|
|
then
|
|
die "only three modes are supported: single、primary、and standby, default single"
|
|
fi
|
|
shift 2
|
|
;;
|
|
-n|--nodename)
|
|
if [ "$2" = "" ]
|
|
then
|
|
die "the parameter '-n|--name' cannot be empty."
|
|
fi
|
|
security_check "$2"
|
|
nodename=$2
|
|
shift 2
|
|
;;
|
|
-D|--data-path)
|
|
if [ "$2" = "" ]
|
|
then
|
|
die "the parameter '-D|--data-path' cannot be empty."
|
|
fi
|
|
data_path=$2
|
|
if [ ${data_path:0:1} != "/" ]
|
|
then
|
|
data_path="$(pwd)/${data_path}"
|
|
fi
|
|
shift 2
|
|
;;
|
|
-R|--app-path)
|
|
if [ "$2" = "" ]
|
|
then
|
|
die "the parameter '-R|--app-path' cannot be empty."
|
|
fi
|
|
app_path=$2
|
|
if [ ${app_path:0:1} != "/" ]
|
|
then
|
|
app_path="$(pwd)/${app_path}"
|
|
fi
|
|
shift 2
|
|
;;
|
|
-P|--gsinit-parameter)
|
|
if [ "$2" = "" ]
|
|
then
|
|
die "the parameter '-P|--gsinit-parameter' cannot be empty."
|
|
fi
|
|
tmp_parameter=$(echo "$2" | sed "s#'##g" | sed 's#"##g')
|
|
tmp_passwd_flag=$(echo "${tmp_parameter}" | grep -E "\-w\s+|\-\-pwpasswd=")
|
|
if [ "${tmp_passwd_flag}" = "" ]
|
|
then
|
|
security_check "$2"
|
|
fi
|
|
check_init_paramters "$2"
|
|
shift 2
|
|
;;
|
|
-l|--log-path)
|
|
if [ "$2" = "" ]
|
|
then
|
|
die "the parameter '-l|--log-path' cannot be empty."
|
|
fi
|
|
log_path="$2"
|
|
if [ ${log_path:0:1} != "/" ]
|
|
then
|
|
log_path="$(pwd)/${log_path}"
|
|
fi
|
|
shift 2
|
|
;;
|
|
-f|--guc-file)
|
|
if [ "$2" = "" ]
|
|
then
|
|
die "the parameter '-f|--guc-file' cannot be empty."
|
|
fi
|
|
guc_file="$2"
|
|
if [ ${guc_file:0:1} != "/" ]
|
|
then
|
|
guc_file="$(pwd)/${guc_file}"
|
|
fi
|
|
check_red_permission "${guc_file}"
|
|
shift 2
|
|
;;
|
|
-C|--dn-guc)
|
|
if [ "$2" = "" ]
|
|
then
|
|
die "the parameter '-C|--dn-guc' cannot be empty."
|
|
fi
|
|
security_check "$2"
|
|
check_conf_paramters "$2"
|
|
shift 2
|
|
;;
|
|
--env-sep-file)
|
|
if [ "$2" = "" ]
|
|
then
|
|
die "the parameter '--env-sep-file' cannot be empty."
|
|
fi
|
|
env_file=$2
|
|
if [ ${env_file:0:1} != "/" ]
|
|
then
|
|
env_file="$(pwd)/${env_file}"
|
|
fi
|
|
shift 2
|
|
;;
|
|
--start)
|
|
start=0
|
|
shift 1
|
|
;;
|
|
--ulimit)
|
|
ulimit_flag=0
|
|
shift 1
|
|
;;
|
|
--cert-path)
|
|
if [ "$2" = "" ]
|
|
then
|
|
die "the parameter '--cert-path' cannot be empty."
|
|
fi
|
|
cert_path=$2
|
|
if [ ${cert_path:0:1} != "/" ]
|
|
then
|
|
cert_path="$(pwd)/${cert_path}"
|
|
fi
|
|
shift 2
|
|
;;
|
|
--ssl-client-ip)
|
|
if [ "$2" = "" ]
|
|
then
|
|
die "the parameter '--ssl-client-ip' cannot be empty."
|
|
fi
|
|
client_ip=$2
|
|
shift 2
|
|
;;
|
|
*)
|
|
log "internal error: option processing error" 1>&2
|
|
log "please input right paramtenter, the following command may help you"
|
|
log "sh install.sh --help or sh install.sh -h"
|
|
exit 1
|
|
esac
|
|
done
|
|
|
|
function env_file_set()
|
|
{
|
|
if [ "${env_file}"X != ~/.bashrc"X" ]
|
|
then
|
|
if [ ! -e "${env_file}" ]
|
|
then
|
|
env_file_path=$(dirname ${env_file})
|
|
mkdir -p ${env_file_path}
|
|
if [ $? -ne 0 ]
|
|
then
|
|
die "touch ${env_file} failed."
|
|
fi
|
|
touch "${env_file}"
|
|
chmod 700 "${env_file}"
|
|
if [ $? -ne 0 ]
|
|
then
|
|
die "an error occurred when assigning read/write/execute permission to the directory $1."
|
|
fi
|
|
fi
|
|
check_red_permission "${env_file}"
|
|
check_write_permission "${env_file}"
|
|
check_execute_permission "${env_file}"
|
|
sed -i "/.*export\\s*GAUSSENV=/d" "${env_file}"
|
|
echo "export GAUSSENV=${env_file}" >> "${env_file}"
|
|
fi
|
|
}
|
|
function app()
|
|
{
|
|
if [ "${app_path}" = "" ]
|
|
then
|
|
app_path=$(cat ${env_file} | grep -e ".*export\\s*GAUSSHOME="| awk -F "=" '{print $2}')
|
|
fi
|
|
if [ "${app_path}" != "" ]
|
|
then
|
|
check_path "${app_path}" "install"
|
|
set_environment "${app_path}" "app"
|
|
if [ ${install_path_full_flag} -eq 1 ]
|
|
then
|
|
decompress
|
|
info "[begin decompressing binary files success.]"
|
|
else
|
|
info "[binary files already decompressed, pass.]"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
function data()
|
|
{
|
|
if [ "${data_path}" = "" ]
|
|
then
|
|
data_path=$(cat ${env_file} | grep -e ".*export\\s*GAUSSDATA="| awk -F "=" '{print $2}')
|
|
fi
|
|
if [ "${data_path}" != "" ]
|
|
then
|
|
check_path "${data_path}" "data"
|
|
set_environment "${data_path}" "data"
|
|
fi
|
|
}
|
|
|
|
function cert()
|
|
{
|
|
if [ "${cert_path}" != "" ]
|
|
then
|
|
if [ ! -e "${cert_path}" ]
|
|
then
|
|
die "the certificate path does not exist."
|
|
fi
|
|
check_path "${cert_path}" "cert"
|
|
if [ -z $(ls -A "${cert_path}" | grep server.crt) ]
|
|
then
|
|
die "no matching SSL certificate file(server.crt) is found. as a result,
|
|
SSL may fail to be opened. Check ssl config carefully after the installation."
|
|
else
|
|
check_red_permission "${cert_path}/server.crt"
|
|
fi
|
|
if [ -z $(ls -A "${cert_path}" | grep server.key) ]
|
|
then
|
|
die "no matching SSL certificate file(server.key) is found. as a result,
|
|
SSL may fail to be opened. Check ssl config carefully after the installation."
|
|
fi
|
|
if [ -z $(ls -A "${cert_path}" | grep cacert.pem) ]
|
|
then
|
|
die "no matching SSL certificate file(cacert.pem) is found. as a result,
|
|
SSL may fail to be opened. Check ssl config carefully after the installation."
|
|
fi
|
|
fi
|
|
}
|
|
|
|
function log_file_set()
|
|
{
|
|
if [ "${log_path}" != "" ]
|
|
then
|
|
check_path "${log_path}" "log"
|
|
data_contain_log_flag=$(echo ${data_path} | grep "${log_path}")
|
|
if [ "${data_contain_log_flag}" != "" ]
|
|
then
|
|
die "log-path cannot be a subdirectory of data-path."
|
|
fi
|
|
set_environment ${log_path} log
|
|
fi
|
|
}
|
|
|
|
function start()
|
|
{
|
|
if [ "${mode_type}" = "primary" ]
|
|
then
|
|
mode="-M primary"
|
|
if [ "${nodename}" = "" ]
|
|
then
|
|
nodename="master"
|
|
fi
|
|
elif [ "${mode_type}" = "standby" ]
|
|
then
|
|
mode="-b full"
|
|
action="build"
|
|
if [ "${nodename}" = "" ]
|
|
then
|
|
nodename="slave"
|
|
fi
|
|
else
|
|
mode="-Z single_node"
|
|
if [ "${nodename}" = "" ]
|
|
then
|
|
nodename="single"
|
|
fi
|
|
fi
|
|
log "mode_type is ${mode_type} and mode is ${mode}, node name is ${nodename}"
|
|
# check whether the app-path and data-path paths are contained.
|
|
cd ${app_path}
|
|
if [ $? -ne 0 ]
|
|
then
|
|
die "cd app-path failed, no such file or directory."
|
|
fi
|
|
app_path=$(pwd)
|
|
cd ${data_path}
|
|
if [ $? -ne 0 ]
|
|
then
|
|
die "cd data-path failed, no such file or directory."
|
|
fi
|
|
data_path=$(pwd)
|
|
app_contain_data_flag=$(echo ${app_path} | grep "${data_path}")
|
|
data_contain_app_flag=$(echo ${data_path} | grep "${app_path}")
|
|
if [ "${app_contain_data_flag}" != "" ]
|
|
then
|
|
die "data-path cannot be a subdirectory of app-path."
|
|
fi
|
|
if [ "${data_contain_app_flag}" != "" ]
|
|
then
|
|
die "app-path cannot be a subdirectory of data-path."
|
|
fi
|
|
if [ ${data_full_flag} -ne 0 ]
|
|
then
|
|
if [ ${interactive_passwd_flag} -eq 1 ]
|
|
then
|
|
if [ "${password}" = "" ]
|
|
then
|
|
index=0
|
|
while [ "${password}" = "" ]
|
|
do
|
|
if [ ${index} -gt 2 ]
|
|
then
|
|
die "maximum number of retries exceeded"
|
|
fi
|
|
hide_password 0
|
|
echo -e "\n"
|
|
hide_password 1
|
|
echo -e "\n"
|
|
if [ "${password}" != "${password_check}" ]
|
|
then
|
|
info "the two passwords entered are inconsistent, please retry."
|
|
index=$[ ${index} + 1 ]
|
|
password=""
|
|
continue
|
|
fi
|
|
check_passwd "${password}"
|
|
if [ $? -ne 0 ]
|
|
then
|
|
die "install gaussdb failed, the password can contain only 8 to 32 characters
|
|
and at least three types of the following characters: uppercase letters, lowercase letters, digits, and special characters."
|
|
fi
|
|
index=$[ ${index} + 1 ]
|
|
done
|
|
init_parameters="${init_parameters} -w ${password}"
|
|
init_show_parameters="${init_show_parameters} ""-w ******"
|
|
else
|
|
check_passwd "${password}"
|
|
if [ $? -ne 0 ]
|
|
then
|
|
die "install gaussdb failed, the password can contain only 8 to 32 characters
|
|
and at least three types of the following characters: uppercase letters, lowercase letters, digits, and special characters."
|
|
fi
|
|
init_parameters="${init_parameters} -w ${password}"
|
|
init_show_parameters="${init_show_parameters} ""-w ******"
|
|
fi
|
|
fi
|
|
init_db
|
|
data_full_flag=0
|
|
info "[install datanode success.]"
|
|
fi
|
|
|
|
if [ "${config_parameters}" != "" ]
|
|
then
|
|
config_db
|
|
info "[config datanode success.]"
|
|
fi
|
|
|
|
if [ "$guc_file" = "" ]
|
|
then
|
|
if [ -e "${root_path}/opengauss_lite.conf" ]
|
|
then
|
|
guc_file="${root_path}/opengauss_lite.conf"
|
|
fi
|
|
fi
|
|
|
|
if [ "${guc_file}" != "" ]
|
|
then
|
|
guc_db
|
|
fi
|
|
|
|
if [ "${cert_path}" != "" ]
|
|
then
|
|
cert_db
|
|
fi
|
|
|
|
if [ ${start} -eq 0 ]
|
|
then
|
|
start_db
|
|
fi
|
|
}
|
|
|
|
function main()
|
|
{
|
|
check_os
|
|
data
|
|
if [ "${app_path}" != "" -a "${data_path}" != "" ]
|
|
then
|
|
if [ ${data_full_flag} -ne 0 ]
|
|
then
|
|
check
|
|
fi
|
|
fi
|
|
env_file_set
|
|
cert
|
|
app
|
|
log_file_set
|
|
source ${env_file}
|
|
if [ "${app_path}" != "" -a "${data_path}" != "" ]
|
|
then
|
|
start
|
|
fi
|
|
info "run cmd 'source ${env_file}' to make the environment variables take effect."
|
|
}
|
|
main
|
|
exit 0 |