Skip to content

Commit 370d1fd

Browse files
author
chenyunliang520
committed
Enhance cluster_ha_showcase.py with DSN masking for secure logging, add cluster_opengauss_docker.sh for OpenGauss cluster deployment, and include cluster_opengauss_docker_readme.md for setup instructions; set executable permissions for modified and new files
1 parent 2e46a8f commit 370d1fd

File tree

4 files changed

+857
-3
lines changed

4 files changed

+857
-3
lines changed

example/cluster_ha_showcase.py

100644100755
Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# -*- coding: utf-8 -*-
2+
import re
23
import sys
34
import time
45
import random
@@ -105,20 +106,29 @@ def connect_with_retry(
105106
dsn: str, max_attempts: int = 5, timeout: int = 10
106107
) -> Connection:
107108
"""带重试的数据库连接"""
109+
masked_dsn = re.sub(
110+
r"user=[^ ]+|password=[^ ]+",
111+
lambda m: f"{m.group(0).split('=')[0]}=***",
112+
dsn,
113+
)
108114
for attempt in range(1, max_attempts + 1):
109115
try:
110116
start_time = time.time()
111117
conn = connect(
112118
dsn, connect_timeout=timeout, application_name="pg_connection_test"
113119
)
114-
logger.info(f"连接成功: {dsn},耗时: {time.time() - start_time:.2f} 秒")
120+
logger.info(
121+
f"连接成功: {masked_dsn},耗时: {time.time() - start_time:.2f} 秒"
122+
)
115123
return conn
116124
except Error as e:
117-
logger.error(f"连接失败 ({dsn}),第 {attempt}/{max_attempts} 次尝试: {e}")
125+
logger.error(
126+
f"连接失败 ({masked_dsn}),第 {attempt}/{max_attempts} 次尝试: {e}"
127+
)
118128
if attempt == max_attempts:
119129
raise
120130
time.sleep(2**attempt)
121-
raise RuntimeError(f"连接失败: {dsn}")
131+
raise RuntimeError(f"连接失败: {masked_dsn}")
122132

123133

124134
def disaster_recovery(params, simulate_failure: bool = False):
Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
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

Comments
 (0)