This is an automated email from the ASF dual-hosted git repository.

jiafengzheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 1cc735f20b [feature](docker)Refactor Image build script (#16528)
1cc735f20b is described below

commit 1cc735f20bfd06f5fa1bc22daeeba08a5c01f4af
Author: FreeOnePlus <54164178+freeonep...@users.noreply.github.com>
AuthorDate: Fri Feb 10 18:30:54 2023 +0800

    [feature](docker)Refactor Image build script (#16528)
    
    
    Co-authored-by: Yijia Su <suyi...@selectdb.com>
---
 docker/runtime/be/Dockerfile              |   4 +-
 docker/runtime/be/resource/entry_point.sh | 184 ++++++++++++++++++
 docker/runtime/be/resource/init_be.sh     | 274 ++++++++++++++++++--------
 docker/runtime/fe/resource/init_fe.sh     | 307 ++++++++++++++++++++----------
 4 files changed, 588 insertions(+), 181 deletions(-)

diff --git a/docker/runtime/be/Dockerfile b/docker/runtime/be/Dockerfile
index d4b60eec65..95eda2ca1c 100644
--- a/docker/runtime/be/Dockerfile
+++ b/docker/runtime/be/Dockerfile
@@ -35,6 +35,8 @@ RUN apt-get update && \
        mv apache-doris-be-x.x.x-bin-x86_64 /opt/apache-doris/be
 
 ADD resource/init_be.sh /opt/apache-doris/be/bin
+ADD resource/entry_point.sh /usr/local/bin
+RUN chmod 755 /usr/local/bin/entry_point.sh
 RUN chmod 755 /opt/apache-doris/be/bin/init_be.sh
 
-ENTRYPOINT ["/opt/apache-doris/be/bin/init_be.sh"]
+ENTRYPOINT ["bash","entry_point.sh"]
diff --git a/docker/runtime/be/resource/entry_point.sh 
b/docker/runtime/be/resource/entry_point.sh
new file mode 100644
index 0000000000..ab2ec6a3d3
--- /dev/null
+++ b/docker/runtime/be/resource/entry_point.sh
@@ -0,0 +1,184 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+set -eo pipefail
+shopt -s nullglob
+
+# Obtain necessary and basic information to complete initialization
+
+# logging functions
+# usage: doris_[note|warn|error] $log_meg
+#    ie: doris_warn "task may be risky!"
+#   out: 2023-01-08T19:08:16+08:00 [Warn] [Entrypoint]: task may be risky!
+doris_log() {
+    local type="$1"
+    shift
+    # accept argument string or stdin
+    local text="$*"
+    if [ "$#" -eq 0 ]; then text="$(cat)"; fi
+    local dt="$(date -Iseconds)"
+    printf '%s [%s] [Entrypoint]: %s\n' "$dt" "$type" "$text"
+}
+doris_note() {
+    doris_log Note "$@"
+}
+doris_warn() {
+    doris_log Warn "$@" >&2
+}
+doris_error() {
+    doris_log ERROR "$@" >&2
+    exit 1
+}
+
+# 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' ]
+}
+
+docker_setup_env() {
+    declare -g DATABASE_ALREADY_EXISTS
+    if [ -d "${DORIS_HOME}/be/storage/data" ]; then
+        DATABASE_ALREADY_EXISTS='true'
+    fi
+}
+
+get_doris_args() {
+    local feServerArray=($(echo "${FE_SERVERS}" | awk '{gsub (/,/," "); print 
$0}'))
+    for i in "${feServerArray[@]}"; do
+        val=${i}
+        val=${val// /}
+        tmpFeId=$(echo "${val}" | awk -F ':' '{ sub(/fe/, ""); sub(/ /, ""); 
print$1}')
+        tmpFeIp=$(echo "${val}" | awk -F ':' '{ sub(/ /, ""); print$2}')
+        feIpArray[$tmpFeId]=${tmpFeIp}
+    done
+
+    declare -g MASTER_FE_IP BE_HOST_IP BE_HEARTBEAT_PORT
+    MASTER_FE_IP=${feIpArray[1]}
+    doris_note "masterFe = ${MASTER_FE_IP}"
+    BE_HOST_IP=$(echo "${BE_ADDR}" | awk -F ':' '{ sub(/ /, ""); print$1}')
+    BE_HEARTBEAT_PORT=$(echo "${BE_ADDR}" | awk -F ':' '{ sub(/ /, ""); 
print$2}')
+    doris_note "be_addr = ${BE_HOST_IP}:${BE_HEARTBEAT_PORT}"
+}
+
+# Execute sql script, passed via stdin
+# usage: docker_process_sql [mysql-cli-args]
+#    ie: docker_process_sql --database=mydb <<<'INSERT ...'
+#    ie: docker_process_sql --database=mydb <my-file.sql
+docker_process_sql() {
+    set +e
+    mysql -uroot -P9030 -h${MASTER_FE_IP} --comments "$@" 2>/dev/null
+}
+
+check_be_status() {
+    set +e
+    local is_fe_start=false
+    for i in {1..300}; do
+        if [[ $(($i % 20)) == 1 ]]; then
+            doris_warn "start check be status~"
+        fi
+        docker_process_sql <<<"show backends;" | grep 
"[[:space:]]${BE_HOST_IP}[[:space:]]" | grep 
"[[:space:]]${BE_HEARTBEAT_PORT}[[:space:]]" | grep "[[:space:]]true[[:space:]]"
+        be_join_status=$?
+        if [[ "${be_join_status}" == 0 ]]; then
+            doris_note "Verify that BE is registered to FE successfully"
+            is_fe_start=true
+            break
+        else
+            if [[ $(($i % 20)) == 1 ]]; then
+                doris_note "register is failed, wait next~"
+            fi
+        fi
+        sleep 1
+    done
+    if ! [[ $is_fe_start ]]; then
+        doris_error "Failed to register BE to FE!Tried 30 times!Maybe FE Start 
Failed!"
+    fi
+}
+
+# usage: docker_process_init_files [file [file [...]]]
+#    ie: docker_process_init_files /always-initdb.d/*
+# process initializer files, based on file extensions
+docker_process_init_files() {
+    local f
+    for f; do
+        case "$f" in
+        *.sh)
+            if [ -x "$f" ]; then
+                doris_note "$0: running $f"
+                "$f"
+            else
+                doris_note "$0: sourcing $f"
+                . "$f"
+            fi
+            ;;
+        *.sql)
+            doris_note "$0: running $f"
+            docker_process_sql <"$f"
+            echo
+            ;;
+        *.sql.bz2)
+            doris_note "$0: running $f"
+            bunzip2 -c "$f" | docker_process_sql
+            echo
+            ;;
+        *.sql.gz)
+            doris_note "$0: running $f"
+            gunzip -c "$f" | docker_process_sql
+            echo
+            ;;
+        *.sql.xz)
+            doris_note "$0: running $f"
+            xzcat "$f" | docker_process_sql
+            echo
+            ;;
+        *.sql.zst)
+            doris_note "$0: running $f"
+            zstd -dc "$f" | docker_process_sql
+            echo
+            ;;
+        *) doris_warn "$0: ignoring $f" ;;
+        esac
+        echo
+    done
+}
+
+_main() {
+    docker_setup_env
+    # get init args
+    get_doris_args
+    # Start Doris BE
+    {
+        set +e
+        bash init_be.sh 2>/dev/null
+    } &
+    # check BE started status
+    check_be_status
+    if [ -z ${DATABASE_ALREADY_EXISTS} ]; then
+        # run script
+        docker_process_init_files /docker-entrypoint-initdb.d/*
+    fi
+
+    # keep BE started status
+    wait
+    exec "$@"
+}
+
+if ! _is_sourced; then
+    _main "$@"
+fi
diff --git a/docker/runtime/be/resource/init_be.sh 
b/docker/runtime/be/resource/init_be.sh
index e4de6b7c7e..bd85416af6 100644
--- a/docker/runtime/be/resource/init_be.sh
+++ b/docker/runtime/be/resource/init_be.sh
@@ -16,90 +16,198 @@
 # specific language governing permissions and limitations
 # under the License.
 
-FE_SERVERS=""
-BE_ADDR=""
-
-ARGS=$(getopt -o -h: --long fe_servers:,be_addr: -n "$0" -- "$@")
-
-eval set -- "${ARGS}"
-
-while [[ -n "$1" ]]; do
-    case "$1" in
-    --fe_servers)
-        FE_SERVERS=$2
-        shift
-        ;;
-    --be_addr)
-        BE_ADDR=$2
-        shift
-        ;;
-    --) ;;
-
-    *)
-        echo "Error option $1"
-        break
-        ;;
-    esac
+set -eo pipefail
+shopt -s nullglob
+
+DORIS_HOME="/opt/apache-doris"
+
+# Obtain necessary and basic information to complete initialization
+
+# logging functions
+# usage: doris_[note|warn|error] $log_meg
+#    ie: doris_warn "task may be risky!"
+#   out: 2023-01-08T19:08:16+08:00 [Warn] [Entrypoint]: task may be risky!
+doris_log() {
+    local type="$1"
     shift
-done
-
-#echo FE_SERVERS = $FE_SERVERS
-echo "DEBUG >>>>>> FE_SERVERS=[${FE_SERVERS}]"
-echo "DEBUG >>>>>> BE_ADDR=[${BE_ADDR}]"
-
-feIpArray=()
-feEditLogPortArray=()
-
-IFS=","
-# shellcheck disable=SC2206
-feServerArray=(${FE_SERVERS})
-
-for i in "${!feServerArray[@]}"; do
-    val=${feServerArray[i]}
-    val=${val// /}
-    tmpFeId=$(echo "${val}" | awk -F ':' '{ sub(/fe/, ""); sub(/ /, ""); 
print$1}')
-    tmpFeIp=$(echo "${val}" | awk -F ':' '{ sub(/ /, ""); print$2}')
-    tmpFeEditLogPort=$(echo "${val}" | awk -F ':' '{ sub(/ /, ""); print$3}')
-    feIpArray[tmpFeId]=${tmpFeIp}
-    feEditLogPortArray[tmpFeId]=${tmpFeEditLogPort}
-done
-
-be_ip=$(echo "${BE_ADDR}" | awk -F ':' '{ sub(/ /, ""); print$1}')
-be_heartbeat_port=$(echo "${BE_ADDR}" | awk -F ':' '{ sub(/ /, ""); print$2}')
-
-echo "DEBUG >>>>>> feIpArray = ${feIpArray[*]}"
-echo "DEBUG >>>>>> feEditLogPortArray = ${feEditLogPortArray[*]}"
-echo "DEBUG >>>>>> masterFe = ${feIpArray[1]}:${feEditLogPortArray[1]}"
-echo "DEBUG >>>>>> be_addr = ${be_ip}:${be_heartbeat_port}"
-
-priority_networks=$(echo "${be_ip}" | awk -F '.' '{print$1"."$2"."$3".0/24"}')
-echo "DEBUG >>>>>> Append the configuration [priority_networks = 
${priority_networks}] to /opt/apache-doris/be/conf/fe.conf"
-echo "priority_networks = ${priority_networks}" 
>>/opt/apache-doris/be/conf/be.conf
-
-registerMySQL="mysql -uroot -P9030 -h${feIpArray[1]} -e \"alter system add 
backend '${be_ip}:${be_heartbeat_port}'\""
-echo "DEBUG >>>>>> registerMySQL = ${registerMySQL}"
-
-registerShell="/opt/apache-doris/be/bin/start_be.sh &"
-echo "DEBUG >>>>>> registerShell = ${registerShell}"
-
-for ((i = 0; i <= 20; i++)); do
-
-    ## check be register status
-    echo "mysql -uroot -P9030 -h${feIpArray[1]} -e \"show backends\" | grep \" 
${be_ip} \" | grep \" ${be_heartbeat_port} \""
-    mysql -uroot -P9030 -h"${feIpArray[1]}" -e "show backends" | grep 
"[[:space:]]${be_ip}[[:space:]]" | grep 
"[[:space:]]${be_heartbeat_port}[[:space:]]"
-    be_join_status=$?
-    echo "DEBUG >>>>>> The " "${i}" "time to register BE node, 
be_join_status=${be_join_status}"
-    if [[ "${be_join_status}" == 0 ]]; then
-        ## be registe successfully
-        echo "DEBUG >>>>>> run command ${registerShell}"
-        eval "${registerShell}"
+    # accept argument string or stdin
+    local text="$*"
+    if [ "$#" -eq 0 ]; then text="$(cat)"; fi
+    local dt="$(date -Iseconds)"
+    printf '%s [%s] [Entrypoint]: %s\n' "$dt" "$type" "$text"
+}
+doris_note() {
+    doris_log Note "$@"
+}
+doris_warn() {
+    doris_log Warn "$@" >&2
+}
+doris_error() {
+    doris_log ERROR "$@" >&2
+    exit 1
+}
+
+# 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' ]
+}
+
+docker_setup_env() {
+    declare -g DATABASE_ALREADY_EXISTS
+    if [ -d "${DORIS_HOME}/be/storage/data" ]; then
+        DATABASE_ALREADY_EXISTS='true'
+    fi
+}
+
+# Check the variables required for startup
+docker_required_variables_env() {
+    if [[ $FE_SERVERS =~ 
^.+:[1-2]{0,1}[0-9]{0,1}[0-9]{1}(\.[1-2]{0,1}[0-9]{0,1}[0-9]{1}){3}:[1-6]{0,1}[0-9]{1,4}(,.+:[1-2]{0,1}[0-9]{0,1}[0-9]{1}(\.[1-2]{0,1}[0-9]{0,1}[0-9]{1}){3}:[1-6]{0,1}[0-9]{1,4})*$
 ]]; then
+        doris_warn "FE_SERVERS" $FE_SERVERS
     else
-        ## be doesn't registe
-        echo "DEBUG >>>>>> run commnad ${registerMySQL}"
-        eval "${registerMySQL}"
-        if [[ "${i}" == 20 ]]; then
-            echo "DEBUG >>>>>> BE Start Or Register FAILED!"
+        doris_error "FE_SERVERS rule error!example: 
\$FE_NAME:\$FE_HOST_IP:\$FE_EDIT_LOG_PORT[,\$FE_NAME:\$FE_HOST_IP:\$FE_EDIT_LOG_PORT]..."
+    fi
+    if [[ $BE_ADDR =~ 
^[1-2]{0,1}[0-9]{0,1}[0-9]{1}(\.[1-2]{0,1}[0-9]{0,1}[0-9]{1}){3}:[1-6]{0,1}[0-9]{1,4}$
 ]]; then
+        doris_warn "BE_ADDR" $BE_ADDR
+    else
+        doris_error "BE_ADDR rule error!example: 
\$BE_HOST_IP:\$HEARTBEAT_SERVICE_PORT"
+    fi
+}
+
+get_doris_be_args() {
+    local feServerArray=($(echo "${FE_SERVERS}" | awk '{gsub (/,/," "); print 
$0}'))
+    for i in "${feServerArray[@]}"; do
+        val=${i}
+        val=${val// /}
+        tmpFeId=$(echo "${val}" | awk -F ':' '{ sub(/fe/, ""); sub(/ /, ""); 
print$1}')
+        tmpFeIp=$(echo "${val}" | awk -F ':' '{ sub(/ /, ""); print$2}')
+        tmpFeEditLogPort=$(echo "${val}" | awk -F ':' '{ sub(/ /, ""); 
print$3}')
+        check_arg "tmpFeIp" $tmpFeIp
+        feIpArray[$tmpFeId]=${tmpFeIp}
+        check_arg "tmpFeEditLogPort" $tmpFeEditLogPort
+        feEditLogPortArray[$tmpFeId]=${tmpFeEditLogPort}
+    done
+
+    declare -g MASTER_FE_IP BE_HOST_IP BE_HEARTBEAT_PORT PRIORITY_NETWORKS
+    MASTER_FE_IP=${feIpArray[1]}
+    check_arg "MASTER_FE_IP" $MASTER_FE_IP
+    BE_HOST_IP=$(echo "${BE_ADDR}" | awk -F ':' '{ sub(/ /, ""); print$1}')
+    check_arg "BE_HOST_IP" $BE_HOST_IP
+    BE_HEARTBEAT_PORT=$(echo "${BE_ADDR}" | awk -F ':' '{ sub(/ /, ""); 
print$2}')
+    check_arg "BE_HEARTBEAT_PORT" $BE_HEARTBEAT_PORT
+
+    PRIORITY_NETWORKS=$(echo "${BE_HOST_IP}" | awk -F '.' 
'{print$1"."$2"."$3".0/24"}')
+    check_arg "priority_networks" $PRIORITY_NETWORKS
+
+    doris_note "feIpArray = ${feIpArray[*]}"
+    doris_note "feEditLogPortArray = ${feEditLogPortArray[*]}"
+    doris_note "masterFe = ${feIpArray[1]}:${feEditLogPortArray[1]}"
+    doris_note "be_addr = ${BE_HOST_IP}:${BE_HEARTBEAT_PORT}"
+    doris_note "priority_networks = ${PRIORITY_NETWORKS}"
+    # wait fe start
+    check_be_status true
+}
+
+add_priority_networks() {
+    doris_note "add priority_networks ${1} to ${DORIS_HOME}/be/conf/be.conf"
+    echo "priority_networks = ${1}" >>${DORIS_HOME}/be/conf/be.conf
+}
+
+# Execute sql script, passed via stdin
+# usage: docker_process_sql sql_script
+docker_process_sql() {
+    set +e
+    mysql -uroot -P9030 -h${MASTER_FE_IP} --comments "$@" >2 &
+    1>/dev/null
+}
+
+register_be_to_fe() {
+    set +e
+    # check fe status
+    local is_fe_start=false
+    for i in {1..300}; do
+        if [[ $(($i % 20)) == 1 ]]; then
+            doris_note "Register BE to FE is failed. retry."
         fi
-        sleep 5
+        docker_process_sql <<<"alter system add backend 
'${BE_HOST_IP}:${BE_HEARTBEAT_PORT}'"
+        register_be_status=$?
+        if [[ $register_be_status == 0 ]]; then
+            doris_note "BE successfully registered to FE!"
+            is_fe_start=true
+            break
+        else
+            check_be_status
+            if [ -n "$BE_ALREADY_EXISTS" ]; then
+                doris_warn "Same backend already exists! No need to register 
again!"
+                break
+            fi
+            if [[ $(($i % 20)) == 1 ]]; then
+                doris_warn "register_be_status: ${register_be_status}"
+                doris_warn "BE failed registered to FE!"
+            fi
+        fi
+        sleep 1
+    done
+    if ! [[ $is_fe_start ]]; then
+        doris_error "Failed to register BE to FE!Tried 30 times!Maybe FE Start 
Failed!"
     fi
-done
+}
+
+# Check whether the passed parameters are empty to avoid subsequent task 
execution failures. At the same time,
+# enumeration checks can be added, such as checking whether a certain 
parameter appears repeatedly, etc.
+check_arg() {
+    if [ -z $2 ]; then
+        doris_error "$1 is null!"
+    fi
+}
+
+# 这里可用 docker_process_sql() 函数封装,为了方便调试,暂未封装
+check_be_status() {
+    set +e
+    for i in {1..300}; do
+        if [[ $(($i % 20)) == 1 ]]; then
+            if [[ $1 == true ]]; then
+                doris_note "MASTER FE is not started. retry."
+            else
+                doris_note "BE is not register. retry."
+            fi
+        fi
+        if [[ $1 == true ]]; then
+            docker_process_sql <<<"show frontends" | grep 
"[[:space:]]${MASTER_FE_IP}[[:space:]]"
+        else
+            docker_process_sql <<<"show backends" | grep 
"[[:space:]]${BE_HOST_IP}[[:space:]]" | grep 
"[[:space:]]${BE_HEARTBEAT_PORT}[[:space:]]"
+        fi
+        be_join_status=$?
+        if [[ "${be_join_status}" == 0 ]]; then
+            if [[ $1 == true ]]; then
+                doris_note "MASTER FE is started!"
+            else
+                doris_note "Init Check - Verify that BE is registered to FE 
successfully"
+                BE_ALREADY_EXISTS=true
+            fi
+            break
+        fi
+        sleep 1
+    done
+}
+
+_main() {
+    docker_setup_env
+    docker_required_variables_env
+    get_doris_be_args
+
+    if [ -z "$DATABASE_ALREADY_EXISTS" ]; then
+        add_priority_networks $PRIORITY_NETWORKS
+    fi
+
+    register_be_to_fe
+    check_be_status
+    doris_note "Ready to start BE!"
+    start_be.sh
+    exec "$@"
+}
+
+if ! _is_sourced; then
+    _main "$@"
+fi
diff --git a/docker/runtime/fe/resource/init_fe.sh 
b/docker/runtime/fe/resource/init_fe.sh
index 64e97a08dc..bcc546553d 100644
--- a/docker/runtime/fe/resource/init_fe.sh
+++ b/docker/runtime/fe/resource/init_fe.sh
@@ -16,111 +16,224 @@
 # specific language governing permissions and limitations
 # under the License.
 
-FE_ID=0
-FE_SERVERS=""
-
-ARGS=$(getopt -o -h: --long fe_id:,fe_servers: -n "$0" -- "$@")
-
-eval set -- "${ARGS}"
-
-while [[ -n "$1" ]]; do
-    case "$1" in
-    --fe_id)
-        FE_ID=$2
-        shift
-        ;;
-    --fe_servers)
-        FE_SERVERS=$2
-        shift
-        ;;
-    --) ;;
-
-    *)
-        echo "Error option $1"
-        break
-        ;;
-    esac
-    shift
-done
-
-echo "DEBUG >>>>>> FE_ID = [${FE_ID}]"
-echo "DEBUG >>>>>> FE_SERVERS = [${FE_SERVERS}]"
-
-feIpArray=()
-feEditLogPortArray=()
-
-IFS=","
-# shellcheck disable=SC2206
-feServerArray=(${FE_SERVERS})
-
-for i in "${!feServerArray[@]}"; do
-
-    val=${feServerArray[i]}
-    val=${val// /}
-    tmpFeId=$(echo "${val}" | awk -F ':' '{ sub(/fe/, ""); sub(/ /, ""); 
print$1}')
-    tmpFeIp=$(echo "${val}" | awk -F ':' '{ sub(/ /, ""); print$2}')
-    tmpFeEditLogPort=$(echo "${val}" | awk -F ':' '{ sub(/ /, ""); print$3}')
-    echo "DEBUG >>>>>> tmpFeId = [${tmpFeId}]"
-    echo "DEBUG >>>>>> tmpFeIp = [${tmpFeIp}]"
-    echo "DEBUG >>>>>> tmpFeEditLogPort = [${tmpFeEditLogPort}]"
-
-    feIpArray[tmpFeId]=${tmpFeIp}
-    feEditLogPortArray[tmpFeId]=${tmpFeEditLogPort}
-
-done
-
-echo "DEBUG >>>>>> feIpArray = ${feIpArray[*]}"
-echo "DEBUG >>>>>> feEditLogPortArray = ${feEditLogPortArray[*]}"
-echo "DEBUG >>>>>> masterFe = ${feIpArray[1]}:${feEditLogPortArray[1]}"
-echo "DEBUG >>>>>> currentFe = 
${feIpArray[FE_ID]}:${feEditLogPortArray[FE_ID]}"
-
-priority_networks=$(echo "${feIpArray[FE_ID]}" | awk -F '.' 
'{print$1"."$2"."$3".0/24"}')
-echo "DEBUG >>>>>> Append the configuration [priority_networks = 
${priority_networks}] to /opt/doris-fe/conf/fe.conf"
-echo "priority_networks = ${priority_networks}" 
>>/opt/apache-doris/fe/conf/fe.conf
-
-if [[ "${FE_ID}" != 1 ]]; then
+set -eo pipefail
+shopt -s nullglob
 
-    ## if current node is not master
-    ## PREPARE1: registe follower from mysql client
-    ## PREPARE2: call start_fe.sh using --help optional
-    ## STEP1: check master fe service works
-    ## STEP2: if feMasterStat == true; register PREPARE1 & PREPARE2 [retry 3 
times, sleep 10s]
+DORIS_HOME="/opt/apache-doris"
 
-    ## PREPARE1: registe follower from mysql client
-    registerMySQL="mysql -uroot -P9030 -h${feIpArray[1]} -e \"alter system add 
follower '${feIpArray[FE_ID]}:${feEditLogPortArray[FE_ID]}'\""
+# Obtain necessary and basic information to complete initialization
 
-    ## PREPARE2: call start_fe.sh using --help optional
-    registerShell="/opt/apache-doris/fe/bin/start_fe.sh --helper 
'${feIpArray[1]}:${feEditLogPortArray[1]}'"
+# logging functions
+# usage: doris_[note|warn|error] $log_meg
+#    ie: doris_warn "task may fe risky!"
+#   out: 2023-01-08T19:08:16+08:00 [Warn] [Entrypoint]: task may fe risky!
+doris_log() {
+    local type="$1"
+    shift
+    # accept argument string or stdin
+    local text="$*"
+    if [ "$#" -eq 0 ]; then text="$(cat)"; fi
+    local dt="$(date -Iseconds)"
+    printf '%s [%s] [Entrypoint]: %s\n' "$dt" "$type" "$text"
+}
+doris_note() {
+    doris_log Note "$@"
+}
+doris_warn() {
+    doris_log Warn "$@" >&2
+}
+doris_error() {
+    doris_log ERROR "$@" >&2
+    exit 1
+}
+
+# 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' ]
+}
+
+docker_setup_env() {
+    declare -g DATABASE_ALREADY_EXISTS
+    if [ -d "${DORIS_HOME}/fe/doris-meta/image" ]; then
+        DATABASE_ALREADY_EXISTS='true'
+    fi
+}
+
+# Check the variables required for startup
+docker_required_variables_env() {
+    if [[ $FE_SERVERS =~ 
^.+:[1-2]{0,1}[0-9]{0,1}[0-9]{1}(\.[1-2]{0,1}[0-9]{0,1}[0-9]{1}){3}:[1-6]{0,1}[0-9]{1,4}(,.+:[1-2]{0,1}[0-9]{0,1}[0-9]{1}(\.[1-2]{0,1}[0-9]{0,1}[0-9]{1}){3}:[1-6]{0,1}[0-9]{1,4})*$
 ]]; then
+        doris_warn "FE_SERVERS" $FE_SERVERS
+    else
+        doris_error "FE_SERVERS rule error!example: 
\$FE_NAME:\$FE_HOST_IP:\$FE_EDIT_LOG_PORT[,\$FE_NAME:\$FE_HOST_IP:\$FE_EDIT_LOG_PORT]..."
+    fi
+    if [[ $FE_ID =~ ^[1-9]{1}$ ]]; then
+        doris_warn "FE_ID" $FE_ID
+    else
+        doris_error "FE_ID rule error!If FE is the role of Master, please set 
FE_ID=1, and ensure that all IDs correspond to the IP of the current node."
+    fi
+}
+
+get_doris_fe_args() {
+    local feServerArray=($(echo "${FE_SERVERS}" | awk '{gsub (/,/," "); print 
$0}'))
+    for i in "${feServerArray[@]}"; do
+        val=${i}
+        val=${val// /}
+        tmpFeName=$(echo "${val}" | awk -F ':' '{ sub(/fe/, ""); sub(/ /, ""); 
print$1}')
+        tmpFeIp=$(echo "${val}" | awk -F ':' '{ sub(/ /, ""); print$2}')
+        tmpFeEditLogPort=$(echo "${val}" | awk -F ':' '{ sub(/ /, ""); 
print$3}')
+        check_arg "TMP_FE_NAME" $tmpFeName
+        feIpArray[$tmpFeName]=${tmpFeIp}
+        check_arg "TMP_FE_EDIT_LOG_PORT" $tmpFeEditLogPort
+        feEditLogPortArray[$tmpFeName]=${tmpFeEditLogPort}
+    done
 
-    echo "DEBUG >>>>>> FE is follower, fe_id = ${FE_ID}"
-    echo "DEBUG >>>>>> registerMySQL = 【${registerMySQL}】"
-    echo "DEBUG >>>>>> registerShell = 【${registerShell}】"
-    echo "DEBUG >>>>>> feMasterStat =  【mysql -uroot -P9030 -h ${feIpArray[1]} 
-e \"show frontends\" | grep \"${feIpArray[1]}_9010\" | grep -E 
\"true[[:space:]]*true\"】"
+    declare -g MASTER_FE_IP CURRENT_FE_IP MASTER_FE_EDIT_PORT 
CURRENT_FE_EDIT_PORT PRIORITY_NETWORKS CURRENT_FE_IS_MASTER
+    MASTER_FE_IP=${feIpArray[1]}
+    check_arg "MASTER_FE_IP" $MASTER_FE_IP
+    MASTER_FE_EDIT_PORT=${feEditLogPortArray[1]}
+    check_arg "MASTER_FE_EDIT_PORT" $MASTER_FE_EDIT_PORT
+    CURRENT_FE_IP=${feIpArray[FE_ID]}
+    check_arg "CURRENT_FE_IP" $CURRENT_FE_IP
+    CURRENT_FE_EDIT_PORT=${feEditLogPortArray[FE_ID]}
+    check_arg "CURRENT_FE_EDIT_PORT" $CURRENT_FE_EDIT_PORT
+
+    if [ ${MASTER_FE_IP} == ${CURRENT_FE_IP} ]; then
+        CURRENT_FE_IS_MASTER=true
+    else
+        CURRENT_FE_IS_MASTER=false
+    fi
+
+    PRIORITY_NETWORKS=$(echo "${CURRENT_FE_IP}" | awk -F '.' 
'{print$1"."$2"."$3".0/24"}')
+    check_arg "PRIORITY_NETWORKS" $PRIORITY_NETWORKS
+
+    doris_note "FE_IP_ARRAY = ${feIpArray[*]}"
+    doris_note "FE_EDIT_LOG_PORT_ARRAY = ${feEditLogPortArray[*]}"
+    doris_note "MASTER_FE = ${feIpArray[1]}:${feEditLogPortArray[1]}"
+    doris_note "CURRENT_FE = ${CURRENT_FE_IP}:${CURRENT_FE_EDIT_PORT}"
+    doris_note "PRIORITY_NETWORKS = ${PRIORITY_NETWORKS}"
+    # wait fe start
+    check_fe_status true
+}
+
+add_priority_networks() {
+    doris_note "add priority_networks ${1} to ${DORIS_HOME}/fe/conf/fe.conf"
+    echo "priority_networks = ${1}" >>${DORIS_HOME}/fe/conf/fe.conf
+}
+
+# Execute sql script, passed via stdin
+# usage: docker_process_sql sql_script
+docker_process_sql() {
+    set +e
+    mysql -uroot -P9030 -h${MASTER_FE_IP} --comments "$@" 2>/dev/null
+}
+
+docker_setup_db() {
+    set +e
+    # check fe status
+    local is_fe_start=false
+    if [ ${CURRENT_FE_IS_MASTER} == true ]; then
+        doris_note "Current FE is Master FE!  No need to register again!"
+        return
+    fi
+    for i in {1..300}; do
+        if [[ $(($i % 20)) == 1 ]]; then
+            doris_note "ADD FOLLOWER failed, retry."
+        fi
+        docker_process_sql <<<"alter system add FOLLOWER 
'${CURRENT_FE_IP}:${CURRENT_FE_EDIT_PORT}'"
+        register_fe_status=$?
+        if [[ $register_fe_status == 0 ]]; then
+            doris_note "FE successfully registered!"
+            is_fe_start=true
+            break
+        else
+            check_fe_status
+            if [ -n "$CURRENT_FE_ALREADY_EXISTS" ]; then
+                doris_warn "Same frontend already exists! No need to register 
again!"
+                break
+            fi
+            if [[ $(($i % 20)) == 1 ]]; then
+                doris_warn "register_fe_status: ${register_fe_status}"
+                doris_warn "FE failed registered!"
+            fi
+        fi
+        sleep 1
+    done
+    if ! [[ $is_fe_start ]]; then
+        doris_error "Failed to register CURRENT_FE to FE!Tried 30 times!Maybe 
FE Start Failed!"
+    fi
+}
+
+# Check whether the passed parameters are empty to avoid subsequent task 
execution failures. At the same time,
+# enumeration checks can fe added, such as checking whether a certain 
parameter appears repeatedly, etc.
+check_arg() {
+    if [ -z $2 ]; then
+        doris_error "$1 is null!"
+    fi
+}
+
+# 这里可用 docker_process_sql() 函数封装,为了方便调试,暂未封装
+check_fe_status() {
+    set +e
+    declare -g CURRENT_FE_ALREADY_EXISTS
+    if [ ${CURRENT_FE_IS_MASTER} == true ]; then
+        doris_note "Current FE is Master FE!  No need check fe status!"
+        return
+    fi
+    for i in {1..300}; do
+        if [[ $(($i % 20)) == 1 ]]; then
+            doris_note "try session Master FE."
+        fi
+        if [[ $1 == true ]]; then
+            docker_process_sql <<<"show frontends" | grep 
"[[:space:]]${MASTER_FE_IP}[[:space:]]" | grep 
"[[:space:]]${MASTER_FE_EDIT_PORT}[[:space:]]"
+        else
+            docker_process_sql <<<"show frontends" | grep 
"[[:space:]]${CURRENT_FE_IP}[[:space:]]" | grep 
"[[:space:]]${CURRENT_FE_EDIT_PORT}[[:space:]]"
+        fi
+        fe_join_status=$?
+        if [[ "${fe_join_status}" == 0 ]]; then
+            if [[ $1 == true ]]; then
+                doris_note "Master FE is started!"
+            else
+                doris_note "Verify that CURRENT_FE is registered to FE 
successfully"
+            fi
+            CURRENT_FE_ALREADY_EXISTS=true
+            break
+        else
+            if [[ $(($i % 20)) == 1 ]]; then
+                if [[ $1 == true ]]; then
+                    doris_note "Master FE is not started, retry."
+                else
+                    doris_warn "Verify that CURRENT_FE is registered to FE 
failed, retry."
+                fi
+            fi
+        fi
+        sleep 1
+    done
+}
 
-    ## STEP1: check FE master status
+_main() {
+    docker_setup_env
+    docker_required_variables_env
+    get_doris_fe_args
 
-    for ((i = 0; i <= 2000; i++)); do
+    if [ -z "$DATABASE_ALREADY_EXISTS" ]; then
+        add_priority_networks $PRIORITY_NETWORKS
+    fi
 
-        ## run STEP1 & STEP2, and then break
-        echo "Run registerShell command, [ registerMySQL = ${registerMySQL} ]"
-        eval "${registerMySQL}"
-        sleep 2
+    docker_setup_db
+    check_fe_status
+    doris_note "Ready to start CURRENT_FE!"
 
-        ## followerJoined: Joined = 0, doesn't join = 1
-        mysql -uroot -P9030 -h"${feIpArray[1]}" -e "show frontends" | grep 
"${feIpArray[FE_ID]}_9010" | grep -E "false[[:space:]]*false"
-        followerJoined=$?
+    if [ $CURRENT_FE_IS_MASTER == true ]; then
+        start_fe.sh
+    else
+        start_fe.sh --helper ${MASTER_FE_IP}:${MASTER_FE_EDIT_PORT}
+    fi
 
-        if [[ "${followerJoined}" == 0 ]]; then
-            echo "Run registerShell command, [ registerShell = 
${registerShell} ]"
-            eval "${registerShell}"
-            echo "The resutl of run registerShell command, [ res = $? ]"
-        fi
-        sleep 5
-    done
+    exec "$@"
+}
 
-else
-    registerShell="/opt/apache-doris/fe/bin/start_fe.sh"
-    eval "${registerShell}"
-    echo "DEBUG >>>>>> FE is master, fe_id = ${FE_ID}"
-    echo "DEBUG >>>>>> registerShell = ${registerShell}"
+if ! _is_sourced; then
+    _main "$@"
 fi


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to