From 177e4d2b26d81c1d5cfc1d0f597b736640d78eb3 Mon Sep 17 00:00:00 2001 From: Endial Fang Date: Thu, 14 Sep 2023 15:11:33 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 3 +- customer/usr/local/bin/common.sh | 148 ++++++++++++-------------- customer/usr/local/bin/entry.sh | 1 + customer/usr/local/bin/environment.sh | 4 +- customer/usr/local/bin/init.sh | 2 +- customer/usr/local/bin/run.sh | 2 +- 6 files changed, 75 insertions(+), 85 deletions(-) diff --git a/Dockerfile b/Dockerfile index 60a03b3..d427f4d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -59,6 +59,7 @@ RUN set -eux; \ RUN set -eux; \ APP_ARCH=`arch` \ APP_SRC="/tmp/${APP_NAME}-${APP_VER}"; \ + dpkgArch="$(dpkg --print-architecture)"; \ cd ${APP_SRC}; \ LDFLAGS="-L/usr/local/lib -L/usr/lib/${APP_ARCH}-linux-gnu" \ CPPFLAGS="-I/usr/local/include -D_GNU_SOURCE" \ @@ -125,7 +126,7 @@ RUN set -eux; \ select_source ${APT_SOURCE}; \ \ # 安装应用依赖的软件包及库 - install_pkg curl; \ + install_pkg ncat; \ install_pkg `cat /usr/local/${APP_NAME}/runDeps`; \ \ # 执行后处理脚本 diff --git a/customer/usr/local/bin/common.sh b/customer/usr/local/bin/common.sh index 2ebaa00..64415d2 100644 --- a/customer/usr/local/bin/common.sh +++ b/customer/usr/local/bin/common.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Ver: 1.3 by Endial Fang (endial@126.com) +# Ver: 1.4 by Endial Fang (endial@126.com) # # 应用通用业务处理函数 @@ -53,15 +53,16 @@ app_ensure_config_file_exist() { # $2 - 前缀(不含结束的"_") app_configure_from_environment() { local confFile="${1:?missing file}" - local envPrefix="${2:?missing parameters}" + local envPrefix="${2:-APP_CFG}" LOG_D "Configuration File: ${confFile}" if [[ ${file#*.} != "xml" ]]; then # 更新普通key-value配置文件,转换为小写后写入文件 - for var in "${!APP_CFG_@}"; do - key="$(echo "$var" | sed -e 's/^APP_CFG_//g' -e 's/___/-/g' -e 's/__/./g' | tr '[:upper:]' '[:lower:]')" + for var in $(eval echo \${!${envPrefix}_@}); do + key="$(echo "$var" | sed -e 's/^'${envPrefix}'_//g' -e 's/___/-/g' -e 's/__/./g' | tr '[:upper:]' '[:lower:]')" value="${!var}" + LOG_D " ${key}: ${value}" app_common_conf_set "$confFile" "$key" "$value" done else @@ -69,7 +70,7 @@ app_configure_from_environment() { for var in $(eval echo \${!${envPrefix}_@}); do key=$(echo "$var" | sed -e 's/^'${envPrefix}'_//g' -e 's/___/-/g' -e 's/__/./g') value="${!var}" - LOG_D " Process: ${key} => ${value}" + LOG_D " ${key}: ${value}" app_common_xml_set "${confFile}" "${key}" "${value}" done fi @@ -174,26 +175,31 @@ app_verify_minimum_env() { [[ "$error_code" -eq 0 ]] || exit "$error_code" } -# 更改默认监听地址为 "*" 或 "0.0.0.0",以对容器外提供服务;默认配置文件应当为仅监听 localhost(127.0.0.1) +# 更改默认监听地址为 "*" 或 "0.0.0.0",以对容器外提供服务 app_enable_remote_connections() { - LOG_D "Modify default config to enable all IP access" - + LOG_I "Modify default config to ENABLE external IP access" + +} + +# 更改默认监听地址为 "localhost" 或 "127.0.0.1",以禁止对容器外提供服务 +app_disable_remote_connections() { + LOG_I "Modify default config to DISABLE external IP access" + } # 检测依赖的服务端口是否就绪;该脚本依赖系统工具 'netcat' # 参数: # $1 - host:port app_wait_service() { - local serviceport=${1:?Missing server info} - local service=${serviceport%%:*} - local port=${serviceport#*:} + local serviceInfo=${1:?Missing server info} + local service=${serviceInfo%%:*} + local port=${serviceInfo#*:} local retry_seconds=5 - local max_try=100 + local max_try=6 let i=1 if [[ -z "$(which nc)" ]]; then - LOG_E "Nedd nc installed before, command: \"apt-get install netcat\"." - exit 1 + install_pkg ncat fi LOG_I "[0/${max_try}] check for ${service}:${port}..." @@ -203,13 +209,12 @@ app_wait_service() { result=$? until [ $result -eq 0 ]; do - LOG_D " [$i/${max_try}] not available yet" if (( $i == ${max_try} )); then LOG_E "${service}:${port} is still not available; giving up after ${max_try} tries." exit 1 fi + LOG_D " [$i/${max_try}] not available yet, try in ${retry_seconds}'s latter ..." - LOG_I "[$i/${max_try}] try in ${retry_seconds}s once again ..." let "i++" sleep ${retry_seconds} @@ -242,11 +247,16 @@ app_start_server_bg() { # debug_execute "rabbitmq-server" >/dev/null 2>&1 & #fi - # 通过命令或特定端口检测应用是否就绪 - LOG_D "Checking ${APP_NAME} ready status..." - # wait-for-port --timeout 60 "$ZOO_PORT_NUMBER" - - LOG_I "${APP_NAME} is ready for service..." + LOG_D "Checking ${APP_NAME} ready status..." + local counter=10 + while ! app_is_server_running ; do + LOG_D "Waiting for ${APP_NAME} to ready ... $counter" + if [[ "$counter" -ne 0 ]]; then + break + fi + sleep 1; + counter=$((counter - 1)) + done } # 停止应用服务 @@ -268,9 +278,10 @@ app_stop_server() { #fi # 检测停止是否完成 + LOG_D "Checking ${APP_NAME} running status..." local counter=10 while [[ "$counter" -ne 0 ]] && app_is_server_running; do - LOG_D "Waiting for ${APP_NAME} to stop..." + LOG_D "Waiting for ${APP_NAME} to stop ... $counter" sleep 1 counter=$((counter - 1)) done @@ -281,7 +292,7 @@ app_stop_server() { app_is_server_running() { LOG_D "Check if ${APP_NAME} is running..." local pid - pid="$(get_pid_from_file '/var/run/${APP_NAME}/${APP_NAME}.pid')" + pid="$(get_pid_from_file '${APP_PID_FILE}')" LOG_D "${APP_NAME} PID: ${pid}" if [[ -n "${pid}" ]]; then @@ -291,77 +302,43 @@ app_is_server_running() { fi } +app_is_server_not_running() { + if [[ app_is_server_running == false ]]; then + true + else + flse + fi +} + # 清理初始化应用时生成的临时文件 app_clean_tmp_file() { LOG_D "Clean ${APP_NAME} tmp files for init..." - -} - -# 在重新启动容器时,删除标志文件及必须删除的临时文件 (容器重新启动) -app_clean_from_restart() { - LOG_D "Clean ${APP_NAME} tmp files for restart..." local -r -a files=( - "/var/run/${APP_NAME}/${APP_NAME}.pid" + "${APP_PID_FILE}" ) for file in ${files[@]}; do if [[ -f "$file" ]]; then - LOG_I "Cleaning stale $file file" + LOG_D " Remove $file" rm "$file" fi done } -# 应用默认初始化操作 -# 执行完毕后,生成文件 ${APP_CONF_DIR}/.app_init_flag 及 ${APP_DATA_DIR}/.data_init_flag 文件 -app_default_init() { - app_clean_from_restart - LOG_D "Check init status of ${APP_NAME}..." - - # 检测配置文件是否存在 - if [[ ! -f "${APP_CONF_DIR}/.app_init_flag" ]]; then - LOG_I "No injected configuration file found, creating default config files..." - - # TODO: 生成配置文件,并按照容器运行参数进行相应修改 - - touch "${APP_CONF_DIR}/.app_init_flag" - echo "$(date '+%Y-%m-%d %H:%M:%S') : Init success." >> "${APP_CONF_DIR}/.app_init_flag" - else - LOG_I "User injected custom configuration detected!" - - LOG_D "Update configure files from environment..." - app_update_conf - fi - - if [[ ! -f "${APP_DATA_DIR}/.data_init_flag" ]]; then - LOG_I "Deploying ${APP_NAME} from scratch..." - - # 启动后台服务 - app_start_server_bg - - # TODO: 根据需要生成相应初始化数据 - - touch ${APP_DATA_DIR}/.data_init_flag - echo "$(date '+%Y-%m-%d %H:%M:%S') : Init success." >> ${APP_DATA_DIR}/.data_init_flag - else - LOG_I "Deploying ${APP_NAME} with persisted data..." - fi -} - # 用户自定义的前置初始化操作,依次执行目录 preinitdb.d 中的初始化脚本 # 执行完毕后,生成文件 ${APP_DATA_DIR}/.custom_preinit_flag app_custom_preinit() { - LOG_I "Check custom pre-init status of ${APP_NAME}..." + LOG_I "Process pre-init for ${APP_NAME}..." # 检测用户配置文件目录是否存在 preinitdb.d 文件夹,如果存在,尝试执行目录中的初始化脚本 - if [ -d "/srv/conf/${APP_NAME}/preinitdb.d" ]; then + if [ -d "${APP_CONF_DIR}/preinitdb.d" ]; then # 检测数据存储目录是否存在已初始化标志文件;如果不存在,检索可执行脚本文件并进行初始化操作 - if [[ -n $(find "/srv/conf/${APP_NAME}/preinitdb.d/" -type f -regex ".*\.\(sh\)") ]] && \ + if [[ -n $(find "${APP_CONF_DIR}/preinitdb.d/" -type f -regex ".*\.\(sh\)") ]] && \ [[ ! -f "${APP_DATA_DIR}/.custom_preinit_flag" ]]; then LOG_I "Process custom pre-init scripts from /srv/conf/${APP_NAME}/preinitdb.d..." # 检索所有可执行脚本,排序后执行 - find "/srv/conf/${APP_NAME}/preinitdb.d/" -type f -regex ".*\.\(sh\)" | sort | process_init_files + find "${APP_CONF_DIR}/preinitdb.d/" -type f -regex ".*\.\(sh\)" | sort | process_init_files touch "${APP_DATA_DIR}/.custom_preinit_flag" echo "$(date '+%Y-%m-%d %H:%M:%S') : Init success." >> "${APP_DATA_DIR}/.custom_preinit_flag" @@ -370,30 +347,35 @@ app_custom_preinit() { LOG_I "Custom preinit for ${APP_NAME} already done before, skipping initialization." fi fi +} - # 检测依赖的服务是否就绪 - #for i in ${SERVICE_PRECONDITION[@]}; do - # app_wait_service "${i}" - #done +# 应用默认初始化操作 +# 执行完毕后,生成文件 ${APP_CONF_DIR}/.app_init_flag 及 ${APP_DATA_DIR}/.data_init_flag 文件 +app_default_init() { + LOG_I "Process default init for ${APP_NAME}..." + + app_update_conf + app_enable_remote_connections } # 用户自定义的应用初始化操作,依次执行目录initdb.d中的初始化脚本 # 执行完毕后,生成文件 ${APP_DATA_DIR}/.custom_init_flag app_custom_init() { - LOG_I "Check custom initdb status of ${APP_NAME}..." + LOG_I "Process customer init ${APP_NAME}..." # 检测用户配置文件目录是否存在 initdb.d 文件夹,如果存在,尝试执行目录中的初始化脚本 - if [ -d "/srv/conf/${APP_NAME}/initdb.d" ]; then + if [ -d "${APP_CONF_DIR}/initdb.d" ]; then # 检测数据存储目录是否存在已初始化标志文件;如果不存在,检索可执行脚本文件并进行初始化操作 - if [[ -n $(find "/srv/conf/${APP_NAME}/initdb.d/" -type f -regex ".*\.\(sh\|sql\|sql.gz\)") ]] && \ + if [[ -n $(find "${APP_CONF_DIR}/initdb.d/" -type f -regex ".*\.\(sh\|sql\|sql.gz\)") ]] && \ [[ ! -f "${APP_DATA_DIR}/.custom_init_flag" ]]; then - LOG_I "Process custom init scripts from /srv/conf/${APP_NAME}/initdb.d..." + LOG_I "Process custom init scripts from ${APP_CONF_DIR}/initdb.d..." # 启动后台服务 + app_disable_remote_connections app_start_server_bg # 检索所有可执行脚本,排序后执行 - find "/srv/conf/${APP_NAME}/initdb.d/" -type f -regex ".*\.\(sh\|sql\|sql.gz\)" | sort | while read -r f; do + find "${APP_CONF_DIR}/initdb.d/" -type f -regex ".*\.\(sh\|sql\|sql.gz\)" | sort | while read -r f; do case "$f" in *.sh) if [[ -x "$f" ]]; then @@ -418,9 +400,15 @@ app_custom_init() { touch "${APP_DATA_DIR}/.custom_init_flag" echo "$(date '+%Y-%m-%d %H:%M:%S') : Init success." >> "${APP_DATA_DIR}/.custom_init_flag" LOG_I "Custom init for ${APP_NAME} complete." + + # 检测服务是否运行中;如果运行,则停止后台服务 + app_is_server_running && app_stop_server + app_clean_tmp_file + app_enable_remote_connections else LOG_I "Custom init for ${APP_NAME} already done before, skipping initialization." fi fi } + diff --git a/customer/usr/local/bin/entry.sh b/customer/usr/local/bin/entry.sh index be6d9cb..a663c6b 100755 --- a/customer/usr/local/bin/entry.sh +++ b/customer/usr/local/bin/entry.sh @@ -20,6 +20,7 @@ LOG_I "** Processing entry.sh **" if [[ "$(id -u)" == '0' ]] && [[ "$1" == "run.sh" ]]; then print_welcome_info /usr/local/bin/setup.sh + /usr/local/bin/init.sh # 执行应用启动脚本并替换当前进程 exec gosu "${APP_USER}" "$@" diff --git a/customer/usr/local/bin/environment.sh b/customer/usr/local/bin/environment.sh index ca0a32f..889fc77 100644 --- a/customer/usr/local/bin/environment.sh +++ b/customer/usr/local/bin/environment.sh @@ -36,8 +36,8 @@ export APP_CACHE_DIR="/var/cache/${APP_NAME}" export APP_RUN_DIR="/var/run/${APP_NAME}" # 应用配置参数 -export APP_CONF_FILE=${APP_CONF_DIR}/default.conf -export APP_PID_FILE="${APP_PID_FILE:-/var/run/${APP_NAME}/${APP_NAME}.pid}" +export APP_CONF_FILE="${APP_CONF_FILE:-${APP_CONF_DIR}/default.conf}" +export APP_PID_FILE="${APP_PID_FILE:-${APP_RUN_DIR}/${APP_NAME}.pid}" # 个性化变量 diff --git a/customer/usr/local/bin/init.sh b/customer/usr/local/bin/init.sh index 89701c4..5272030 100755 --- a/customer/usr/local/bin/init.sh +++ b/customer/usr/local/bin/init.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Ver: 1.2 by Endial Fang (endial@126.com) +# Ver: 1.3 by Endial Fang (endial@126.com) # # 应用初始化脚本 diff --git a/customer/usr/local/bin/run.sh b/customer/usr/local/bin/run.sh index 91a0cdc..a3842ca 100755 --- a/customer/usr/local/bin/run.sh +++ b/customer/usr/local/bin/run.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Ver: 1.5 by Endial Fang (endial@126.com) +# Ver: 1.6 by Endial Fang (endial@126.com) # # 应用启动脚本;组合默认的配置参数及容器启动时传入的 CMD 参数,启动应用