代码拉取完成,页面将自动刷新
#!/bin/bash
#==============================================================#
# File : configure
# Desc : generate pigsty.yml config according to env
# Ctime : 2021-05-17
# Mtime : 2024-08-25
# Path : configure
# Author : Ruohang Feng ([email protected])
# License : AGPLv3
#==============================================================#
PIGSTY_VERSION=v3.0.1
#--------------------------------------------------------------#
# Usage
#--------------------------------------------------------------#
# ./configure
# [-i|--ip <ip>]
# [-r|--region <region> [default|china|europe]
# [-c|--conf <confname> [meta|dual|trio|full|prod]
# [-n|--non-interactive]
# [-x|--proxy]
#==============================================================#
# args
# -i --ip <ip addr> : set local primary ip address
# -c --conf : conf, (el7|el8|el9|ubuntu20|debian|...)
# -n --non-interactive : flag, run as non-interactive mode
# -x --proxy : flag, setup proxy_env from environment
#==============================================================#
INTERACTIVE=true # run configure with interactive mode
PRIMARY_IP="" # primary IP address (do not use public IP)
MODE="" # config template (meta|dual|trio|full|prod)
REGION="" # default region (default|china|europe)
USE_PROXY=false # use global env http_proxy, https_proxy, all_proxy, no_proxy
DEFAULT_NO_PROXY="localhost,127.0.0.1,10.0.0.0/8,192.168.0.0/16,*.pigsty,*.aliyun.com,mirrors.*,mirror.*,*.myqcloud.com,*.tsinghua.edu.cn,*.fedoraproject.org"
#--------------------------------------------------------------#
# Utils
#--------------------------------------------------------------#
__CN='\033[0m';__CB='\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}"; }
ipv4_regexp='(([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])'
#--------------------------------------------------------------#
# Param
#--------------------------------------------------------------#
PROG_NAME="$(basename $0)"
PROG_DIR="$(cd $(dirname $0) && pwd)"
PIGSTY_HOME="${PROG_DIR}"
REPO_NAME=pigsty
NGINX_HOME=/www
REPO_DIR=${NGINX_HOME}/${REPO_NAME}
BIN_DIR=${PIGSTY_HOME}/files/bin
# extract os vendor & version from /etc/os-release
OS_VENDOR=""
OS_VERSION=""
OS_PACKAGE=""
OS_MANAGER=""
#----------------------------------------------#
# region
#----------------------------------------------#
# return 0 if behind gfw (inside mainland china), otherwise 1
function behind_gfw() {
local return_code=$(curl -I -s --connect-timeout 1 www.google.com -w %{http_code} | tail -n1)
if [ "${return_code}" = "200" ]; then
return 1
fi
return 0
}
function check_region(){
if [ "${REGION}" == "" ]; then
if behind_gfw; then
REGION=china # mainland china is behind GFW
else
REGION=default # otherwise use default mirror
fi
log_info "region = ${REGION}"
fi
}
#----------------------------------------------#
# proxy
#----------------------------------------------#
function check_proxy(){
if [[ "${USE_PROXY}" == "true" ]]; then
if [[ "${HTTP_PROXY}" == '' && ${http_proxy} != '' ]]; then
#log_info "use http_proxy instead of HTTP_PROXY"
HTTP_PROXY=${http_proxy}
fi
if [[ "${NO_PROXY}" == '' ]]; then
#log_info "use the default no proxy"
NO_PROXY=${DEFAULT_NO_PROXY}
fi
if [[ "${ALL_PROXY}" != '' && ${HTTP_PROXY} == '' ]]; then
#log_info "use ALL_PROXY as HTTP_PROXY"
HTTP_PROXY=${ALL_PROXY}
fi
if [[ "${ALL_PROXY}" != '' && ${HTTPS_PROXY} == '' ]]; then
#log_info "use ALL_PROXY as HTTPS_PROXY"
HTTPS_PROXY=${ALL_PROXY}
fi
log_info "proxy = from env"
fi
}
#----------------------------------------------#
# kernel
#----------------------------------------------#
function check_kernel(){
local kernel_name=$(uname -s)
if [[ "${kernel_name}" == "Linux" ]]; then
log_info "kernel = ${kernel_name}"
return 0
else
log_warn "kernel = ${kernel_name}, not supported, Linux only"
#exit 1
fi
}
#----------------------------------------------#
# machine
#----------------------------------------------#
function check_machine(){
local machine_name=$(uname -m)
if [[ "${machine_name}" == "x86_64" ]]; then
log_info "machine = ${machine_name}"
return 0
else
log_warn "machine = ${machine_name}, not supported, x86_64 only"
#exit 2
fi
}
#----------------------------------------------#
# os package manager (yum|apt|...)
#----------------------------------------------#
function check_package_manager(){
# get package / manager: rpm|deb and dnf|yum|apt|apt-get|zypper
if command -v dpkg >/dev/null 2>&1; then
OS_PACKAGE="deb"
if command -v apt >/dev/null 2>&1; then
OS_MANAGER="apt"
elif command -v apt-get >/dev/null 2>&1; then
OS_MANAGER="apt-get"
else
log_error "fail to determine os package manager for deb"
exit 4
fi
elif command -v rpm >/dev/null 2>&1; then
OS_PACKAGE="rpm"
if command -v dnf >/dev/null 2>&1; then
OS_MANAGER="dnf"
elif command -v yum >/dev/null 2>&1; then
OS_MANAGER="yum"
elif command -v zypper >/dev/null 2>&1; then
OS_MANAGER="zypper"
else
log_error "fail to determine os package manager for rpm"
exit 4
fi
else
log_error "fail to determine os package type"
exit 3
fi
log_info "package = ${OS_PACKAGE},${OS_MANAGER}"
}
#----------------------------------------------#
# os release (Linux|Darwin etc..)
#----------------------------------------------#
function check_vendor_version(){
if [[ -f /etc/os-release ]]; then
. /etc/os-release
OS_VENDOR="$ID"
OS_VERSION="$VERSION_ID"
if [[ $VERSION_ID == *.* ]]; then
OS_VERSION=$(echo "$VERSION_ID" | cut -d. -f1)
else
OS_VERSION="${VERSION_ID}"
fi
log_info "vendor = ${OS_VENDOR} (${NAME})"
log_info "version = ${OS_VERSION} (${VERSION_ID})"
return 0
else
log_warn "/etc/os-release file not found, unknown OS"
#exit 5
fi
}
#----------------------------------------------#
# sudo
#----------------------------------------------#
function can_nopass_sudo(){
local current_user=$(whoami)
if [[ "${current_user}" == "root" ]]; then
return 0
fi
if sudo -n ls >/dev/null 2>/dev/null; then
return 0
fi
return 1
}
function check_sudo(){
local current_user=$(whoami)
if can_nopass_sudo; then
log_info "sudo = ${current_user} ok"
else
log_warn "sudo = ${current_user} missing nopasswd"
log_warn "fix nopass sudo for '${current_user}' with sudo:"
log_hint "echo '%%${current_user} ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/${current_user}\n"
# exit 5 # we don't exit here , just a configure process
fi
}
#----------------------------------------------#
# ssh
#----------------------------------------------#
# One MUST have nopass to localhost with same user
# configure can fix that for you (via ssh-keygen)
function can_nopass_ssh(){
local current_user=$(whoami)
local user=${1-${current_user}}
local ipaddr=${2-'127.0.0.1'}
if ssh -oBatchMode=yes -o "StrictHostKeyChecking no" ${user}@${ipaddr} 'ls' 1>/dev/null 2>/dev/null; then
return 0
else
return 1
fi
}
function check_ssh(){
if can_nopass_ssh ; then
log_info "ssh = $(whoami)@127.0.0.1 ok"
return 0
else
log_warn "ssh = $(whoami)@127.0.0.1 failed"
# exit 6 # we don't exit here , just a configure process
fi
}
#----------------------------------------------#
# primary ip
#----------------------------------------------#
# One MUST configure a local primary IP address
# local primary ip are fetched in following order
# 1. if ip is given via -i|--ip , just use it
# 2. if only one ip is detected, just use it
# 3. if multiple ip detected, ask user for it (interactive mode)
# 4. if -n|non-interactive is set, abort on error
#----------------------------------------------#
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
}
function get_ip_count(){
echo $(hostname --all-ip-addresses 2>/dev/null | wc -w)
}
function list_ipaddr(){
local ipList=$(hostname --all-ip-addresses)
local i=0
for ip in $ipList
do
i=$((i+1))
local ipDetail=$(ip addr 2>/dev/null | grep "inet ${ip}")
printf " (${__CC}${i}${__CN}) ${__CR}${ip}${__CN}\t${__CY}${ipDetail}${__CN}\n"
done
}
function check_ipaddr(){
local primary_ip=${1-${PRIMARY_IP}}
local interactive=${2-${INTERACTIVE}}
# if ip is given, check it
if [[ ! -z "${primary_ip}" ]]; then
if is_valid_ip ${primary_ip}; then
log_info "primary_ip = ${primary_ip} (from argument)"
PRIMARY_IP=${primary_ip}
return 0
else
log_error "primary_ip = ${primary_ip} invalid (from argument)"
exit 7
fi
fi
local ipCount=$(get_ip_count)
if ((ipCount<1)); then
log_warn "primary_ip = probe failed, use 10.10.10.10"
PRIMARY_IP=10.10.10.10
return 0
fi
if ((ipCount==1)); then
log_info "primary_ip = $(hostname --all-ip-addresses) (from probe)"
PRIMARY_IP=$(hostname --all-ip-addresses | egrep -o '(([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])')
return 0
fi
# multiple IP detected
log_warn "Multiple IP address candidates found:"
list_ipaddr
# special case: demo fixed ip (10.10.10.10), we will choose it directly without asking!
if [[ $(hostname --all-ip-addresses) == *'10.10.10.10'* ]]; then
log_info "primary_ip = 10.10.10.10 (from demo)"
PRIMARY_IP="10.10.10.10"
return 0
fi
# ask for input if in interactive mode, abort on non-interactive mode
if [[ ${interactive} != "true" ]]; then
log_error "primary_ip = dilemma abort"
log_hint "HINT: specify ip with -i|--ip , or disable non-interactive mode\n"
exit 9
fi
log_input "INPUT primary_ip address (of current meta node, e.g 10.10.10.10):"
read -r
local primary_ip=${REPLY}
if is_valid_ip ${primary_ip}; then
log_info "primary_ip = ${primary_ip} (from input)"
PRIMARY_IP=${primary_ip}
return 0
else
log_error "primary_ip = ${primary_ip} invalid (from input)"
exit 9
fi
}
#----------------------------------------------#
# check admin
#----------------------------------------------#
# check whether current user have nopass ssh
# access to primary ip with sudo privilege set
function check_admin(){
local primary_ip=${1-${PRIMARY_IP}}
local current_user=$(whoami)
if ssh -t -o "StrictHostKeyChecking no" -o "ConnectTimeout=4" ${primary_ip} 'sudo -n ls' 1>/dev/null 2>/dev/null; then
log_info "admin = ${current_user}@${primary_ip} ok"
else
log_error "admin = ${current_user}@${primary_ip} failed (nopass ssh sudo failed)"
log_hint "check ${current_user} in sudoer, @${primary_ip} is ssh accessible\n"
# exit 10 # we don't exit here , just a configure process
fi
# if using root, warning
if [[ "${current_user}" == "root" ]]; then
log_warn "user = root is not recommended, sure?"
fi
}
#----------------------------------------------#
# check deployment mode
#----------------------------------------------#
function check_mode(){
local mode=${1-${MODE}}
local primary_ip=${2-${PRIMARY_IP}}
# if mode is explicitly set, just use it
if [[ ! -z "${mode}" ]]; then
log_info "mode = ${mode} (manually set)"
return 0
fi
# use el by default, and adhoc template for el7, will be obsolete soon (2024)
if [[ ${OS_PACKAGE} == "rpm" ]]; then
if [[ "${OS_VERSION}" == "7" ]]; then
MODE=default/el7 # deprecated os support: el7
log_warn "mode = el7, CentOS 7.9 EOL @ 2024-06-30, deprecated, consider using el8 or el9 instead"
return 0
elif [[ "${OS_VERSION}" == "8" ]]; then
MODE=default/el8
log_info "mode = el8"
return 0
elif [[ "${OS_VERSION}" == "9" ]]; then
MODE=default/el9
log_info "mode = el9"
return 0
fi
# fallback to el8 by default
log_warn "mode = ${OS_VENDOR} ${OS_VERSION} unknown, fallback to default/el8"
MODE=default/el8
return 0
fi
# use ubuntu by default
if [[ ${OS_PACKAGE} == "deb" ]]; then
if [[ "${OS_VENDOR}" == "debian" ]]; then
if [[ "${OS_VERSION}" == "11" ]]; then
MODE=default/d11 # deprecated os support: debian11
log_warn "mode = d11 (debian11), EOL @ 2024-08-14, deprecated, consider using debian12 instead"
return 0
elif [[ "${OS_VERSION}" == "12" ]]; then
MODE=default/d12
log_info "mode = d12 (debian12)"
return 0
fi
MODE=default/d12
log_warn "os = ${OS_VENDOR} ${OS_VERSION} unknown, fallback to debian 12"
return 0
elif [[ "${OS_VENDOR}" == "ubuntu" ]]; then
if [[ "${OS_VERSION}" == "20" ]]; then
MODE=default/u20 # deprecated os support: ubuntu20
log_warn "mode = u20 (ubuntu20.04), EOL @ 2025-04-23, deprecated, consider using ubuntu22.04 instead"
return 0
elif [[ "${OS_VERSION}" == "22" ]]; then
MODE=default/u22
log_info "mode = u22 (ubuntu22.04)"
return 0
fi
MODE=default/u22
log_warn "os = ${OS_VENDOR} ${OS_VERSION} unknown, fallback to ubuntu 22"
return 0
fi
fi
# if OS is not determined, fall backup to the generic conf/meta.yml
log_warn "mode = meta (fallback to generic config)"
MODE=meta
return 0
}
#----------------------------------------------#
# generate config
#----------------------------------------------#
function check_config(){
local primary_ip=${1-${PRIMARY_IP}}
local mode=${2-${MODE}} # use files/pigsty/${mode}.yml as template
local pigsty_home=${3-${PIGSTY_HOME}}
local config_src="${pigsty_home}/conf/${mode}.yml"
local config_dst="${pigsty_home}/pigsty.yml"
# panic if given config file not exists
if [[ ! -f ${config_src} ]]; then
log_error "config = conf/${mode}.yml not exists"
exit 11
fi
cat "${config_src}" > "${config_dst}"
# copy target config, and replace IP placeholder for singleton templates
case "${mode}" in
meta|default*|dbms*) # replace primary IP address for these config templates
sed -ie "s/10.10.10.10/${primary_ip}/g" "${config_dst}"
rm -rf "${config_dst}e"
;;
esac
# replace node_tune & pg_conf with tiny or oltp according to cpu count
if (($(getconf _NPROCESSORS_ONLN)>=4)); then
sed -ie "s/pg_conf: tiny.yml/pg_conf: oltp.yml/g" "${config_dst}"
sed -ie "s/node_tune: tiny/node_tune: oltp/g" "${config_dst}"
rm -rf "${config_dst}e"
fi
# replace region if not default
if [[ ${REGION} != "default" ]]; then
sed -ie 's/ region: default/ region: '"${REGION}"' /g' "${config_dst}"
rm -rf "${config_dst}e"
fi
# add proxy_env from current env
if [[ "${USE_PROXY}" == "true" ]]; then
local proxy_txt_ori=" proxy_env:"
local proxy_txt="${proxy_txt_ori}"
# build proxy_env config from non-empty environment variable
[[ "${HTTP_PROXY}" != "" ]] && proxy_txt="${proxy_txt}\n http_proxy: \"${HTTP_PROXY}\""
[[ "${HTTPS_PROXY}" != "" ]] && proxy_txt="${proxy_txt}\n https_proxy: \"${HTTPS_PROXY}\""
[[ "${ALL_PROXY}" != "" ]] && proxy_txt="${proxy_txt}\n all_proxy: \"${ALL_PROXY}\""
[[ "${NO_PROXY}" != "" ]] && proxy_txt="${proxy_txt}\n no_proxy: \"${NO_PROXY}\""
# remove existing proxy_env config and replace with the new one:
if [[ $proxy_txt != "${proxy_txt_ori}" ]]; then
sed -ie "/^\s*proxy_env:.*$/d" "${config_dst}"
sed -ie "/^\s*https\?_proxy:.*$/d" "${config_dst}"
sed -ie "/^\s*all_proxy:.*$/d" "${config_dst}"
sed -ie "/^\s*no_proxy:.*$/d" "${config_dst}"
sed -ie "s%^\(\s\{4\}region:.\+\)$%\1\n${proxy_txt}%g" "${config_dst}"
rm -rf "${config_dst}e"
fi
fi
rm -rf "${config_dst}e"
return 0
}
#----------------------------------------------#
# check utils
#----------------------------------------------#
# install ansible sshpass unzip wget yum , etc...
function check_utils(){
# check ansible is installed
if command -v ansible-playbook >/dev/null ; then
log_info "ansible = $(ansible --version | head -n1)"
else
log_warn "ansible = not found"
# exit 20 # we don't exit here, just a configure process
fi
}
#--------------------------------------------------------------#
# Main
#--------------------------------------------------------------#
function main(){
# arg parsing
while [ $# -gt 0 ]; do
case $1 in
-h|--help)
echo './configure [-n|--non-interactive] [-i|--ip <ipaddr>] [-c|--conf <confname>] [-x|--proxy]'
exit 0;;
-i|--ip) PRIMARY_IP="$2" ; shift;;
-r|--region) REGION="$2" ; shift;;
-m|--mode) MODE="$2" ; shift;;
-c|--conf|--config) MODE="$2" ; shift;;
-n|--non-interactive) INTERACTIVE=false ;;
-x|--proxy) USE_PROXY=true ;;
(--) shift; break;;
(-*) echo "$0: error - unrecognized option $1" 1>&2; exit 1;;
(*) break;;
esac
shift
done
log_hint "configure pigsty ${PIGSTY_VERSION} begin\n"
# check
check_region # region = default
check_kernel # kernel = Linux
check_machine # machine = x86_64
check_package_manager # package = rpm|deb, manager = dnf|yum|zypper|apt|apt-get
check_vendor_version # release = centos, version = 7,8,9...
check_sudo # current_user = NOPASSWD sudo
check_ssh # current_user = NOPASSWD ssh
check_proxy # use_proxy = true|false
check_ipaddr # primary_ip (arg|probe|input) (INTERACTIVE: ask for ip)
check_admin # check current_user@primary_ip nopass ssh sudo
check_mode # check config template
check_config # generate config according to primary_ip and mode
#check_utils # check ansible sshpass and other utils installed
log_info "configure pigsty done"
log_hint "proceed with ./install.yml \n"
}
main $@
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。