163 lines
5.7 KiB
Bash
Executable File
163 lines
5.7 KiB
Bash
Executable File
#!/bin/bash
|
|
set -uo pipefail
|
|
#==============================================================#
|
|
# File : etcd-add
|
|
# Desc : Create ETCD Cluster / Append Members
|
|
# Ctime : 2025-07-20
|
|
# Mtime : 2025-07-22
|
|
# Path : bin/etcd-add
|
|
# Deps : ansible-playbook, etcd.yml
|
|
# Docs : https://pigsty.io/docs/etcd/admin
|
|
# License : Apache-2.0 @ https://pigsty.io/docs/about/license/
|
|
# Copyright : 2018-2026 Ruohang Feng / Vonng (rh@vonng.com)
|
|
#==============================================================#
|
|
APP_NAME="$(basename $0)"
|
|
APP_DIR="$(cd $(dirname $0) && pwd)"
|
|
PIGSTY_HOME=$(cd $(dirname ${APP_DIR}) && pwd)
|
|
|
|
|
|
#--------------------------------------------------------------#
|
|
# Usage
|
|
#--------------------------------------------------------------#
|
|
# bin/etcd-add # create etcd cluster
|
|
# bin/etcd-add [ip...] # add new members to existing cluster
|
|
|
|
|
|
#--------------------------------------------------------------#
|
|
# Utils
|
|
#--------------------------------------------------------------#
|
|
__CN='\033[0m';__CK='\033[0;30m';__CR='\033[0;31m';__CG='\033[0;32m';
|
|
__CY='\033[0;33m';__CB='\033[0;34m';__CM='\033[0;35m';__CC='\033[0;36m';__CW='\033[0;37m';
|
|
function log_info() { printf "[${__CG} OK ${__CN}] ${__CG}$*${__CN}\n"; }
|
|
function log_warn() { printf "[${__CY}WARN${__CN}] ${__CY}$*${__CN}\n"; }
|
|
function log_error() { printf "[${__CR}FAIL${__CN}] ${__CR}$*${__CN}\n"; }
|
|
function log_debug() { printf "[${__CB}HINT${__CN}] ${__CB}$*${__CN}\n"; }
|
|
function log_input() { printf "[${__CM} IN ${__CN}] ${__CM}$*\n=> ${__CN}"; }
|
|
function log_hint() { printf "${__CB}$*${__CN}\n"; }
|
|
function log_line() { printf "${__CM}[$*] ===========================================${__CN}\n"; }
|
|
function is_valid_ip(){
|
|
if [[ "$1" =~ (([0-9]|[0-9]{2}|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[0-9]{2}|1[0-9]{2}|2[0-4][0-9]|25[0-5]) ]]; then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
#--------------------------------------------------------------#
|
|
# Param
|
|
#--------------------------------------------------------------#
|
|
ETCD_CLUSTER=${ETCD_CLUSTER:-'etcd'}
|
|
cd "${PIGSTY_HOME}"
|
|
|
|
#--------------------------------------------------------------#
|
|
# Create Entire Cluster [ 0 arg = create all ]
|
|
#--------------------------------------------------------------#
|
|
# if no args given, create entire etcd cluster
|
|
if (($# == 0)); then
|
|
log_line "WARNING"
|
|
log_warn "You are about to perform a etcd Create Operation!"
|
|
log_warn "This operation will CREATE & RESTART the etcd cluster!"
|
|
log_warn "It will not remove existing etcd cluster and data"
|
|
log_warn "but mis-configuration could lead to DOWNTIME!"
|
|
log_warn "if this is not what your want, Ctrl+C to abort before start!"
|
|
|
|
# Countdown from 5 to 1
|
|
for i in 5 4 3 2 1; do
|
|
log_hint "\rCountdown: $i seconds remaining..."
|
|
sleep 1
|
|
done
|
|
log_warn "Proceeding with etcd cluster create operation."
|
|
|
|
log_line "EXECUTE"
|
|
log_warn "create etcd cluster '${ETCD_CLUSTER}'"
|
|
log_hint "$ ./etcd.yml -l ${ETCD_CLUSTER}"
|
|
|
|
"${PIGSTY_HOME}/etcd.yml" -l "${ETCD_CLUSTER}"
|
|
|
|
if [[ $? -ne 0 ]]; then
|
|
log_line "FAILURE"
|
|
log_error "fail to create etcd cluster '${ETCD_CLUSTER}'"
|
|
exit 2
|
|
fi
|
|
log_line "SUMMARY"
|
|
log_info "create etcd cluster ${ETCD_CLUSTER} complete!"
|
|
exit 0
|
|
fi
|
|
|
|
|
|
#--------------------------------------------------------------#
|
|
# Append Members [1+ args = add ips ]
|
|
#--------------------------------------------------------------#
|
|
# if args given, append specific etcd members by IP
|
|
IP_LIST=""
|
|
TARGET_PATTERN=""
|
|
EXISTS_PATTERN="${ETCD_CLUSTER}"
|
|
for ((i=1; i<=$#; i++))
|
|
do
|
|
if ! is_valid_ip "${!i}"; then
|
|
log_error "invalid ip address given: ${!i}"
|
|
exit 1
|
|
fi
|
|
IP_LIST="${IP_LIST} ${!i}"
|
|
if [[ -z "${TARGET_PATTERN}" ]]; then
|
|
TARGET_PATTERN="${!i}"
|
|
else
|
|
TARGET_PATTERN="${TARGET_PATTERN},${!i}"
|
|
fi
|
|
EXISTS_PATTERN="${EXISTS_PATTERN},!${!i}"
|
|
done
|
|
|
|
#---------------------------------#
|
|
# Planning
|
|
#---------------------------------#
|
|
log_line "PLANNING"
|
|
log_info "append new etcd members: ${IP_LIST} to cluster '${ETCD_CLUSTER}'"
|
|
log_warn " append new members to cluster:"
|
|
log_info " $ ./etcd.yml-l '${TARGET_PATTERN}'"
|
|
|
|
log_line "WARNING"
|
|
log_warn "You are about to perform a etcd cluster expand Operation!"
|
|
log_warn "This operation will append new member to the existing etcd cluster!"
|
|
log_warn "Mis-configuration could lead to DOWNTIME!"
|
|
log_warn "if this is not what your want, Ctrl+C to abort before start!"
|
|
|
|
# Countdown from 3 to 1
|
|
for i in 3 2 1; do
|
|
log_hint "\rCountdown: $i seconds remaining..."
|
|
sleep 1
|
|
done
|
|
log_warn "Proceeding with etcd cluster expand operation."
|
|
|
|
#---------------------------------#
|
|
# Append Members
|
|
#---------------------------------#
|
|
log_line "EXECUTE"
|
|
log_warn "append etcd members${IP_LIST} to ${ETCD_CLUSTER}"
|
|
log_hint "$ ./etcd.yml -e etcd_init=existing -l '${TARGET_PATTERN}'"
|
|
|
|
"${PIGSTY_HOME}/etcd.yml" -e etcd_init=existing -l "${TARGET_PATTERN}"
|
|
|
|
if [[ $? -ne 0 ]]; then
|
|
log_line "FAILURE"
|
|
log_error "fail to append etcd members${IP_LIST} to ${ETCD_CLUSTER}"
|
|
exit 4
|
|
fi
|
|
log_info "append etcd members${IP_LIST} to ${ETCD_CLUSTER} complete"
|
|
|
|
#---------------------------------#
|
|
# Summary
|
|
#---------------------------------#
|
|
log_line "SUMMARY"
|
|
log_info "append etcd members ${IP_LIST} to ${ETCD_CLUSTER} success"
|
|
|
|
log_line "INSTRUCTIONS"
|
|
log_warn "also update existing etcd member config with"
|
|
log_hint "$ ./etcd.yml -l '${EXISTS_PATTERN}' --tags=etcd_config,etcd_launch -f 1"
|
|
|
|
log_warn "also update patroni etcd config with:"
|
|
log_hint ".$ ./pgsql.yml -t pg_conf,patroni_reload -e patroni_reload=true"
|
|
|
|
log_warn "also update vip-manager etcd config with: (if enabled)"
|
|
log_hint ".$ ./pgsql.yml -t pg_vip"
|
|
|
|
exit 0 |