diff --git a/docker-build/patroni-for-openGauss/build.sh b/docker-build/patroni-for-openGauss/centos_x86/build.sh similarity index 100% rename from docker-build/patroni-for-openGauss/build.sh rename to docker-build/patroni-for-openGauss/centos_x86/build.sh diff --git a/docker-build/patroni-for-openGauss/dockerfile b/docker-build/patroni-for-openGauss/centos_x86/dockerfile similarity index 100% rename from docker-build/patroni-for-openGauss/dockerfile rename to docker-build/patroni-for-openGauss/centos_x86/dockerfile diff --git a/docker-build/patroni-for-openGauss/entrypoint.sh b/docker-build/patroni-for-openGauss/centos_x86/entrypoint.sh similarity index 100% rename from docker-build/patroni-for-openGauss/entrypoint.sh rename to docker-build/patroni-for-openGauss/centos_x86/entrypoint.sh diff --git a/docker-build/patroni-for-openGauss/etcd.conf.sample b/docker-build/patroni-for-openGauss/centos_x86/etcd.conf.sample similarity index 100% rename from docker-build/patroni-for-openGauss/etcd.conf.sample rename to docker-build/patroni-for-openGauss/centos_x86/etcd.conf.sample diff --git a/docker-build/patroni-for-openGauss/gosu-amd64 b/docker-build/patroni-for-openGauss/centos_x86/gosu-amd64 similarity index 100% rename from docker-build/patroni-for-openGauss/gosu-amd64 rename to docker-build/patroni-for-openGauss/centos_x86/gosu-amd64 diff --git a/docker-build/patroni-for-openGauss/gosu-arm64 b/docker-build/patroni-for-openGauss/centos_x86/gosu-arm64 similarity index 100% rename from docker-build/patroni-for-openGauss/gosu-arm64 rename to docker-build/patroni-for-openGauss/centos_x86/gosu-arm64 diff --git a/docker-build/patroni-for-openGauss/openGauss-2.0.1-CentOS-64bit.tar.bz2 b/docker-build/patroni-for-openGauss/centos_x86/openGauss-2.0.1-CentOS-64bit.tar.bz2 similarity index 100% rename from docker-build/patroni-for-openGauss/openGauss-2.0.1-CentOS-64bit.tar.bz2 rename to docker-build/patroni-for-openGauss/centos_x86/openGauss-2.0.1-CentOS-64bit.tar.bz2 diff --git a/docker-build/patroni-for-openGauss/patroni-2.0.2.tar.gz b/docker-build/patroni-for-openGauss/centos_x86/patroni-2.0.2.tar.gz similarity index 100% rename from docker-build/patroni-for-openGauss/patroni-2.0.2.tar.gz rename to docker-build/patroni-for-openGauss/centos_x86/patroni-2.0.2.tar.gz diff --git a/docker-build/patroni-for-openGauss/patroni.yaml.sample b/docker-build/patroni-for-openGauss/centos_x86/patroni.yaml.sample similarity index 100% rename from docker-build/patroni-for-openGauss/patroni.yaml.sample rename to docker-build/patroni-for-openGauss/centos_x86/patroni.yaml.sample diff --git a/docker-build/patroni-for-openGauss/psycopg2-2.8.6.tar.gz b/docker-build/patroni-for-openGauss/centos_x86/psycopg2-2.8.6.tar.gz similarity index 100% rename from docker-build/patroni-for-openGauss/psycopg2-2.8.6.tar.gz rename to docker-build/patroni-for-openGauss/centos_x86/psycopg2-2.8.6.tar.gz diff --git a/docker-build/patroni-for-openGauss/psycopg2_binary-2.8.6-cp36-cp36m-manylinux1_x86_64.whl b/docker-build/patroni-for-openGauss/centos_x86/psycopg2_binary-2.8.6-cp36-cp36m-manylinux1_x86_64.whl similarity index 100% rename from docker-build/patroni-for-openGauss/psycopg2_binary-2.8.6-cp36-cp36m-manylinux1_x86_64.whl rename to docker-build/patroni-for-openGauss/centos_x86/psycopg2_binary-2.8.6-cp36-cp36m-manylinux1_x86_64.whl diff --git a/docker-build/patroni-for-openGauss/wal2json.so b/docker-build/patroni-for-openGauss/centos_x86/wal2json.so similarity index 100% rename from docker-build/patroni-for-openGauss/wal2json.so rename to docker-build/patroni-for-openGauss/centos_x86/wal2json.so diff --git a/docker-build/patroni-for-openGauss/openEuler_aarch64/build.sh b/docker-build/patroni-for-openGauss/openEuler_aarch64/build.sh new file mode 100644 index 0000000000000000000000000000000000000000..a2c71a39c7e556cd71bca54c0ecea21474d86f60 --- /dev/null +++ b/docker-build/patroni-for-openGauss/openEuler_aarch64/build.sh @@ -0,0 +1 @@ +docker build -t "opengauss:3.0.1" -f dockerfile . diff --git a/docker-build/patroni-for-openGauss/openEuler_aarch64/dockerfile b/docker-build/patroni-for-openGauss/openEuler_aarch64/dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..3091e20c115ca29da7e07ef0e03b207e87632997 --- /dev/null +++ b/docker-build/patroni-for-openGauss/openEuler_aarch64/dockerfile @@ -0,0 +1,65 @@ +FROM openeuler-20.03-lts:latest + +# prepare openGauss +ENV LC_ALL=en_US.utf-8 +ENV LANG en_US.utf8 + +COPY gosu-arm64 /usr/local/bin/gosu +# COPY wal2json.so /tmp +COPY etcd.conf.sample /home/omm/etcd.conf +COPY patroni.yaml.sample /home/omm/patroni.yaml +ENV GOSU_VERSION 1.12 +ADD patroni-2.0.2.tar.gz /var/lib +ADD etcd.tar.gz /usr/local/bin +ADD openGauss-3.0.0-openEuler-64bit.tar.bz2 /usr/local/opengauss +COPY gs_isready /usr/local/opengauss/bin/ +ADD libpython3.7m.so.1.0 /usr/local +COPY openEuler_aarch64.repo /etc/yum.repos.d/openEuler_aarch64.repo +ADD psycopg2.tar.gz /usr/local/lib64/python3.7/site-packages/ + + +RUN set -eux; \ + yum install -y python3 libaio libaio-devel numactl numactl-devel python3-setuptools libpq-devel \ + python-devel python3-devel python3-pip gcc bind-utils vim && \ + groupadd -g 70 omm && \ + useradd -u 70 -g omm -d /home/omm omm && \ + mkdir -p /var/lib/opengauss && \ + mkdir -p /usr/local/opengauss && \ + mkdir -p /var/run/opengauss && \ + mkdir -p /home/omm && \ + mkdir -p /var/log/ && \ + mkdir /docker-entrypoint-initdb.d && \ + chown omm:omm /var/lib/opengauss /home/omm /var/run/opengauss /usr/local/opengauss /docker-entrypoint-initdb.d \ + /var/log /var/lib/patroni-2.0.2 -R && \ + chmod +x /usr/local/opengauss/bin/gs_isready && \ + cp /usr/local/libpython3.7m.so.1.0 /usr/lib64/ && \ + # cp /tmp/wal2json.so /usr/local/opengauss && \ + echo "export GAUSSHOME=/usr/local/opengauss" >> /home/omm/.bashrc && \ + echo "export PATH=\$GAUSSHOME/bin:\$PATH " >> /home/omm/.bashrc && \ + echo "export LD_LIBRARY_PATH=\$GAUSSHOME/lib:\$LD_LIBRARY_PATH" >> /home/omm/.bashrc && \ + echo "export ETCD_UNSUPPORTED_ARCH=arm64" >> /home/omm/.bashrc && \ + chown omm:omm /home/omm -R && \ + chmod +x /usr/local/bin/gosu && \ + #pip3 install psycopg2-binary==2.8.6 && \ + #pip3 install psycopg2==2.8.6 && \ + #pip install psycopg2-binary==2.8.6 && \ + #pip install psycopg2==2.8.6 && \ + pip3 install six python-etcd importlib-metadata && \ + cd /var/lib/patroni-2.0.2/ && python3 setup.py build && python3 setup.py install && \ + rm /var/lib/patroni-2.0.2/ -rf && \ + mv /etc/localtime /etc/localtime_bak && \ + cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \ + unlink /usr/bin/python && \ + ln -s /usr/bin/python3 /usr/bin/python && \ + chmod 755 /usr/local/lib64/python3.7/site-packages/psycopg2 -R + +# prepare atcd and patroni + +ENV PGDATA /var/lib/opengauss/data + +COPY entrypoint.sh /usr/local/bin/ +RUN chmod 755 /usr/local/bin/entrypoint.sh;ln -s /usr/local/bin/entrypoint.sh / # backwards compat +ENTRYPOINT ["entrypoint.sh"] +EXPOSE 5432 +USER omm +CMD ["patroni"] diff --git a/docker-build/patroni-for-openGauss/openEuler_aarch64/entrypoint.sh b/docker-build/patroni-for-openGauss/openEuler_aarch64/entrypoint.sh new file mode 100644 index 0000000000000000000000000000000000000000..7ffffcacc1f66ee289c38d8802cda0871eb8c137 --- /dev/null +++ b/docker-build/patroni-for-openGauss/openEuler_aarch64/entrypoint.sh @@ -0,0 +1,634 @@ +#!/usr/bin/env bash +set -Eeo pipefail + +# usage: file_env VAR [DEFAULT] +# ie: file_env 'XYZ_DB_PASSWORD' 'example' +# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of +# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature) + +export GAUSSHOME=/usr/local/opengauss +export PATH=$GAUSSHOME/bin:$PATH +export LD_LIBRARY_PATH=$GAUSSHOME/lib:$LD_LIBRARY_PATH +export LANG=en_US.UTF-8 + +file_env() { + local var="$1" + local fileVar="${var}_FILE" + local def="${2:-}" + if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then + echo >&2 "error: both $var and $fileVar are set (but are exclusive)" + exit 1 + fi + local val="$def" + if [ "${!var:-}" ]; then + val="${!var}" + elif [ "${!fileVar:-}" ]; then + val="$(< "${!fileVar}")" + fi + export "$var"="$val" + unset "$fileVar" +} + +# check to see if this file is being run or sourced from another script +_is_sourced() { + [ "${#FUNCNAME[@]}" -ge 2 ] \ + && [ "${FUNCNAME[0]}" = '_is_sourced' ] \ + && [ "${FUNCNAME[1]}" = 'source' ] +} + +# used to create initial opengauss directories and if run as root, ensure ownership belong to the omm user +docker_create_db_directories() { + local user; user="$(id -u)" + + mkdir -p "$PGDATA" + chmod 700 "$PGDATA" + + # ignore failure since it will be fine when using the image provided directory; + mkdir -p /var/run/opengauss || : + chmod 775 /var/run/opengauss || : + + # Create the transaction log directory before initdb is run so the directory is owned by the correct user + if [ -n "$POSTGRES_INITDB_XLOGDIR" ]; then + mkdir -p "$POSTGRES_INITDB_XLOGDIR" + if [ "$user" = '0' ]; then + find "$POSTGRES_INITDB_XLOGDIR" \! -user postgres -exec chown postgres '{}' + + fi + chmod 700 "$POSTGRES_INITDB_XLOGDIR" + fi + + # allow the container to be started with `--user` + if [ "$user" = '0' ]; then + find "$PGDATA" \! -user omm -exec chown omm '{}' + + find /var/run/opengauss \! -user omm -exec chown omm '{}' + + fi +} + +# initialize empty PGDATA directory with new database via 'initdb' +# arguments to `initdb` can be passed via POSTGRES_INITDB_ARGS or as arguments to this function +# `initdb` automatically creates the "postgres", "template0", and "template1" dbnames +# this is also where the database user is created, specified by `GS_USER` env +docker_init_database_dir() { + # "initdb" is particular about the current user existing in "/etc/passwd", so we use "nss_wrapper" to fake that if necessary + if ! getent passwd "$(id -u)" &> /dev/null && [ -e /usr/lib/libnss_wrapper.so ]; then + export LD_PRELOAD='/usr/lib/libnss_wrapper.so' + export NSS_WRAPPER_PASSWD="$(mktemp)" + export NSS_WRAPPER_GROUP="$(mktemp)" + echo "postgres:x:$(id -u):$(id -g):PostgreSQL:$PGDATA:/bin/false" > "$NSS_WRAPPER_PASSWD" + echo "postgres:x:$(id -g):" > "$NSS_WRAPPER_GROUP" + fi + + if [ -n "$POSTGRES_INITDB_XLOGDIR" ]; then + set -- --xlogdir "$POSTGRES_INITDB_XLOGDIR" "$@" + fi + + gs_initdb -w "$GS_PASSWORD" --nodename=opengauss --encoding=UTF-8 --locale=en_US.UTF-8 --dbcompatibility=PG -D $PGDATA + # unset/cleanup "nss_wrapper" bits + if [ "${LD_PRELOAD:-}" = '/usr/lib/libnss_wrapper.so' ]; then + rm -f "$NSS_WRAPPER_PASSWD" "$NSS_WRAPPER_GROUP" + unset LD_PRELOAD NSS_WRAPPER_PASSWD NSS_WRAPPER_GROUP + fi +} + +# print large warning if GS_PASSWORD is long +# error if both GS_PASSWORD is empty and GS_HOST_AUTH_METHOD is not 'trust' +# print large warning if GS_HOST_AUTH_METHOD is set to 'trust' +# assumes database is not set up, ie: [ -z "$DATABASE_ALREADY_EXISTS" ] +docker_verify_minimum_env() { + # check password first so we can output the warning before postgres + # messes it up + if [[ "$GS_PASSWORD" =~ ^(.{8,}).*$ ]] && [[ "$GS_PASSWORD" =~ ^(.*[a-z]+).*$ ]] && [[ "$GS_PASSWORD" =~ ^(.*[A-Z]).*$ ]] && [[ "$GS_PASSWORD" =~ ^(.*[0-9]).*$ ]] && [[ "$GS_PASSWORD" =~ ^(.*[#?!@$%^&*-]).*$ ]]; then + cat >&2 <<-'EOWARN' + + Message: The supplied GS_PASSWORD is meet requirements. + +EOWARN + else + cat >&2 <<-'EOWARN' + + Error: The supplied GS_PASSWORD is not meet requirements. + Please Check if the password contains uppercase, lowercase, numbers, special characters, and password length(8). + At least one uppercase, lowercase, numeric, special character. + Example: Enmo@123 +EOWARN + exit 1 + fi + if [ -z "$GS_PASSWORD" ] && [ 'trust' != "$GS_HOST_AUTH_METHOD" ]; then + # The - option suppresses leading tabs but *not* spaces. :) + cat >&2 <<-'EOE' + Error: Database is uninitialized and superuser password is not specified. + You must specify GS_PASSWORD to a non-empty value for the + superuser. For example, "-e GS_PASSWORD=password" on "docker run". + + You may also use "GS_HOST_AUTH_METHOD=trust" to allow all + connections without a password. This is *not* recommended. + +EOE + exit 1 + fi + if [ 'trust' = "$GS_HOST_AUTH_METHOD" ]; then + cat >&2 <<-'EOWARN' + ******************************************************************************** + WARNING: GS_HOST_AUTH_METHOD has been set to "trust". This will allow + anyone with access to the opengauss port to access your database without + a password, even if GS_PASSWORD is set. + It is not recommended to use GS_HOST_AUTH_METHOD=trust. Replace + it with "-e GS_PASSWORD=password" instead to set a password in + "docker run". + ******************************************************************************** +EOWARN + fi +} + +# usage: docker_process_init_files [file [file [...]]] +# ie: docker_process_init_files /always-initdb.d/* +# process initializer files, based on file extensions and permissions +docker_process_init_files() { + # gsql here for backwards compatiblilty "${gsql[@]}" + gsql=( docker_process_sql ) + + echo + local f + for f; do + case "$f" in + *.sh) + if [ -x "$f" ]; then + echo "$0: running $f" + "$f" + else + echo "$0: sourcing $f" + . "$f" + fi + ;; + *.sql) echo "$0: running $f"; docker_process_sql -f "$f"; echo ;; + *.sql.gz) echo "$0: running $f"; gunzip -c "$f" | docker_process_sql; echo ;; + *.sql.xz) echo "$0: running $f"; xzcat "$f" | docker_process_sql; echo ;; + *) echo "$0: ignoring $f" ;; + esac + echo + done +} + +# Execute sql script, passed via stdin (or -f flag of pqsl) +# usage: docker_process_sql [gsql-cli-args] +# ie: docker_process_sql --dbname=mydb <<<'INSERT ...' +# ie: docker_process_sql -f my-file.sql +# ie: docker_process_sql > $PGDATA/pg_hba.conf +} + +# append parameter to postgres.conf for connections +opengauss_setup_postgresql_conf() { + if [ -n "$PORT" ]; then + gs_guc set -D $PGDATA -c "port=$PORT" + else + gs_guc set -D $PGDATA -c "PORT=5432" + fi + gs_guc set -D $PGDATA -c "password_encryption_type = 1" \ + -c "wal_level=logical" \ + -c "max_wal_senders=16" \ + -c "max_replication_slots=9" \ + -c "wal_sender_timeout=0s" \ + -c "wal_receiver_timeout=0s" + + if [ -n "$SERVER_MODE" ]; then + gs_guc set -D $PGDATA -c "listen_addresses = '${HOST_IP}'" \ + -c "most_available_sync = on" \ + -c "remote_read_mode = off" \ + -c "pgxc_node_name = '$HOST_NAME'" \ + -c "application_name = '$HOST_NAME'" + set_REPLCONNINFO + if [ -n "$SYNCHRONOUS_STANDBY_NAMES" ]; then + gs_guc set -D $PGDATA -c "synchronous_standby_names=$SYNCHRONOUS_STANDBY_NAMES" + fi + else + gs_guc set -D $PGDATA -c "listen_addresses = '*'" + fi + + if [ -n "$db_config" ]; then + OLD_IFS="$IFS" + IFS="#" + db_config=($db_config) + for s in ${db_config[@]}; do + gs_guc set -D $PGDATA -c "$s" + done + IFS="$OLD_IFS" + fi + if [ -f "/tmp/db_config.conf" ]; then + cat /tmp/db_config.conf >> "$PGDATA/postgresql.conf" + fi +} + +opengauss_setup_mot_conf() { + echo "enable_numa = false" >> "$PGDATA/mot.conf" +} + +# start socket-only postgresql server for setting up or running scripts +# all arguments will be passed along as arguments to `postgres` (via pg_ctl) +docker_temp_server_start() { + if [ "$1" = 'gaussdb' ]; then + shift + fi + + # internal start of server in order to allow setup using gsql client + # does not listen on external TCP/IP and waits until start finishes + set -- "$@" -c listen_addresses='' -p "${PORT:-5432}" + + PGUSER="${PGUSER:-$GS_USER}" \ + gs_ctl -D "$PGDATA" \ + -o "$(printf '%q ' "$@")" \ + -w start +} + +# stop postgresql server after done setting up user and running scripts +docker_temp_server_stop() { + PGUSER="${PGUSER:-postgres}" \ + gs_ctl -D "$PGDATA" -m fast -w stop +} + +docker_slave_full_backup() { + echo "rebuild standby" + set +e + while : + do + gs_ctl restart -D "$PGDATA" -M $SERVER_MODE + gs_ctl build -D "$PGDATA" -M $SERVER_MODE -b full + if [ $? -eq 0 ]; then + break + else + echo "errcode=$?" + echo "build failed" + sleep 1000s + fi + done + set -e +} + +_create_config_og() { + docker_setup_env + # setup data directories and permissions (when run as root) + docker_create_db_directories + if [ "$(id -u)" = '0' ]; then + # then restart script as postgres user + exec gosu omm "$BASH_SOURCE" "$@" + fi + + # only run initialization on an empty data directory + if [ -z "$DATABASE_ALREADY_EXISTS" ]; then + docker_verify_minimum_env + + # check dir permissions to reduce likelihood of half-initialized database + ls /docker-entrypoint-initdb.d/ > /dev/null + + docker_init_database_dir + opengauss_setup_hba_conf + opengauss_setup_postgresql_conf + opengauss_setup_mot_conf + + # PGPASSWORD is required for gsql when authentication is required for 'local' connections via pg_hba.conf and is otherwise harmless + # e.g. when '--auth=md5' or '--auth-local=md5' is used in POSTGRES_INITDB_ARGS + export PGPASSWORD="${PGPASSWORD:-$GS_PASSWORD}" + docker_temp_server_start "$@" + if [ -z "$SERVER_MODE" ] || [ "$SERVER_MODE" = "primary" ]; then + docker_setup_db + docker_setup_user + docker_process_init_files /docker-entrypoint-initdb.d/* + fi + + if [ -n "$SERVER_MODE" ] && [ "$SERVER_MODE" != "primary" ]; then + docker_slave_full_backup + fi + docker_temp_server_stop + unset PGPASSWORD + + echo + echo 'openGauss init process complete; ready for start up.' + echo + else + echo + echo 'openGauss Database directory appears to contain a database; Skipping initialization' + echo + fi +} + +# process PEER_IPS, PEER_HOST_NAMES +# uses environment variables for input: PEER_IPS, PEER_HOST_NAMES +process_check_PEERS () { + # process PEER_IPS and PEER_HOST_NAMES to array + PEER_IPS_ARR=(${PEER_IPS//,/ }) + PEER_HOST_NAMES_ARR=(${PEER_HOST_NAMES//,/ }) + local len_ips=${#PEER_IPS_ARR[*]} + local len_names=${#PEER_HOST_NAMES_ARR[*]} + echo "len_ips=$len_ips" + echo "len_names=$len_names" + if [ ${len_ips} -ne ${len_names} ]; then + cat >&2 <<-'EOE' + Error: PEER_IPS are not matched with PEER_HOST_NAMES! + +EOE + exit 1 + fi + echo "compare peerips end" + if [ ${len_ips} -gt 8 ]; then + cat >&2 <<-'EOE' + Error: Opengauss support 8 standbies at most! + +EOE + exit 1 + fi + echo "compare peerips 8 length end" + # set +e + for i in $(seq 0 $(($len_ips - 1))); do + while : + do + + local tempip=`host ${PEER_IPS_ARR[$i]} | grep -Eo "[0-9]+.[0-9]+.[0-9]+.[0-9]+"` + echo "tempip get..." + if [ -n "$tempip" ]; then + echo "tempip compare..." + PEER_IPS_ARR[$i]="$tempip" + break + else + echo "tempip sleep..." + sleep 1s + fi + done + done + echo "tempip get end" + # set -e + PEER_NUM=$len_ips + echo "export STANDBY_NUM=$PEER_NUM" >> /home/omm/.bashrc +} + +# get etcd's parameter ETCD_MEMBERS +get_ETCD_MEMBERS () { + echo "----get_ETCD_MEMBERS-----" + ETCD_MEMBERS="${HOST_NAME}=http://${HOST_IP}:2380" + echo "ETCD_MEMBERS=$ETCD_MEMBERS" + local len=$(($PEER_NUM - 1)) + for i in $(seq 0 ${len}); do + echo "${i} ${PEER_HOST_NAMES_ARR[$i]} ${PEER_IPS_ARR[$i]}" + ETCD_MEMBERS="${ETCD_MEMBERS},${PEER_HOST_NAMES_ARR[$i]}=http://${PEER_IPS_ARR[$i]}:2380" + done + echo "ETCD_MEMBERS=$ETCD_MEMBERS" +} + +# get database's parameter replconninfoi +# uses environment variables for input: HOST_IP, PORT +get_replconninfoi () { + replconninfoi="localhost=${HOST_IP} localport=$((${PORT} + 1)) localheartbeatport=$((${PORT} + 2)) localservice=$((${PORT} + 4)) remotehost=$1 remoteport=$(($2 + 1)) remoteheartbeatport=$(($2 + 2)) remoteservice=$(($2 + 4))" +} + +# set database's parameter REPL_CONN_INFO +# uses environment variables for input: PEER_IPS +set_REPLCONNINFO () { + REPL_CONN_INFO="" + local len=$(($PEER_NUM - 1)) + for i in $(seq 0 $len); do + get_replconninfoi "${PEER_IPS_ARR[$i]}" $PORT + gs_guc set -D $PGDATA -c "replconninfo$((${i} + 1)) = '${replconninfoi}'" + done +} + +# change etcd's config +# uses environment variables for input: HOST_NAME, HOST_IP, INITIAL_CLUSTER_STATE +change_etcd_config() { + get_ETCD_MEMBERS + sed -i "s/^name: 'default'/name: '${HOST_NAME}'/" /home/omm/etcd.conf && \ + sed -i "s/^listen-peer-urls: http:\/\/localhost:2380/listen-peer-urls: http:\/\/${HOST_IP}:2380/" /home/omm/etcd.conf && \ + sed -i "s/^initial-advertise-peer-urls: http:\/\/localhost:2380/initial-advertise-peer-urls: http:\/\/${HOST_IP}:2380/" /home/omm/etcd.conf && \ + sed -i "s/^advertise-client-urls: http:\/\/localhost:2379/advertise-client-urls: http:\/\/${HOST_IP}:2379/" /home/omm/etcd.conf && \ + sed -i "s|^initial-cluster: initial-cluster|initial-cluster: ${ETCD_MEMBERS}|" /home/omm/etcd.conf + if [ -n "${INITIAL_CLUSTER_STATE}" ] && [ "${INITIAL_CLUSTER_STATE}" == "existing" ]; then + sed -i "s/initial-cluster-state: 'new'/initial-cluster-state: 'existing'/" /home/omm/etcd.conf + fi +} + +# get ETCD_HOSTS +get_ETCD_HOSTS () { + ETCD_HOSTS="${HOST_IP}:2379" + for i in $(seq 0 $len); do + ETCD_HOSTS="${ETCD_HOSTS},${PEER_IPS_ARR[$i]}:2379" + done +} + +# change patroni's config +# uses environment variables for input: HOST_NAME, HOST_IP, PORT, GS_PASSWORD, GS_PASSWORD +change_patroni_config() { + get_ETCD_HOSTS + sed -i "s/^name: name/name: ${HOST_NAME}/" /home/omm/patroni.yaml && \ + sed -i "s/^ listen: localhost:8008/ listen: ${HOST_IP}:8008/" /home/omm/patroni.yaml && \ + sed -i "s/^ connect_address: localhost:8008/ connect_address: ${HOST_IP}:8008/" /home/omm/patroni.yaml && \ + sed -i "s/^ host: localhost:2379/ hosts: ${ETCD_HOSTS}/" /home/omm/patroni.yaml && \ + sed -i "s/^ listen: localhost:16000/ listen: ${HOST_IP}:${PORT}/" /home/omm/patroni.yaml && \ + sed -i "s/^ connect_address: localhost:16000/ connect_address: ${HOST_IP}:${PORT}/" /home/omm/patroni.yaml + if [ -n "$GS_USERNAME" ] && [ "$GS_USERNAME" != "admin" ]; then + sed -i "s/^ username: admin/ username: $GS_USERNAME/" /home/omm/patroni.yaml + fi + sed -i "s/^ password: huawei_123/ password: $GS_PASSWORD/" /home/omm/patroni.yaml +} + +# add new members +# uses environment variables for input: +add_standby () { + source /home/omm/.bashrc + echo "STANDBY_NUM=$STANDBY_NUM" + if [ $STANDBY_NUM -gt 8 ]; then + cat >&2 <<-'EOE' + Error: Opengauss support 8 standbies at most and there are already 8 standbies now! + +EOE + exit 1 + fi + echo "NEW_MEMBER_IPS=$NEW_MEMBER_IPS" + echo "NEW_MEMBER_NAMES=$NEW_MEMBER_NAMES" + NEW_MEMBER_IPS_ARR=(${NEW_MEMBER_IPS//,/ }) + NEW_MEMBER_NAMES_ARR=(${NEW_MEMBER_NAMES//,/ }) + echo "NEW_MEMBER_IPS_ARR=${NEW_MEMBER_IPS_ARR[*]}" + echo "NEW_MEMBER_NAMES_ARR=${NEW_MEMBER_NAMES_ARR[*]}" + local len_ips=${#NEW_MEMBER_IPS_ARR[*]} + local len_names=${#NEW_MEMBER_NAMES_ARR[*]} + echo "len_ips=$len_ips" + echo "len_names=$len_names" + if [ $len_ips -ne $len_names ]; then + cat >&2 <<-'EOE' + Error: NEW_MEMBER_IPS are not matched with NEW_MEMBER_IPS! + +EOE + exit 1 + fi + if [ $len_ips -eq 0 ]; then + cat >&2 <<-'EOE' + Error: No new members! + +EOE + exit 1 + fi + if [ $(($STANDBY_NUM + len_ips)) -gt 8 ]; then + cat >&2 <<-'EOE' + Error: The cluster has already $STANDBY_NUM standbies now, so $len_ips standbies can't be added! + +EOE + exit 1 + fi + local len=$(($len_ips - 1)) + local member_list=`etcdctl member list` + echo -e "member_list=$member_list" + for i in $(seq 0 $len); do + if [[ $member_list =~ " started, ${NEW_MEMBER_NAMES_ARR[$i]}" ]]; then + echo "${NEW_MEMBER_IPS[$i]} has already been in the cluster." + else + while : + do + host ${NEW_MEMBER_IPS_ARR[$i]} && echo "" > /dev/null + if [ $? -eq 0 ]; then + NEW_MEMBER_IPS_ARR[$i]=`host ${NEW_MEMBER_IPS_ARR[$i]} | grep -Eo "[0-9]+.[0-9]+.[0-9]+.[0-9]+"` + echo "NEW_MEMBER_IPS: $i ${NEW_MEMBER_IPS_ARR[$i]}" + break + fi + done + if [[ $member_list == *unstarted*${NEW_MEMBER_IPS_ARR[$i]}* ]]; then + echo "${NEW_MEMBER_NAMES_ARR[$i]} has already been in the etcd cluster." + else + etcdctl member add ${NEW_MEMBER_NAMES_ARR[$i]} --peer-urls="http://${NEW_MEMBER_IPS_ARR[$i]}:2380" + fi + get_replconninfoi "${NEW_MEMBER_IPS_ARR[$i]}" $PORT + gs_guc reload -D $PGDATA -c "replconninfo$((${STANDBY_NUM} + ${i} + 1 ))='${replconninfoi}'" + fi + done + sed -i "s|STANDBY_NUM=${STANDBY_NUM}|STANDBY_NUM=$(($STANDBY_NUM + len_ips))|" /home/omm/.bashrc + echo "Etcd and database is ready to join the new member. Please start the new member." +} + +_main() { + if [ "$(id -u)" = '0' ]; then + id + # then restart script as postgres user + if [ -d "/var/lib/opengauss/data/" ]; then + chown omm:omm /var/lib/opengauss/data/ -R + fi + exec gosu omm "$BASH_SOURCE" "$@" + elif [ $# = 1 ] && [ "$1" = "patroni" ]; then + process_check_PEERS + # change etcd config file + echo "-------------------------change etcd config-------------------------" + change_etcd_config + # start etcd + echo "-------------------------start etcd-------------------------" + export ETCD_UNSUPPORTED_ARCH=arm64 + etcd --config-file /home/omm/etcd.conf > /var/log/etcd.log 2>&1 & + echo "-------------------------etcd.log-------------------------" + sleep 1s + cat /var/log/etcd.log + + # create and config database + echo "-------------------------prepare start-------------------------" + echo "-------------------------create and config opengauss-------------------------" + if [ "`ls -A $PGDATA`" = "" ]; then + _create_config_og + else + echo "database directory has already been exist" + cp "$PGDATA/pg_hba0.conf" "$PGDATA/pg_hba.conf" -f + opengauss_setup_hba_conf + opengauss_setup_postgresql_conf + if [ -n "$SERVER_MODE" ] && [ "$SERVER_MODE" != "primary" ]; then + docker_slave_full_backup + docker_temp_server_stop + fi + fi + + # change patroni config file + echo "change_patroni_config start..." + change_patroni_config + # start patroni + echo "start patroni start..." + source /home/omm/.bashrc + exec patroni /home/omm/patroni.yaml 2>&1 | tee /var/log/patroni.log + echo "start patroni end..." + elif [ "$1" = "list" ] || [ "$1" = "switchover" ] || [ "$1" = "failover" ]; then + patronictl -c /home/omm/patroni.yaml $1 + elif [ "$1" = "add_standby" ]; then + add_standby "$@" + else + exec "$@" + fi +} + +if ! _is_sourced; then + _main "$@" +fi diff --git a/docker-build/patroni-for-openGauss/openEuler_aarch64/entrypoint.sh_bak b/docker-build/patroni-for-openGauss/openEuler_aarch64/entrypoint.sh_bak new file mode 100644 index 0000000000000000000000000000000000000000..7ffffcacc1f66ee289c38d8802cda0871eb8c137 --- /dev/null +++ b/docker-build/patroni-for-openGauss/openEuler_aarch64/entrypoint.sh_bak @@ -0,0 +1,634 @@ +#!/usr/bin/env bash +set -Eeo pipefail + +# usage: file_env VAR [DEFAULT] +# ie: file_env 'XYZ_DB_PASSWORD' 'example' +# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of +# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature) + +export GAUSSHOME=/usr/local/opengauss +export PATH=$GAUSSHOME/bin:$PATH +export LD_LIBRARY_PATH=$GAUSSHOME/lib:$LD_LIBRARY_PATH +export LANG=en_US.UTF-8 + +file_env() { + local var="$1" + local fileVar="${var}_FILE" + local def="${2:-}" + if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then + echo >&2 "error: both $var and $fileVar are set (but are exclusive)" + exit 1 + fi + local val="$def" + if [ "${!var:-}" ]; then + val="${!var}" + elif [ "${!fileVar:-}" ]; then + val="$(< "${!fileVar}")" + fi + export "$var"="$val" + unset "$fileVar" +} + +# check to see if this file is being run or sourced from another script +_is_sourced() { + [ "${#FUNCNAME[@]}" -ge 2 ] \ + && [ "${FUNCNAME[0]}" = '_is_sourced' ] \ + && [ "${FUNCNAME[1]}" = 'source' ] +} + +# used to create initial opengauss directories and if run as root, ensure ownership belong to the omm user +docker_create_db_directories() { + local user; user="$(id -u)" + + mkdir -p "$PGDATA" + chmod 700 "$PGDATA" + + # ignore failure since it will be fine when using the image provided directory; + mkdir -p /var/run/opengauss || : + chmod 775 /var/run/opengauss || : + + # Create the transaction log directory before initdb is run so the directory is owned by the correct user + if [ -n "$POSTGRES_INITDB_XLOGDIR" ]; then + mkdir -p "$POSTGRES_INITDB_XLOGDIR" + if [ "$user" = '0' ]; then + find "$POSTGRES_INITDB_XLOGDIR" \! -user postgres -exec chown postgres '{}' + + fi + chmod 700 "$POSTGRES_INITDB_XLOGDIR" + fi + + # allow the container to be started with `--user` + if [ "$user" = '0' ]; then + find "$PGDATA" \! -user omm -exec chown omm '{}' + + find /var/run/opengauss \! -user omm -exec chown omm '{}' + + fi +} + +# initialize empty PGDATA directory with new database via 'initdb' +# arguments to `initdb` can be passed via POSTGRES_INITDB_ARGS or as arguments to this function +# `initdb` automatically creates the "postgres", "template0", and "template1" dbnames +# this is also where the database user is created, specified by `GS_USER` env +docker_init_database_dir() { + # "initdb" is particular about the current user existing in "/etc/passwd", so we use "nss_wrapper" to fake that if necessary + if ! getent passwd "$(id -u)" &> /dev/null && [ -e /usr/lib/libnss_wrapper.so ]; then + export LD_PRELOAD='/usr/lib/libnss_wrapper.so' + export NSS_WRAPPER_PASSWD="$(mktemp)" + export NSS_WRAPPER_GROUP="$(mktemp)" + echo "postgres:x:$(id -u):$(id -g):PostgreSQL:$PGDATA:/bin/false" > "$NSS_WRAPPER_PASSWD" + echo "postgres:x:$(id -g):" > "$NSS_WRAPPER_GROUP" + fi + + if [ -n "$POSTGRES_INITDB_XLOGDIR" ]; then + set -- --xlogdir "$POSTGRES_INITDB_XLOGDIR" "$@" + fi + + gs_initdb -w "$GS_PASSWORD" --nodename=opengauss --encoding=UTF-8 --locale=en_US.UTF-8 --dbcompatibility=PG -D $PGDATA + # unset/cleanup "nss_wrapper" bits + if [ "${LD_PRELOAD:-}" = '/usr/lib/libnss_wrapper.so' ]; then + rm -f "$NSS_WRAPPER_PASSWD" "$NSS_WRAPPER_GROUP" + unset LD_PRELOAD NSS_WRAPPER_PASSWD NSS_WRAPPER_GROUP + fi +} + +# print large warning if GS_PASSWORD is long +# error if both GS_PASSWORD is empty and GS_HOST_AUTH_METHOD is not 'trust' +# print large warning if GS_HOST_AUTH_METHOD is set to 'trust' +# assumes database is not set up, ie: [ -z "$DATABASE_ALREADY_EXISTS" ] +docker_verify_minimum_env() { + # check password first so we can output the warning before postgres + # messes it up + if [[ "$GS_PASSWORD" =~ ^(.{8,}).*$ ]] && [[ "$GS_PASSWORD" =~ ^(.*[a-z]+).*$ ]] && [[ "$GS_PASSWORD" =~ ^(.*[A-Z]).*$ ]] && [[ "$GS_PASSWORD" =~ ^(.*[0-9]).*$ ]] && [[ "$GS_PASSWORD" =~ ^(.*[#?!@$%^&*-]).*$ ]]; then + cat >&2 <<-'EOWARN' + + Message: The supplied GS_PASSWORD is meet requirements. + +EOWARN + else + cat >&2 <<-'EOWARN' + + Error: The supplied GS_PASSWORD is not meet requirements. + Please Check if the password contains uppercase, lowercase, numbers, special characters, and password length(8). + At least one uppercase, lowercase, numeric, special character. + Example: Enmo@123 +EOWARN + exit 1 + fi + if [ -z "$GS_PASSWORD" ] && [ 'trust' != "$GS_HOST_AUTH_METHOD" ]; then + # The - option suppresses leading tabs but *not* spaces. :) + cat >&2 <<-'EOE' + Error: Database is uninitialized and superuser password is not specified. + You must specify GS_PASSWORD to a non-empty value for the + superuser. For example, "-e GS_PASSWORD=password" on "docker run". + + You may also use "GS_HOST_AUTH_METHOD=trust" to allow all + connections without a password. This is *not* recommended. + +EOE + exit 1 + fi + if [ 'trust' = "$GS_HOST_AUTH_METHOD" ]; then + cat >&2 <<-'EOWARN' + ******************************************************************************** + WARNING: GS_HOST_AUTH_METHOD has been set to "trust". This will allow + anyone with access to the opengauss port to access your database without + a password, even if GS_PASSWORD is set. + It is not recommended to use GS_HOST_AUTH_METHOD=trust. Replace + it with "-e GS_PASSWORD=password" instead to set a password in + "docker run". + ******************************************************************************** +EOWARN + fi +} + +# usage: docker_process_init_files [file [file [...]]] +# ie: docker_process_init_files /always-initdb.d/* +# process initializer files, based on file extensions and permissions +docker_process_init_files() { + # gsql here for backwards compatiblilty "${gsql[@]}" + gsql=( docker_process_sql ) + + echo + local f + for f; do + case "$f" in + *.sh) + if [ -x "$f" ]; then + echo "$0: running $f" + "$f" + else + echo "$0: sourcing $f" + . "$f" + fi + ;; + *.sql) echo "$0: running $f"; docker_process_sql -f "$f"; echo ;; + *.sql.gz) echo "$0: running $f"; gunzip -c "$f" | docker_process_sql; echo ;; + *.sql.xz) echo "$0: running $f"; xzcat "$f" | docker_process_sql; echo ;; + *) echo "$0: ignoring $f" ;; + esac + echo + done +} + +# Execute sql script, passed via stdin (or -f flag of pqsl) +# usage: docker_process_sql [gsql-cli-args] +# ie: docker_process_sql --dbname=mydb <<<'INSERT ...' +# ie: docker_process_sql -f my-file.sql +# ie: docker_process_sql > $PGDATA/pg_hba.conf +} + +# append parameter to postgres.conf for connections +opengauss_setup_postgresql_conf() { + if [ -n "$PORT" ]; then + gs_guc set -D $PGDATA -c "port=$PORT" + else + gs_guc set -D $PGDATA -c "PORT=5432" + fi + gs_guc set -D $PGDATA -c "password_encryption_type = 1" \ + -c "wal_level=logical" \ + -c "max_wal_senders=16" \ + -c "max_replication_slots=9" \ + -c "wal_sender_timeout=0s" \ + -c "wal_receiver_timeout=0s" + + if [ -n "$SERVER_MODE" ]; then + gs_guc set -D $PGDATA -c "listen_addresses = '${HOST_IP}'" \ + -c "most_available_sync = on" \ + -c "remote_read_mode = off" \ + -c "pgxc_node_name = '$HOST_NAME'" \ + -c "application_name = '$HOST_NAME'" + set_REPLCONNINFO + if [ -n "$SYNCHRONOUS_STANDBY_NAMES" ]; then + gs_guc set -D $PGDATA -c "synchronous_standby_names=$SYNCHRONOUS_STANDBY_NAMES" + fi + else + gs_guc set -D $PGDATA -c "listen_addresses = '*'" + fi + + if [ -n "$db_config" ]; then + OLD_IFS="$IFS" + IFS="#" + db_config=($db_config) + for s in ${db_config[@]}; do + gs_guc set -D $PGDATA -c "$s" + done + IFS="$OLD_IFS" + fi + if [ -f "/tmp/db_config.conf" ]; then + cat /tmp/db_config.conf >> "$PGDATA/postgresql.conf" + fi +} + +opengauss_setup_mot_conf() { + echo "enable_numa = false" >> "$PGDATA/mot.conf" +} + +# start socket-only postgresql server for setting up or running scripts +# all arguments will be passed along as arguments to `postgres` (via pg_ctl) +docker_temp_server_start() { + if [ "$1" = 'gaussdb' ]; then + shift + fi + + # internal start of server in order to allow setup using gsql client + # does not listen on external TCP/IP and waits until start finishes + set -- "$@" -c listen_addresses='' -p "${PORT:-5432}" + + PGUSER="${PGUSER:-$GS_USER}" \ + gs_ctl -D "$PGDATA" \ + -o "$(printf '%q ' "$@")" \ + -w start +} + +# stop postgresql server after done setting up user and running scripts +docker_temp_server_stop() { + PGUSER="${PGUSER:-postgres}" \ + gs_ctl -D "$PGDATA" -m fast -w stop +} + +docker_slave_full_backup() { + echo "rebuild standby" + set +e + while : + do + gs_ctl restart -D "$PGDATA" -M $SERVER_MODE + gs_ctl build -D "$PGDATA" -M $SERVER_MODE -b full + if [ $? -eq 0 ]; then + break + else + echo "errcode=$?" + echo "build failed" + sleep 1000s + fi + done + set -e +} + +_create_config_og() { + docker_setup_env + # setup data directories and permissions (when run as root) + docker_create_db_directories + if [ "$(id -u)" = '0' ]; then + # then restart script as postgres user + exec gosu omm "$BASH_SOURCE" "$@" + fi + + # only run initialization on an empty data directory + if [ -z "$DATABASE_ALREADY_EXISTS" ]; then + docker_verify_minimum_env + + # check dir permissions to reduce likelihood of half-initialized database + ls /docker-entrypoint-initdb.d/ > /dev/null + + docker_init_database_dir + opengauss_setup_hba_conf + opengauss_setup_postgresql_conf + opengauss_setup_mot_conf + + # PGPASSWORD is required for gsql when authentication is required for 'local' connections via pg_hba.conf and is otherwise harmless + # e.g. when '--auth=md5' or '--auth-local=md5' is used in POSTGRES_INITDB_ARGS + export PGPASSWORD="${PGPASSWORD:-$GS_PASSWORD}" + docker_temp_server_start "$@" + if [ -z "$SERVER_MODE" ] || [ "$SERVER_MODE" = "primary" ]; then + docker_setup_db + docker_setup_user + docker_process_init_files /docker-entrypoint-initdb.d/* + fi + + if [ -n "$SERVER_MODE" ] && [ "$SERVER_MODE" != "primary" ]; then + docker_slave_full_backup + fi + docker_temp_server_stop + unset PGPASSWORD + + echo + echo 'openGauss init process complete; ready for start up.' + echo + else + echo + echo 'openGauss Database directory appears to contain a database; Skipping initialization' + echo + fi +} + +# process PEER_IPS, PEER_HOST_NAMES +# uses environment variables for input: PEER_IPS, PEER_HOST_NAMES +process_check_PEERS () { + # process PEER_IPS and PEER_HOST_NAMES to array + PEER_IPS_ARR=(${PEER_IPS//,/ }) + PEER_HOST_NAMES_ARR=(${PEER_HOST_NAMES//,/ }) + local len_ips=${#PEER_IPS_ARR[*]} + local len_names=${#PEER_HOST_NAMES_ARR[*]} + echo "len_ips=$len_ips" + echo "len_names=$len_names" + if [ ${len_ips} -ne ${len_names} ]; then + cat >&2 <<-'EOE' + Error: PEER_IPS are not matched with PEER_HOST_NAMES! + +EOE + exit 1 + fi + echo "compare peerips end" + if [ ${len_ips} -gt 8 ]; then + cat >&2 <<-'EOE' + Error: Opengauss support 8 standbies at most! + +EOE + exit 1 + fi + echo "compare peerips 8 length end" + # set +e + for i in $(seq 0 $(($len_ips - 1))); do + while : + do + + local tempip=`host ${PEER_IPS_ARR[$i]} | grep -Eo "[0-9]+.[0-9]+.[0-9]+.[0-9]+"` + echo "tempip get..." + if [ -n "$tempip" ]; then + echo "tempip compare..." + PEER_IPS_ARR[$i]="$tempip" + break + else + echo "tempip sleep..." + sleep 1s + fi + done + done + echo "tempip get end" + # set -e + PEER_NUM=$len_ips + echo "export STANDBY_NUM=$PEER_NUM" >> /home/omm/.bashrc +} + +# get etcd's parameter ETCD_MEMBERS +get_ETCD_MEMBERS () { + echo "----get_ETCD_MEMBERS-----" + ETCD_MEMBERS="${HOST_NAME}=http://${HOST_IP}:2380" + echo "ETCD_MEMBERS=$ETCD_MEMBERS" + local len=$(($PEER_NUM - 1)) + for i in $(seq 0 ${len}); do + echo "${i} ${PEER_HOST_NAMES_ARR[$i]} ${PEER_IPS_ARR[$i]}" + ETCD_MEMBERS="${ETCD_MEMBERS},${PEER_HOST_NAMES_ARR[$i]}=http://${PEER_IPS_ARR[$i]}:2380" + done + echo "ETCD_MEMBERS=$ETCD_MEMBERS" +} + +# get database's parameter replconninfoi +# uses environment variables for input: HOST_IP, PORT +get_replconninfoi () { + replconninfoi="localhost=${HOST_IP} localport=$((${PORT} + 1)) localheartbeatport=$((${PORT} + 2)) localservice=$((${PORT} + 4)) remotehost=$1 remoteport=$(($2 + 1)) remoteheartbeatport=$(($2 + 2)) remoteservice=$(($2 + 4))" +} + +# set database's parameter REPL_CONN_INFO +# uses environment variables for input: PEER_IPS +set_REPLCONNINFO () { + REPL_CONN_INFO="" + local len=$(($PEER_NUM - 1)) + for i in $(seq 0 $len); do + get_replconninfoi "${PEER_IPS_ARR[$i]}" $PORT + gs_guc set -D $PGDATA -c "replconninfo$((${i} + 1)) = '${replconninfoi}'" + done +} + +# change etcd's config +# uses environment variables for input: HOST_NAME, HOST_IP, INITIAL_CLUSTER_STATE +change_etcd_config() { + get_ETCD_MEMBERS + sed -i "s/^name: 'default'/name: '${HOST_NAME}'/" /home/omm/etcd.conf && \ + sed -i "s/^listen-peer-urls: http:\/\/localhost:2380/listen-peer-urls: http:\/\/${HOST_IP}:2380/" /home/omm/etcd.conf && \ + sed -i "s/^initial-advertise-peer-urls: http:\/\/localhost:2380/initial-advertise-peer-urls: http:\/\/${HOST_IP}:2380/" /home/omm/etcd.conf && \ + sed -i "s/^advertise-client-urls: http:\/\/localhost:2379/advertise-client-urls: http:\/\/${HOST_IP}:2379/" /home/omm/etcd.conf && \ + sed -i "s|^initial-cluster: initial-cluster|initial-cluster: ${ETCD_MEMBERS}|" /home/omm/etcd.conf + if [ -n "${INITIAL_CLUSTER_STATE}" ] && [ "${INITIAL_CLUSTER_STATE}" == "existing" ]; then + sed -i "s/initial-cluster-state: 'new'/initial-cluster-state: 'existing'/" /home/omm/etcd.conf + fi +} + +# get ETCD_HOSTS +get_ETCD_HOSTS () { + ETCD_HOSTS="${HOST_IP}:2379" + for i in $(seq 0 $len); do + ETCD_HOSTS="${ETCD_HOSTS},${PEER_IPS_ARR[$i]}:2379" + done +} + +# change patroni's config +# uses environment variables for input: HOST_NAME, HOST_IP, PORT, GS_PASSWORD, GS_PASSWORD +change_patroni_config() { + get_ETCD_HOSTS + sed -i "s/^name: name/name: ${HOST_NAME}/" /home/omm/patroni.yaml && \ + sed -i "s/^ listen: localhost:8008/ listen: ${HOST_IP}:8008/" /home/omm/patroni.yaml && \ + sed -i "s/^ connect_address: localhost:8008/ connect_address: ${HOST_IP}:8008/" /home/omm/patroni.yaml && \ + sed -i "s/^ host: localhost:2379/ hosts: ${ETCD_HOSTS}/" /home/omm/patroni.yaml && \ + sed -i "s/^ listen: localhost:16000/ listen: ${HOST_IP}:${PORT}/" /home/omm/patroni.yaml && \ + sed -i "s/^ connect_address: localhost:16000/ connect_address: ${HOST_IP}:${PORT}/" /home/omm/patroni.yaml + if [ -n "$GS_USERNAME" ] && [ "$GS_USERNAME" != "admin" ]; then + sed -i "s/^ username: admin/ username: $GS_USERNAME/" /home/omm/patroni.yaml + fi + sed -i "s/^ password: huawei_123/ password: $GS_PASSWORD/" /home/omm/patroni.yaml +} + +# add new members +# uses environment variables for input: +add_standby () { + source /home/omm/.bashrc + echo "STANDBY_NUM=$STANDBY_NUM" + if [ $STANDBY_NUM -gt 8 ]; then + cat >&2 <<-'EOE' + Error: Opengauss support 8 standbies at most and there are already 8 standbies now! + +EOE + exit 1 + fi + echo "NEW_MEMBER_IPS=$NEW_MEMBER_IPS" + echo "NEW_MEMBER_NAMES=$NEW_MEMBER_NAMES" + NEW_MEMBER_IPS_ARR=(${NEW_MEMBER_IPS//,/ }) + NEW_MEMBER_NAMES_ARR=(${NEW_MEMBER_NAMES//,/ }) + echo "NEW_MEMBER_IPS_ARR=${NEW_MEMBER_IPS_ARR[*]}" + echo "NEW_MEMBER_NAMES_ARR=${NEW_MEMBER_NAMES_ARR[*]}" + local len_ips=${#NEW_MEMBER_IPS_ARR[*]} + local len_names=${#NEW_MEMBER_NAMES_ARR[*]} + echo "len_ips=$len_ips" + echo "len_names=$len_names" + if [ $len_ips -ne $len_names ]; then + cat >&2 <<-'EOE' + Error: NEW_MEMBER_IPS are not matched with NEW_MEMBER_IPS! + +EOE + exit 1 + fi + if [ $len_ips -eq 0 ]; then + cat >&2 <<-'EOE' + Error: No new members! + +EOE + exit 1 + fi + if [ $(($STANDBY_NUM + len_ips)) -gt 8 ]; then + cat >&2 <<-'EOE' + Error: The cluster has already $STANDBY_NUM standbies now, so $len_ips standbies can't be added! + +EOE + exit 1 + fi + local len=$(($len_ips - 1)) + local member_list=`etcdctl member list` + echo -e "member_list=$member_list" + for i in $(seq 0 $len); do + if [[ $member_list =~ " started, ${NEW_MEMBER_NAMES_ARR[$i]}" ]]; then + echo "${NEW_MEMBER_IPS[$i]} has already been in the cluster." + else + while : + do + host ${NEW_MEMBER_IPS_ARR[$i]} && echo "" > /dev/null + if [ $? -eq 0 ]; then + NEW_MEMBER_IPS_ARR[$i]=`host ${NEW_MEMBER_IPS_ARR[$i]} | grep -Eo "[0-9]+.[0-9]+.[0-9]+.[0-9]+"` + echo "NEW_MEMBER_IPS: $i ${NEW_MEMBER_IPS_ARR[$i]}" + break + fi + done + if [[ $member_list == *unstarted*${NEW_MEMBER_IPS_ARR[$i]}* ]]; then + echo "${NEW_MEMBER_NAMES_ARR[$i]} has already been in the etcd cluster." + else + etcdctl member add ${NEW_MEMBER_NAMES_ARR[$i]} --peer-urls="http://${NEW_MEMBER_IPS_ARR[$i]}:2380" + fi + get_replconninfoi "${NEW_MEMBER_IPS_ARR[$i]}" $PORT + gs_guc reload -D $PGDATA -c "replconninfo$((${STANDBY_NUM} + ${i} + 1 ))='${replconninfoi}'" + fi + done + sed -i "s|STANDBY_NUM=${STANDBY_NUM}|STANDBY_NUM=$(($STANDBY_NUM + len_ips))|" /home/omm/.bashrc + echo "Etcd and database is ready to join the new member. Please start the new member." +} + +_main() { + if [ "$(id -u)" = '0' ]; then + id + # then restart script as postgres user + if [ -d "/var/lib/opengauss/data/" ]; then + chown omm:omm /var/lib/opengauss/data/ -R + fi + exec gosu omm "$BASH_SOURCE" "$@" + elif [ $# = 1 ] && [ "$1" = "patroni" ]; then + process_check_PEERS + # change etcd config file + echo "-------------------------change etcd config-------------------------" + change_etcd_config + # start etcd + echo "-------------------------start etcd-------------------------" + export ETCD_UNSUPPORTED_ARCH=arm64 + etcd --config-file /home/omm/etcd.conf > /var/log/etcd.log 2>&1 & + echo "-------------------------etcd.log-------------------------" + sleep 1s + cat /var/log/etcd.log + + # create and config database + echo "-------------------------prepare start-------------------------" + echo "-------------------------create and config opengauss-------------------------" + if [ "`ls -A $PGDATA`" = "" ]; then + _create_config_og + else + echo "database directory has already been exist" + cp "$PGDATA/pg_hba0.conf" "$PGDATA/pg_hba.conf" -f + opengauss_setup_hba_conf + opengauss_setup_postgresql_conf + if [ -n "$SERVER_MODE" ] && [ "$SERVER_MODE" != "primary" ]; then + docker_slave_full_backup + docker_temp_server_stop + fi + fi + + # change patroni config file + echo "change_patroni_config start..." + change_patroni_config + # start patroni + echo "start patroni start..." + source /home/omm/.bashrc + exec patroni /home/omm/patroni.yaml 2>&1 | tee /var/log/patroni.log + echo "start patroni end..." + elif [ "$1" = "list" ] || [ "$1" = "switchover" ] || [ "$1" = "failover" ]; then + patronictl -c /home/omm/patroni.yaml $1 + elif [ "$1" = "add_standby" ]; then + add_standby "$@" + else + exec "$@" + fi +} + +if ! _is_sourced; then + _main "$@" +fi diff --git a/docker-build/patroni-for-openGauss/openEuler_aarch64/etcd.conf.sample b/docker-build/patroni-for-openGauss/openEuler_aarch64/etcd.conf.sample new file mode 100644 index 0000000000000000000000000000000000000000..cbf3bce71d07b66078039a769c29043f2a32022a --- /dev/null +++ b/docker-build/patroni-for-openGauss/openEuler_aarch64/etcd.conf.sample @@ -0,0 +1,140 @@ +# This is the configuration file for the etcd server. + +# Human-readable name for this member. +name: 'default' + +# Path to the data directory. +data-dir: /tmp/etcd.data + +# Path to the dedicated wal directory. +wal-dir: /tmp/etcd.wal + +# Number of committed transactions to trigger a snapshot to disk. +snapshot-count: 10000 + +# Time (in milliseconds) of a heartbeat interval. +heartbeat-interval: 100 + +# Time (in milliseconds) for an election to timeout. +election-timeout: 1000 + +# Raise alarms when backend size exceeds the given quota. 0 means use the +# default quota. +quota-backend-bytes: 0 + +# List of comma separated URLs to listen on for peer traffic. +listen-peer-urls: http://localhost:2380 + +# List of comma separated URLs to listen on for client traffic. +listen-client-urls: http://0.0.0.0:2379 + +# Maximum number of snapshot files to retain (0 is unlimited). +max-snapshots: 5 + +# Maximum number of wal files to retain (0 is unlimited). +max-wals: 5 + +# Comma-separated white list of origins for CORS (cross-origin resource sharing). +cors: + +# List of this member's peer URLs to advertise to the rest of the cluster. +# The URLs needed to be a comma-separated list. +initial-advertise-peer-urls: http://localhost:2380 + +# List of this member's client URLs to advertise to the public. +# The URLs needed to be a comma-separated list. +advertise-client-urls: http://localhost:2379 + +# Discovery URL used to bootstrap the cluster. +discovery: + +# Valid values include 'exit', 'proxy' +discovery-fallback: 'proxy' + +# HTTP proxy to use for traffic to discovery service. +discovery-proxy: + +# DNS domain used to bootstrap initial cluster. +discovery-srv: + +# Initial cluster configuration for bootstrapping. +initial-cluster: initial-cluster + +# Initial cluster token for the etcd cluster during bootstrap. +initial-cluster-token: 'etcd-cluster' + +# Initial cluster state ('new' or 'existing'). +initial-cluster-state: 'new' + +# Reject reconfiguration requests that would cause quorum loss. +strict-reconfig-check: false + +# Accept etcd V2 client requests +enable-v2: true + +# Enable runtime profiling data via HTTP server +enable-pprof: true + +# Valid values include 'on', 'readonly', 'off' +proxy: 'off' + +# Time (in milliseconds) an endpoint will be held in a failed state. +proxy-failure-wait: 5000 + +# Time (in milliseconds) of the endpoints refresh interval. +proxy-refresh-interval: 30000 + +# Time (in milliseconds) for a dial to timeout. +proxy-dial-timeout: 1000 + +# Time (in milliseconds) for a write to timeout. +proxy-write-timeout: 5000 + +# Time (in milliseconds) for a read to timeout. +proxy-read-timeout: 0 + +client-transport-security: + # Path to the client server TLS cert file. + cert-file: + + # Path to the client server TLS key file. + key-file: + + # Enable client cert authentication. + client-cert-auth: false + + # Path to the client server TLS trusted CA cert file. + trusted-ca-file: + + # Client TLS using generated certificates + auto-tls: false + +peer-transport-security: + # Path to the peer server TLS cert file. + cert-file: + + # Path to the peer server TLS key file. + key-file: + + # Enable peer client cert authentication. + client-cert-auth: false + + # Path to the peer server TLS trusted CA cert file. + trusted-ca-file: + + # Peer TLS using generated certificates. + auto-tls: false + +# Enable debug-level logging for etcd. +log-level: debug + +logger: zap + +# Specify 'stdout' or 'stderr' to skip journald logging even when running under systemd. +log-outputs: [stderr] + +# Force to create a new one member cluster. +force-new-cluster: false + +auto-compaction-mode: periodic +auto-compaction-retention: "1" diff --git a/docker-build/patroni-for-openGauss/openEuler_aarch64/etcd.tar.gz b/docker-build/patroni-for-openGauss/openEuler_aarch64/etcd.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..0b8e942d8b28a18dd5b559120c1702aeec2bdc73 Binary files /dev/null and b/docker-build/patroni-for-openGauss/openEuler_aarch64/etcd.tar.gz differ diff --git a/docker-build/patroni-for-openGauss/openEuler_aarch64/gosu-amd64 b/docker-build/patroni-for-openGauss/openEuler_aarch64/gosu-amd64 new file mode 100644 index 0000000000000000000000000000000000000000..834951f8910b8f4f88d626a05c9c0cdce527f967 Binary files /dev/null and b/docker-build/patroni-for-openGauss/openEuler_aarch64/gosu-amd64 differ diff --git a/docker-build/patroni-for-openGauss/openEuler_aarch64/gosu-arm64 b/docker-build/patroni-for-openGauss/openEuler_aarch64/gosu-arm64 new file mode 100644 index 0000000000000000000000000000000000000000..925e16ed1ff020e522c815ae4b6b8349634ef30a Binary files /dev/null and b/docker-build/patroni-for-openGauss/openEuler_aarch64/gosu-arm64 differ diff --git a/docker-build/patroni-for-openGauss/openEuler_aarch64/gs_isready b/docker-build/patroni-for-openGauss/openEuler_aarch64/gs_isready new file mode 100644 index 0000000000000000000000000000000000000000..363bad4e3d73b6c1cd42883c16c45ae0cb4b2f23 Binary files /dev/null and b/docker-build/patroni-for-openGauss/openEuler_aarch64/gs_isready differ diff --git a/docker-build/patroni-for-openGauss/openEuler_aarch64/libpython3.7m.so.1.0 b/docker-build/patroni-for-openGauss/openEuler_aarch64/libpython3.7m.so.1.0 new file mode 100644 index 0000000000000000000000000000000000000000..7b3e7f1975b5079a05ade7de1b4023df5c96b2e1 Binary files /dev/null and b/docker-build/patroni-for-openGauss/openEuler_aarch64/libpython3.7m.so.1.0 differ diff --git a/docker-build/patroni-for-openGauss/openEuler_aarch64/openEuler_aarch64.repo b/docker-build/patroni-for-openGauss/openEuler_aarch64/openEuler_aarch64.repo new file mode 100644 index 0000000000000000000000000000000000000000..9725bf2428f95da4aa8d0356f23031d6a938f0be --- /dev/null +++ b/docker-build/patroni-for-openGauss/openEuler_aarch64/openEuler_aarch64.repo @@ -0,0 +1,30 @@ +#generic-repos is licensed under the Mulan PSL v2. +#You can use this software according to the terms and conditions of the Mulan PSL v2. +#You may obtain a copy of Mulan PSL v2 at: +# http://license.coscl.org.cn/MulanPSL2 +#THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +#IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +#PURPOSE. +#See the Mulan PSL v2 for more details. + +[OS] +name=OS +baseurl=http://repo.huaweicloud.com/openeuler/openEuler-20.03-LTS/OS/aarch64/ +enabled=1 +gpgcheck=1 +gpgkey=http://repo.huaweicloud.com/openeuler/openEuler-20.03-LTS/OS/aarch64/RPM-GPG-KEY-openEuler + +[everything] +name=everything +baseurl=http://repo.huaweicloud.com/openeuler/openEuler-20.03-LTS/everything/aarch64/ +enabled=1 +gpgcheck=1 +gpgkey=http://repo.huaweicloud.com/openeuler/openEuler-20.03-LTS/everything/aarch64/RPM-GPG-KEY-openEuler + +[EPOL] +name=EPOL +baseurl=http://repo.huaweicloud.com/openeuler/openEuler-20.03-LTS/EPOL/aarch64/ +enabled=1 +gpgcheck=1 +gpgkey=http://repo.huaweicloud.com/openeuler/openEuler-20.03-LTS/OS/aarch64/RPM-GPG-KEY-openEuler + diff --git a/docker-build/patroni-for-openGauss/openEuler_aarch64/openGauss-3.0.0-openEuler-64bit.tar.bz2 b/docker-build/patroni-for-openGauss/openEuler_aarch64/openGauss-3.0.0-openEuler-64bit.tar.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..c5d0ca38205696683be57425e2e3172c12eb109b Binary files /dev/null and b/docker-build/patroni-for-openGauss/openEuler_aarch64/openGauss-3.0.0-openEuler-64bit.tar.bz2 differ diff --git a/docker-build/patroni-for-openGauss/openEuler_aarch64/patroni-2.0.2.tar.gz b/docker-build/patroni-for-openGauss/openEuler_aarch64/patroni-2.0.2.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..7bc9e041cc4769ddc9a984903a57850d88c5bf42 Binary files /dev/null and b/docker-build/patroni-for-openGauss/openEuler_aarch64/patroni-2.0.2.tar.gz differ diff --git a/docker-build/patroni-for-openGauss/openEuler_aarch64/patroni.yaml.sample b/docker-build/patroni-for-openGauss/openEuler_aarch64/patroni.yaml.sample new file mode 100644 index 0000000000000000000000000000000000000000..6c4c5a0302dbd0ded8d148360c9d0b6ca5a4ef49 --- /dev/null +++ b/docker-build/patroni-for-openGauss/openEuler_aarch64/patroni.yaml.sample @@ -0,0 +1,66 @@ +scope: opengauss +namespace: /service +name: name + +restapi: + listen: localhost:8008 + connect_address: localhost:8008 + +etcd: + host: localhost:2379 + +bootstrap: + dcs: + ttl: 30 + loop_wait: 10 + retry_timeout: 10 + maximum_lag_on_failover: 1048576 + master_start_timeout: 300 + synchronous_mode: false + postgresql: + use_pg_rewind: true + use_slots: true + parameters: + wal_level: hotstandby + hot_standby: "on" + wal_keep_segments: 16 + max_wal_sender: 10 + max_replication_slots: 10 + wal_log_hints: "on" + + + + initdb: + - encoding: UTF8 + - data-checksums + + + + +postgresql: + listen: localhost:16000 + connect_address: localhost:16000 + data_dir: /var/lib/opengauss/data + bin_dir: /usr/local/opengauss/bin + config_dir: /var/lib/opengauss/data + custom_conf: /var/lib/opengauss/data/postgresql.conf + + authentication: + replication: + username: admin + password: huawei_123 + superuser: + username: admin + password: huawei_123 + rewind: + username: admin + password: huawei_123 + + + + +tags: + nofailover: false + noloadbalance: false + clonefrom: false + nosync: false diff --git a/docker-build/patroni-for-openGauss/openEuler_aarch64/psycopg2-2.8.6.tar.gz b/docker-build/patroni-for-openGauss/openEuler_aarch64/psycopg2-2.8.6.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..2d586450fade2413e10a39e4d2936ca8f7c87fa6 Binary files /dev/null and b/docker-build/patroni-for-openGauss/openEuler_aarch64/psycopg2-2.8.6.tar.gz differ diff --git a/docker-build/patroni-for-openGauss/openEuler_aarch64/psycopg2.tar.gz b/docker-build/patroni-for-openGauss/openEuler_aarch64/psycopg2.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..137df7d2934157eb4931af8f979db8e72cd4ce9d Binary files /dev/null and b/docker-build/patroni-for-openGauss/openEuler_aarch64/psycopg2.tar.gz differ diff --git a/docker-build/patroni-for-openGauss/openEuler_aarch64/wal2json.so b/docker-build/patroni-for-openGauss/openEuler_aarch64/wal2json.so new file mode 100644 index 0000000000000000000000000000000000000000..fc1effe31f424172f7fbab803b9e879a11cfe2ac Binary files /dev/null and b/docker-build/patroni-for-openGauss/openEuler_aarch64/wal2json.so differ