|
| 1 | +#!/bin/bash |
| 2 | +# create master and slave |
| 3 | +# Copyright (c) Huawei Technologies Co., Ltd. 2020-2028. All rights reserved. |
| 4 | +# |
| 5 | +#openGauss is licensed under Mulan PSL v2. |
| 6 | +#You can use this software according to the terms and conditions of the Mulan PSL v2. |
| 7 | +#You may obtain a copy of Mulan PSL v2 at: |
| 8 | +# |
| 9 | +# http://license.coscl.org.cn/MulanPSL2 |
| 10 | +# |
| 11 | +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, |
| 12 | +# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, |
| 13 | +# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. |
| 14 | +# See the Mulan PSL v2 for more details. |
| 15 | +#------------------------------------------------------------------------- |
| 16 | +# |
| 17 | +# create_master_slave.sh |
| 18 | +# create master and slave |
| 19 | +# |
| 20 | +# IDENTIFICATION |
| 21 | +# GaussDBKernel/server/docker/dockerfiles/create_master_slave.sh |
| 22 | +# |
| 23 | +#------------------------------------------------------------------------- |
| 24 | + |
| 25 | +#set OG_SUBNET,GS_PASSWORD,MASTER_IP,SLAVE_1_IP,MASTER_HOST_PORT,MASTER_LOCAL_PORT,SLAVE_1_HOST_PORT,SLAVE_1_LOCAL_PORT,MASTER_NODENAME,SLAVE_NODENAME |
| 26 | + |
| 27 | +# Define default values |
| 28 | +NETWORK_NAME="opengaussnetwork" |
| 29 | +GS_USERNAME=root |
| 30 | +OG_SUBNET="172.11.0.0/24" |
| 31 | +MASTER_IP="172.11.0.101" |
| 32 | +MASTER_HOST_PORT="5432" |
| 33 | +MASTER_NODENAME="dn_6001" |
| 34 | + |
| 35 | +VERSION="7.0.0-RC1" |
| 36 | + |
| 37 | +# Define default values for slaves |
| 38 | +SLAVE_IP=("172.11.0.102" "172.11.0.103" "172.11.0.104" "172.11.0.105" "172.11.0.106" "172.11.0.107" "172.11.0.108" "172.11.0.109") |
| 39 | +SLAVE_HOST_PORT=("6432" "7432" "8432" "9432" "10432" "11432" "12432" "13432") |
| 40 | +SLAVE_NODENAME=("dn_6002" "dn_6003" "dn_6004" "dn_6005" "dn_6006" "dn_6007" "dn_6008" "dn_6009") |
| 41 | +SLAVE_COUNT=2 |
| 42 | +BASE_DIR="/opt/opengauss_data" |
| 43 | +MASTER_OUT_DIR="${BASE_DIR}/dn_6001" |
| 44 | +SLAVE_OUT_DIR=("${BASE_DIR}/dn_6002" "${BASE_DIR}/dn_6003") |
| 45 | + |
| 46 | +log(){ echo -e "[$(date '+%F %T')] $*"; } |
| 47 | + |
| 48 | +wait_for_db(){ |
| 49 | + local cname="$1" port="$2" |
| 50 | + local max=60; local i=0 |
| 51 | + until docker exec "$cname" su - omm -c "gsql -d postgres -U omm -p \"$port\" -c '\q'" >/dev/null 2>&1; do |
| 52 | + ((i++)); if (( i>=max )); then echo "ERROR: $cname not ready"; exit 1; fi |
| 53 | + sleep 5; log "$LINENO:Waiting $cname ..." |
| 54 | + done |
| 55 | +} |
| 56 | + |
| 57 | +if [ -z "${GS_PASSWORD:-}" ]; then |
| 58 | + echo "Please enter a password with at least 8-16 digits containing numbers, letters, and special characters: " |
| 59 | + read -s GS_PASSWORD |
| 60 | +fi |
| 61 | + |
| 62 | +if [[ "$GS_PASSWORD" =~ ^(.{8,}).*$ ]] && [[ "$GS_PASSWORD" =~ ^(.*[a-z]+).*$ ]] && [[ "$GS_PASSWORD" =~ ^(.*[A-Z]).*$ ]] && [[ "$GS_PASSWORD" =~ ^(.*[0-9]).*$ ]] && [[ "$GS_PASSWORD" =~ ^(.*[#?!@$%^&*-]).*$ ]]; then |
| 63 | + log "$LINENO:The supplied GS_PASSWORD is meet requirements." |
| 64 | +else |
| 65 | + log "$LINENO:Please Check if the password contains uppercase, lowercase, numbers, special characters, and password length(8). At least one uppercase, lowercase, numeric, special character." |
| 66 | + exit 1 |
| 67 | +fi |
| 68 | + |
| 69 | +ARGS=$(getopt -o h --long OG_SUBNET:,GS_PASSWORD:,MASTER_IP:,MASTER_HOST_PORT:,MASTER_LOCAL_PORT:,MASTER_NODENAME:,VERSION:,SLAVE_COUNT:,NETWORK_NAME: -- "$@") |
| 70 | +if [ $? != 0 ]; then |
| 71 | + echo "Argument parsing error" |
| 72 | + exit 1 |
| 73 | +fi |
| 74 | +eval set -- "$ARGS" |
| 75 | + |
| 76 | +# Use getopts to process command line arguments |
| 77 | +while true; do |
| 78 | + case "$1" in |
| 79 | + -h) |
| 80 | + echo "Usage: $0 [--OG_SUBNET value] [--GS_PASSWORD value] [--MASTER_IP value] [--MASTER_HOST_PORT value] [--MASTER_NODENAME value] [--VERSION value] [--SLAVE_COUNT value] [--NETWORK_NAME value]" |
| 81 | + shift |
| 82 | + ;; |
| 83 | + --OG_SUBNET) |
| 84 | + OG_SUBNET="$2" |
| 85 | + shift 2 |
| 86 | + ;; |
| 87 | + --GS_PASSWORD) |
| 88 | + GS_PASSWORD="$2" |
| 89 | + shift 2 |
| 90 | + ;; |
| 91 | + --MASTER_IP) |
| 92 | + MASTER_IP="$2" |
| 93 | + shift 2 |
| 94 | + ;; |
| 95 | + --MASTER_HOST_PORT) |
| 96 | + MASTER_HOST_PORT="$2" |
| 97 | + shift 2 |
| 98 | + ;; |
| 99 | + --MASTER_LOCAL_PORT) |
| 100 | + MASTER_LOCAL_PORT="$2" |
| 101 | + shift 2 |
| 102 | + ;; |
| 103 | + --MASTER_NODENAME) |
| 104 | + MASTER_NODENAME="$2" |
| 105 | + shift 2 |
| 106 | + ;; |
| 107 | + --VERSION) |
| 108 | + VERSION="$2" |
| 109 | + shift 2 |
| 110 | + ;; |
| 111 | + --SLAVE_COUNT) |
| 112 | + SLAVE_COUNT="$2" |
| 113 | + shift 2 |
| 114 | + ;; |
| 115 | + --NETWORK_NAME) |
| 116 | + NETWORK_NAME="$2" |
| 117 | + shift 2 |
| 118 | + ;; |
| 119 | + --) |
| 120 | + shift |
| 121 | + break |
| 122 | + ;; |
| 123 | + *) |
| 124 | + echo "Invalid option: -$OPTARG" >&2 |
| 125 | + exit 1 |
| 126 | + ;; |
| 127 | + esac |
| 128 | +done |
| 129 | + |
| 130 | +# Output the set values |
| 131 | +log "$LINENO:OG_SUBNET set $OG_SUBNET" |
| 132 | +log "$LINENO:MASTER_IP set $MASTER_IP" |
| 133 | +log "$LINENO:MASTER_HOST_PORT set $MASTER_HOST_PORT" |
| 134 | +log "$LINENO:MASTER_NODENAME set $MASTER_NODENAME" |
| 135 | +log "$LINENO:openGauss VERSION set $VERSION" |
| 136 | +log "$LINENO:SLAVE_COUNT set $SLAVE_COUNT" |
| 137 | +log "$LINENO:SLAVE_NODENAME set $SLAVE_NODENAME" |
| 138 | +log "$LINENO:SLAVE_IP set $SLAVE_IP" |
| 139 | +log "$LINENO:SLAVE_HOST_PORT set $SLAVE_HOST_PORT" |
| 140 | +log "$LINENO:NETWORK_NAME set $NETWORK_NAME" |
| 141 | + |
| 142 | +# Loop through and process each slave's information |
| 143 | +for (( i=0; i<SLAVE_COUNT; i++ )); do |
| 144 | + log "$LINENO:SLAVE_${i}_IP set${SLAVE_IP[$i]}" |
| 145 | + log "$LINENO:SLAVE_${i}_HOST_PORT set${SLAVE_HOST_PORT[$i]}" |
| 146 | + log "$LINENO:SLAVE_${i}_NODENAME set${SLAVE_NODENAME[$i]}" |
| 147 | +done |
| 148 | + |
| 149 | + |
| 150 | +log "$LINENO:Starting..." |
| 151 | +log "$LINENO:Reset data dirs..." |
| 152 | +rm -rf "$BASE_DIR" |
| 153 | +mkdir -p "$MASTER_OUT_DIR" "${SLAVE_OUT_DIR[@]}" |
| 154 | + |
| 155 | +log "$LINENO:Cleaning up existing containers and network..." |
| 156 | +for name in "$MASTER_NODENAME" "${SLAVE_NODENAME[@]}"; do |
| 157 | + if [ "$(docker ps -a -q -f name=^/${name}$)" ]; then |
| 158 | + log "$LINENO:Removing existing container $name" |
| 159 | + docker rm -f $name >/dev/null || true |
| 160 | + fi |
| 161 | +done |
| 162 | + |
| 163 | +if [ "$(docker network ls -q -f name=^${NETWORK_NAME}$)" ]; then |
| 164 | + log "$LINENO:Removing existing network $NETWORK_NAME" |
| 165 | + docker network rm $NETWORK_NAME >/dev/null || true |
| 166 | +fi |
| 167 | + |
| 168 | +log "$LINENO:Creating OpenGauss Database Network..." |
| 169 | +docker network create --subnet=$OG_SUBNET $NETWORK_NAME \ |
| 170 | +|| { echo "ERROR: Network was NOT successfully created."; exit 1; } |
| 171 | +log "$LINENO:OpenGauss Database Network Created." |
| 172 | + |
| 173 | +log "$LINENO:Creating OpenGauss Database Master Docker Container..." |
| 174 | +REPL_CONN_INFO_MASTER="" |
| 175 | +local_info="localhost=$MASTER_IP localport=$((MASTER_HOST_PORT+1)) localservice=$((MASTER_HOST_PORT+4)) localheartbeatport=$((MASTER_HOST_PORT+5))" |
| 176 | +for (( i=0; i<SLAVE_COUNT; i++ )); do |
| 177 | + remote_port=${SLAVE_HOST_PORT[$i]} |
| 178 | + remote_info="remotehost=${SLAVE_IP[$i]} remoteport=$((remote_port+1)) remoteservice=$((remote_port+4)) remoteheartbeatport=$((remote_port+5))" |
| 179 | + REPL_CONN_INFO_MASTER+="replconninfo$((i+1)) = '$local_info $remote_info'\n" |
| 180 | +done |
| 181 | +docker run --network $NETWORK_NAME --ip $MASTER_IP --privileged=true \ |
| 182 | +--name $MASTER_NODENAME -h $MASTER_NODENAME -p $MASTER_HOST_PORT:$MASTER_HOST_PORT -d \ |
| 183 | +-v $MASTER_OUT_DIR:/var/lib/opengauss \ |
| 184 | +-e GS_USERNAME=$GS_USERNAME \ |
| 185 | +-e GS_PORT=$MASTER_HOST_PORT \ |
| 186 | +-e OG_SUBNET=$OG_SUBNET \ |
| 187 | +-e GS_USER_PASSWORD="$GS_PASSWORD" \ |
| 188 | +-e GS_PASSWORD="$GS_PASSWORD" \ |
| 189 | +-e NODE_NAME="$MASTER_NODENAME" \ |
| 190 | +-e REPL_CONN_INFO="$REPL_CONN_INFO_MASTER" \ |
| 191 | +opengauss:$VERSION -M primary > /dev/null |
| 192 | + |
| 193 | +log "$LINENO:OpenGauss Database Master Docker Container created." |
| 194 | +wait_for_db "$MASTER_NODENAME" "$MASTER_HOST_PORT" |
| 195 | +log "$LINENO:Master database is ready." |
| 196 | + |
| 197 | +# docker exec "$MASTER_NODENAME" su - omm -c " |
| 198 | +# gsql -d postgres -U omm -c \"DROP USER IF EXISTS repluser;\" |
| 199 | +# gsql -d postgres -U omm -c \"CREATE USER repluser REPLICATION SYSADMIN PASSWORD '$GS_PASSWORD';\" |
| 200 | +# gsql -d postgres -U omm -c \"DROP USER IF EXISTS dbadmin;\" |
| 201 | +# gsql -d postgres -U omm -c \"CREATE USER dbadmin WITH PASSWORD '$GS_PASSWORD'; GRANT ALL PRIVILEGES TO dbadmin;\" |
| 202 | +# " |
| 203 | +# log "$LINENO:Master pg_hba & repluser configured." |
| 204 | + |
| 205 | +for (( i=0; i<SLAVE_COUNT; i++ )); do |
| 206 | + REPL_CONN_INFO_SLAVE="" |
| 207 | + local_port=${SLAVE_HOST_PORT[$i]} |
| 208 | + log "$LINENO:Creating slave ${SLAVE_NODENAME[$i]} on ${SLAVE_IP[$i]}:$local_port ..." |
| 209 | + local_info="localhost=${SLAVE_IP[$i]} localport=$((local_port+1)) localservice=$((local_port+4)) localheartbeatport=$((local_port+5))" |
| 210 | + remote_master_info="remotehost=$MASTER_IP remoteport=$((MASTER_HOST_PORT+1)) remoteservice=$((MASTER_HOST_PORT+4)) remoteheartbeatport=$((MASTER_HOST_PORT+5))" |
| 211 | + k=1 |
| 212 | + REPL_CONN_INFO_SLAVE="replconninfo${k} = '$local_info $remote_master_info'\n" |
| 213 | + for (( j=0; j<SLAVE_COUNT; j++ )); do |
| 214 | + if [[ $i -eq $j ]]; then |
| 215 | + continue |
| 216 | + fi |
| 217 | + k=$((k+1)) |
| 218 | + remote_port=${SLAVE_HOST_PORT[$j]} |
| 219 | + remote_info="remotehost=${SLAVE_IP[$j]} remoteport=$((remote_port+1)) remoteservice=$((remote_port+4)) remoteheartbeatport=$((remote_port+5))" |
| 220 | + REPL_CONN_INFO_SLAVE+="replconninfo${k} = '$local_info $remote_info'\n" |
| 221 | + done |
| 222 | + |
| 223 | + docker run --network $NETWORK_NAME --ip ${SLAVE_IP[$i]} --privileged=true \ |
| 224 | + --name ${SLAVE_NODENAME[$i]} -h ${SLAVE_NODENAME[$i]} -p $local_port:$local_port -d \ |
| 225 | + -v ${SLAVE_OUT_DIR[$i]}:/var/lib/opengauss \ |
| 226 | + -e GS_PORT=$local_port \ |
| 227 | + -e OG_SUBNET=$OG_SUBNET \ |
| 228 | + -e GS_PASSWORD="$GS_PASSWORD" \ |
| 229 | + -e NODE_NAME="${SLAVE_NODENAME[$i]}" \ |
| 230 | + -e REPL_CONN_INFO="$REPL_CONN_INFO_SLAVE" \ |
| 231 | + opengauss:$VERSION -M standby > /dev/null |
| 232 | + |
| 233 | + wait_for_db "${SLAVE_NODENAME[$i]}" "$local_port" |
| 234 | + log "$LINENO:${SLAVE_NODENAME[$i]} database is ready." |
| 235 | +done |
| 236 | + |
| 237 | +log "$LINENO:All nodes are up." |
0 commit comments