#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

#########################
# 广东堡塔安全技术有限公司
# 堡塔云WAF项目组
#########################

PWD_d=`pwd`
WAF_Port="8379"
install_path=/www
setup_path=$install_path/cloud_waf
waf_path=$setup_path/console
mirror=''
Default_Download_Url=""

NGINX_NAME="cloudwaf_nginx"
MYSQL_NAME="cloudwaf_mysql"
Containers="$NGINX_NAME $MYSQL_NAME"
nginx_command="docker exec $NGINX_NAME nginx -t"
mysql_command="docker exec $MYSQL_NAME mysql -V"


CPU_architecture=$(uname -m)
if [ "${CPU_architecture}" == "s390x" ];then
    echo -e "\033[31m 抱歉, 堡塔云WAF不支持s390x架构进行安装，请使用x86_64或者aarch64服务器架构 \033[0m"
    exit 1
elif [ "${CPU_architecture}" == "aarch64" ];then
    CPU_architecture="-aarch64"
elif [ "${CPU_architecture}" == "x86_64" ];then
    # x86_64 默认为空
    CPU_architecture=""
else
    echo " ${CPU_architecture} 此架构暂不支持."
    uname -a
    exit 1
fi

Mirror_file="btwaf_mysql_openresty-latest${CPU_architecture}.tar.gz"
Cloudwaf_file="cloudwaf-latest${CPU_architecture}.tar.gz"


old_dir="$install_path/old_cloud_waf"


qrencode(){
echo "
█████████████████████████████████████████
█████████████████████████████████████████
████ ▄▄▄▄▄ █▀ █▀▀▄▄▀██▀▄▀▄▀▄██ ▄▄▄▄▄ ████
████ █   █ █▀ ▄ █▀▀  ▀▀██▄  ▀█ █   █ ████
████ █▄▄▄█ █▀█ █▄██▀█▀▀▄ ▀▀▄▄█ █▄▄▄█ ████
████▄▄▄▄▄▄▄█▄█▄█ █ █ █▄▀▄▀ █▄█▄▄▄▄▄▄▄████
████▄   ▄▀▄▄▄ ▄█▄▄▄▄▀▄▄▀▀██ ▄▄▀▄█▄▀ ▀████
████▄▄ ▀ ▄▄ ▄ ▀ ▄█▄ ████ ▀ ▀█▀▄██▄▀▄█████
████ ▀▀█  ▄▄▄▄▀▄▀▀█▄▄ ▄▀▄▀▀ ▄ ▀▄▄▄█▀▀████
████ █ ▀█ ▄▄▄▄██▀ ▄ ██▄▀▄▀█▀▀█▄█▄█▀▄█████
████  ▀▀█▄▄█▀▀▄█▄█▄▄▄▄▄▀▄▀▀▀▄▄▀█▄▀█ ▀████
████▀     ▄▀▀ █ ▄█▀  ▄▄▀█  ▀▄▀▄▄ ▄▀▄█████
████▀▀▀▀ █▄ ▄  ▄▀▀▀▄▀▄▀▀▄▀▄  ▄▀ ▄▀█ ▀████
████ ██▀▄▄▄█▀  █▀ ▄ ▄▄ ▀▄ ▀█▀▄ ▀  ▀▄█████
████▄████▄▄█▀ ▄█▄█▄█▄▄▄▀▀█▀▀ ▄▄▄  ▀█ ████
████ ▄▄▄▄▄ █▄█▀ ▄█▀ █▄▄██ ▀  █▄█  ▀▄▀████
████ █   █ █  ▄▄▀▀▀▄▄▄▀▀▄█▀▀ ▄▄  ▀█  ████
████ █▄▄▄█ █ ▀ █▀ ▄ ▄█▄█▀ ▀▀▄▀ ▀▀ ▀██████
████▄▄▄▄▄▄▄█▄▄▄█▄█▄▄▄▄▄███▄▄▄█▄▄█▄█▄█████
█████████████████████████████████████████
█████████████████████████████████████████
            微信扫码入讨论群  
"

}


is64bit=$(getconf LONG_BIT)
if [ "${is64bit}" != '64' ];then
    echo -e "\033[31m 抱歉, 堡塔云WAF不支持32位系统, 请使用64位系统! \033[0m"
    exit 1
fi

if [ $(whoami) != "root" ];then
    echo -e "检测到非root用户安装，请尝试以下解决方案：\n   1.请切换到root用户安装 \n   2.尝试执行以下安装命令：\n     sudo bash $0 $@"
    exit 1
fi

total_memory=$(free -m | awk '/^Mem:/{print $2}')
if [ -z "$total_memory" ]; then
  total_memory=$(free -m | awk '/^内存：/{print $2}')
fi

if [ $total_memory -lt 600 ]; then

    echo -e "抱歉，服务器内存小于1G,不建议安装。"
    exit 1

fi

Check_Waf_Type(){

    if [ -s $waf_path/data/.cluster-state ]; then
        #echo "堡塔云WAF集群"
        number=$(cat $waf_path/data/.cluster-state)
        if [[ "$number" == "1" ]]; then
            echo "堡塔云WAF集群：主控"
            Master="yes"

        elif [ "$number" == "2" ]; then
            echo "堡塔云WAF集群：被控"
            Slave="yes"

        fi
    
    elif [ -f $waf_path/CloudWaf ] && [ ! -f $waf_path/data/.cluster-state ]; then
        echo "堡塔云WAF单机版"
        Standalone="yes"
    fi

}

GetSysInfo(){
    if [ -s "/etc/redhat-release" ];then
        SYS_VERSION=$(cat /etc/redhat-release)
    elif [ -s "/etc/issue" ]; then
        SYS_VERSION=$(cat /etc/issue)
    fi
    SYS_INFO=$(uname -a)
    SYS_BIT=$(getconf LONG_BIT)
    MEM_TOTAL=$(free -m|grep Mem|awk '{print $2}')
    CPU_INFO=$(getconf _NPROCESSORS_ONLN)

    echo -e ${SYS_VERSION}
    echo -e Bit:${SYS_BIT} Mem:${MEM_TOTAL}M Core:${CPU_INFO}
    echo -e ${SYS_INFO}
    echo -e "请截图以上报错信息发帖至论坛www.bt.cn/bbs求助，或加入微信群反馈"

}

Replace_symbol(){
# 更换符号为__
    text="${text#"${text%%[![:space:]]*}"}"
    text=${text%% }
    text=${text// /__}
    text=${text//\（/__}
    text=${text//\）/__}
    text=${text//\"/__}
    text=${text//\“/__}
    text=${text//\”/__}
    text=${text//\(/__}
    text=${text//\)/__}
    text=${text//\!/__}
    text=${text//\！/__}
    text=${text//:/__}
    text=${text//：/__}
    text=${text//,/__}
    text=${text//，/__}
    text=${text//。/__}
    text=${text//\$/__}
    text=${text//\{/__}
    text=${text//\}/__}
    text=${text//\[/__}
    text=${text//\]/__}
    text=${text//./__}
    text=${text//-/__}
    text=${text//>/__}
    text=${text//=/__}
    text=${text//\//__}
    text=${text//\'/__}
    
}

Little_tail(){

    arch=$(uname -m)

    if [ -s "/etc/redhat-release" ];then
        SYS_VERSION=$(cat /etc/redhat-release)
    elif Command_Exists hostnamectl; then
        SYS_VERSION=$(hostnamectl | grep "Operating System" | awk -F":" '{print $2}')
    elif [ -s "/etc/issue" ]; then
        SYS_VERSION=$(cat /etc/issue | tr '\n' ' ')
    fi
    
    text="${SYS_VERSION}"
    Replace_symbol
    #echo "$text"
    system="$text"

    curl -o /dev/null -fsSLk --connect-time 10 "https://api.bt.cn/bt_waf/setup_count?system=${system}&arch=${arch}&src_code=${src_code}&status=${status_01}&err_msg=${url_err_msg}" >/dev/null 2>&1
}

Red_Error(){
    if [[ $notice != "0" ]]; then
        # 0时不notice
        Submit_notice
    fi

    echo '=================================================';
    printf '\033[1;31;40m%b\033[0m\n' "$@";
    GetSysInfo

    if [[ "$@" == "" ]]; then
        url_err_msg="安装失败"
    else
        text="$@"
        Replace_symbol

        url_err_msg="$text"
        #echo "url_err_msg：$url_err_msg"
    fi
        
    status_01="0"
    Little_tail
    rm -f /tmp/submit /tmp/submit.gz

    # 二维码
    qrencode

    exit 1;

    
}

PORT(){

    if Command_Exists ss ; then
        command_port="ss"
        
    elif Command_Exists netstat ; then
        command_port="netstat"
        #使用netstat时进程显示nginx
    else
        echo -e "命令不存在，无法检查端口是否使用"
        command_port=""
    fi

    if [[ ! -z $command_port ]]; then
        if [ -d "$setup_path" ]; then
            # 排除了openresty docker-proxy
            check_command=$($command_port -ltnp | grep -E ':(80|443|33060)\s' |grep -v openresty|grep -v docker-proxy)
        else
            check_command=$($command_port -ltnp | grep -E ':(80|443|33060)\s')
        fi

        if [[ ! -z "$check_command" ]]; then
            echo "$check_command"
            echo -e "\033[31m堡塔云WAF需要使用 80 443 33060 端口,系统内已有服务使用,无法进行安装.\n建议使用全新系统或者修改相关程序端口再安装. \033[0m"
            url_err_msg="端口占用"
            status_01="0"
            Little_tail
            exit 1
        fi
    fi
}

Check_Port(){
    if ! Command_Exists docker; then
        PORT
    else
        check=$(docker ps |grep -wE "$NGINX_NAME|$MYSQL_NAME")
        if [[ -z "$check" ]]; then
            PORT
        fi
    fi
}

Submit_notice() {
     if [ "$offline_install" != "offline" ] && [[ -s /tmp/waf_install_log.txt ]]; then
        if [ ! -s /tmp/submit.gz ]; then
            if [ -f "$setup_path/submit.gz" ]; then
                \cp -arfp $setup_path/submit.gz /tmp/submit.gz
            else
                if [ -z "$download_Url" ]; then
                    get_node_url >/dev/null 2>&1
                fi
                wget --no-check-certificate -q -O /tmp/submit.gz $download_Url/cloudwaf/package/submit.gz -t 5 -T 10            
            fi
        fi
        gzip -d /tmp/submit.gz -c > /tmp/submit
        chmod 755 /tmp/submit
        /tmp/submit "" /tmp/waf_install_log.txt >/dev/null 2>&1
    fi
    #cat /tmp/waf_install_log.txt
}

Script_Command() {
    # 使用 Script_Command 时 $? 要修改成 $exit_code 才能正常获取返回值

    if [[ "$@" == "" ]]; then
        echo "变量为空"
    fi

    if Command_Exists script; then
        script -q -c "$@ && echo 0 > /tmp/exit_code.txt || echo 1 > /tmp/exit_code.txt" /tmp/waf_install_log.txt
        exit_code=$(cat /tmp/exit_code.txt)
        #echo $exit_code
        if [[ $exit_code == "0" ]]; then
            echo > /tmp/waf_install_log.txt
        else
            Submit_notice
            notice="0"
        fi
    else
        bash -c "$@"
        exit_code=$?
        #echo $exit_code
    fi
}

LXC_install_tips (){
    # 检查是否在LXC容器中
    System_Info=$(hostnamectl)
    check_container=$(echo "$System_Info" |grep "Chassis"|awk -F":" '{print $2}')
    #echo $check_container
    if [[ "$check_container" =~ "container" ]];then
        echo -e "\033[33m在LXC容器安装,可能无法正常安装,Docker可能无法正确获取CPU核心数,会导致nginx在运行时系统死机并且负载高,\n建议您使用VPS或物理机进行安装\033[0m"
        echo -e ""
        echo -e "\033[33m必须开启 \"无特权的容器 (Unprivileged container)\"、\"嵌套 (nesting)\"，否则无法启动容器。\033[0m"
        echo "请确认是否继续进行安装？"
        while [ "$lxc" != 'y' ] && [ "$lxc" != 'n' ]; do
            read -p "Please confirm whether in LXC container continue install? (y/n): " lxc;
        done

        if [ "$lxc" == 'n' ];then
            echo "安装已取消."
            exit;
        fi

        LXC_install="yes"
    fi
}

Check_Disk_Space(){
    df_Th=$(df -Th)
    #echo "$df_Th"
    root_df_Th=$( echo "$df_Th"|grep -w /|awk '{print $6}')
    root_df_Th2=$( echo "$df_Th"|grep -w /|awk '{print $5}')
    a=$(echo $root_df_Th|awk -F "%" '{print $1}')
    echo -e "当前/目录已使用: ${root_df_Th} 可用：${root_df_Th2}"
    if [ $a -ge 98 ];then
        echo -e "当前/目录磁盘剩余空间小于2% 可用：${root_df_Th2},可能是因此导致堡塔云WAF无法正常使用."
    fi
    www_df_Th=$(echo "$df_Th"|grep -w /www|awk '{print $6}')
    www_df_Th2=$(echo "$df_Th"|grep -w /www|awk '{print $5}')
    b=$(echo $www_df_Th|awk -F "%" '{print $1}')
    if [[ ! -z $www_df_Th ]]; then
        echo -e "当前/www目录已使用: ${www_df_Th} 可用：${www_df_Th2}"
        if [ $b -ge 98 ];then
            echo -e "当前/www目录磁盘剩余空间小于2% 可用：${www_df_Th2},可能是因此导致堡塔云WAF无法正常使用."
        fi
    fi

    #查看 Inodes
    df_I=$(df -i)
    #echo "$df_I"
    root_df_I=$( echo "$df_I"|grep -w /|awk '{print $5}')
    c=$(echo $root_df_I|awk -F "%" '{print $1}')
    echo -e "当前/目录的Inodes已使用: ${root_df_I}"
    if [ $c -ge 98 ];then
        echo -e "当前/目录磁盘Inodes剩余空间小于2%,可能是因此导致堡塔云WAF无法正常使用."
        echo -e "查询Inodes占用的命令: for i in /*; do echo \$i; find \$i | wc -l; done"
        echo -e "请根据查询结果到对应目录进行处理,注意清理该目录前请备份好数据后再操作."
    fi
    www_df_I=$( echo "$df_I"|grep -w /www|awk '{print $5}')
    b=$(echo $www_df_I|awk -F "%" '{print $1}')
    if [[ ! -z $www_df_I ]]; then
        echo -e "当前/www的Inodes目录已使用: ${www_df_I}"
        if [ $b -ge 98 ];then
            echo -e "当前/www目录磁盘Inodes剩余空间小于2%,可能是因此导致堡塔云WAF无法正常使用."
            echo -e "查询Inodes占用的命令: for i in /www/*; do echo \$i; find \$i | wc -l; done"
            echo -e "请根据查询结果到对应目录进行处理,注意清理该目录前请备份好数据后再操作."
        fi
    fi
}

Get_Pack_Manager(){
	if [ -f "/usr/bin/yum" ] && [ -d "/etc/yum.repos.d" ]; then
		PM="yum"
	elif [ -f "/usr/bin/apt-get" ] && [ -f "/usr/bin/dpkg" ]; then
		PM="apt-get"		
	fi
}

Conflicting_Package_Check() {
# 检查冲突的软件包：podman runc
    Get_Pack_Manager
    if [ "$PM" == "yum" ]; then
        echo -e "正在检查是否安装 podman runc ...."
        rpm_qa=$(rpm -qa)
        podman_check=$(echo "$rpm_qa"|grep -E "^podman-")
        runc_check=$(echo "$rpm_qa"|grep -E "^runc-")

        if [[ "$podman_check" != "" ]] && [[ "$runc_check" != "" ]]; then
            
            echo "$podman_check"
            echo "$runc_check"
            Red_Error "podman 与 docker 互斥, 服务器内已经装有podman, 请备份好所有容器和镜像后, 再卸载podman, 再执行命令安装。" "podman卸载命令(请务必备份好后，再执行卸载命令)：yum remove -y podman*"

        fi

        if [[ "$runc_check" != "" ]]; then
            echo "$runc_check"
            echo -e "\033[33m检测到 runc 软件包, 可能存在软件包冲突, 建议先卸载 runc 软件包，再安装。\033[0m"
            echo -e "runc 卸载命令(请务备好后，再执行卸载命令)：yum remove runc"
            sleep 10
        fi

    fi

}

Install_RPM_Pack(){
	yumPacks="wget curl tar gzip iproute lsof net-tools firewalld ipset sqlite ca-certificates";
	yum install -y ${yumPacks}

	for yumPack in ${yumPacks}
	do
		rpmPack=$(rpm -q ${yumPack})
		packCheck=$(echo ${rpmPack}|grep not)
		if [ "${packCheck}" ]; then
			yum install ${yumPack} -y
		fi
	done

    setenforce 0
    sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
}

Install_Deb_Pack(){
    debPacks="wget curl tar gzip iproute2 lsof net-tools lsb-release ufw ipset sqlite3 ca-certificates";
	apt-get update -y
	DEBIAN_FRONTEND=noninteractive apt-get install -y $debPacks --allow-downgrades --allow-remove-essential --allow-change-held-packages

	for debPack in ${debPacks}
	do
		packCheck=$(dpkg -l ${debPack})
		if [ "$?" -ne "0" ] ;then
			apt-get install -y $debPack
		fi
	done
}

Command_Exists() {
    command -v "$@" >/dev/null 2>&1
}

Check_Sys_Write(){
    echo "正在检测系统关键目录是否可写"
    if [ ! -d "/etc/init.d" ];then
        mkdir -p /etc/init.d
	fi

    if [ ! -d "$install_path" ];then
        mkdir -p $install_path
	fi
	
    Get_Pack_Manager
    if [ "$PM" == "yum" ]; then
        read_dir="$install_path /usr/lib/systemd/system/ /etc/init.d/ /usr/bin/"
    else
        read_dir="$install_path /usr/lib/systemd/system/ /etc/init.d/ /usr/bin/"
    fi
    
    echo "Ture" > /tmp/btw_install_test_111.pl || touch /tmp/btw_install_test_111.pl
    for dir in ${read_dir[@]}
    do
        if [[ -d "$dir" ]]; then
            if [[ ! -f "/tmp/btw_install_test_111.pl" ]]; then
                echo "建立测试 /tmp/btw_install_test_111.pl 文件失败"
                state=0
            else
                \cp /tmp/btw_install_test_111.pl $dir/btw_install_test_111.pl
            fi
            state=$(echo $?)
            if [[ "$state" != "0" ]];then
                echo -e "\033[31m错误：检测到系统关键目录不可写! $read_dir \033[0m"
                echo "1、如果安装了[宝塔系统加固]，请先临时关闭"
                echo "2、如果安装了云锁，请临时关闭[系统加固、文件防护]功能"
                echo "3、如果安装了安全狗，请临时关闭[系统防护]功能"
                echo "4、如果使用了其它安全软件，请先卸载 "
                echo -e "5、如果使用了禁止写入命令，请执行命令取消禁止写入：\n   chattr -iaR $read_dir "

                if [ $(whoami) != "root" ];then
                    echo -e "6、检测到非root用户安装，请尝试以下解决方案：\n   1.请切换到root用户安装 \n   2.尝试执行以下安装命令：\n     sudo bash $0 $@"
                fi

                echo ""
                echo -e "\033[31m解决以上问题后，请尝试重新安装！ \033[0m"
                echo -e "如果无法解决请截图以上报错信息发帖至论坛www.bt.cn/bbs求助"
                exit 1
            else
                rm -f $dir/btw_install_test_111.pl
            fi
        fi
    done

    if [[ -f "/tmp/btw_install_test_111.pl" ]]; then
        rm -f /tmp/btw_install_test_111.pl
    fi
}

Check_Sys_Packs(){
    echo "正在检查系统中是否存在必备的依赖包"
    Packs="wget curl tar gzip"
    if [ -f /usr/bin/which ];then
        for pack in ${Packs[@]}
        do
            check_pack=$(which $pack)
            #echo $check_pack
            if [[ "$check_pack" == "" ]]; then
                    echo -e "\033[31mERROR: $pack 命令不存在，尝试以下解决方法：\033[0m"
                    if [ "$PM" == "yum" ]; then
                        echo 1、使用命令重新安装依赖包：yum reinstall -y ${Packs}
                    else
                        echo 1、使用命令重新安装依赖包：apt-get reinstall -y ${Packs}
                    fi
                    echo -e "2、检查系统源是否可用？尝试更换可用的源参考教程：\n   https://www.bt.cn/bbs/thread-58005-1-1.html "
                    echo ""
                    echo -e "\033[31m解决以上问题后，请尝试重新安装！ \033[0m"
                    echo -e "如果无法解决请截图以上报错信息发帖至论坛www.bt.cn/bbs求助"
                    exit 1
            fi

        done
    fi
}

get_node_url(){
	if [ ! -f /bin/curl ];then
		if [ "${PM}" = "yum" ]; then
			yum install curl -y
		elif [ "${PM}" = "apt-get" ]; then
			apt-get install curl -y
		fi
	fi

	if [ -f "/www/node.pl" ];then
		download_Url=$(cat /www/node.pl)
		echo "Download node: $download_Url";
		echo '---------------------------------------------';
		return
	fi
	
	echo '---------------------------------------------';
	echo "Selected download node...";
    nodes=(https://dg2.bt.cn https://download.bt.cn https://ctcc1-node.bt.cn https://cmcc1-node.bt.cn https://ctcc2-node.bt.cn https://hk1-node.bt.cn https://na1-node.bt.cn https://jp1-node.bt.cn);
	tmp_file1=/dev/shm/net_test1.pl
	tmp_file2=/dev/shm/net_test2.pl
	[ -f "${tmp_file1}" ] && rm -f ${tmp_file1}
	[ -f "${tmp_file2}" ] && rm -f ${tmp_file2}
	touch $tmp_file1
	touch $tmp_file2
	for node in ${nodes[@]};
	do
		NODE_CHECK=$(curl -k --connect-timeout 3 -m 3 2>/dev/null -w "%{http_code} %{time_total}" ${node}/net_test|xargs)
		RES=$(echo ${NODE_CHECK}|awk '{print $1}')
		NODE_STATUS=$(echo ${NODE_CHECK}|awk '{print $2}')
		TIME_TOTAL=$(echo ${NODE_CHECK}|awk '{print $3 * 1000 - 500 }'|cut -d '.' -f 1)
		if [ "${NODE_STATUS}" == "200" ];then
			if [ $TIME_TOTAL -lt 100 ];then
				if [ $RES -ge 1500 ];then
					echo "$RES $node" >> $tmp_file1
				fi
			else
				if [ $RES -ge 1500 ];then
					echo "$TIME_TOTAL $node" >> $tmp_file2
				fi
			fi

			i=$(($i+1))
			if [ $TIME_TOTAL -lt 100 ];then
				if [ $RES -ge 3000 ];then
					break;
				fi
			fi	
		fi
	done

	NODE_URL=$(cat $tmp_file1|sort -r -g -t " " -k 1|head -n 1|awk '{print $2}')
	if [ -z "$NODE_URL" ];then
		NODE_URL=$(cat $tmp_file2|sort -g -t " " -k 1|head -n 1|awk '{print $2}')
		if [ -z "$NODE_URL" ];then
			NODE_URL='https://download.bt.cn';
		fi
	fi
	rm -f $tmp_file1
	rm -f $tmp_file2
	download_Url=$NODE_URL
	echo "Download node: $download_Url";
	echo '---------------------------------------------';
}

Docker_Download_Url_Check() {
    echo -e "正在选择下载docker地址源,请稍等..."
    ser_names=(mirrors.ustc.edu.cn/docker-ce mirrors.tuna.tsinghua.edu.cn/docker-ce mirrors.aliyun.com/docker-ce mirror.azure.cn/docker-ce download.docker.com)
    tmp_file1=/dev/shm/net_test1.pl
	tmp_file2=/dev/shm/net_test2.pl
    [ -f "${tmp_file1}" ] && rm -f ${tmp_file1}
    [ -f "${tmp_file2}" ] && rm -f ${tmp_file2}
    touch $tmp_file1
    touch $tmp_file2

    for ser_name in ${ser_names[@]};
    do
        NODE_CHECK=$(curl -k -s 2>/dev/null --connect-timeout 5 -w "%{http_code} %{time_total}" https://${ser_name} -o c${ser_name}.txt|xargs)
        rm -rf c${ser_name}.txt
        NODE_STATUS=$(echo ${NODE_CHECK}|awk '{print $1}')
        TIME_TOTAL=$(echo ${NODE_CHECK}|awk '{print $2 * 1000 - 500 }'|cut -d '.' -f 1)
        if [ "${NODE_STATUS}" == "200" ] || [ "${NODE_STATUS}" == "301" ] || [ "${NODE_STATUS}" == "403" ];then
            if [ $TIME_TOTAL -lt 100 ]; then
                echo "$ser_name" >> $tmp_file1
            elif [ $TIME_TOTAL -gt 1500 ] && [ $TIME_TOTAL -lt 2500 ]; then
                echo "$ser_name" >> $tmp_file2
            fi
        fi
    done
    Docker_NODE_URL=$(cat $tmp_file1|head -n 1|awk '{print $1}')
        if [ -z "$Docker_NODE_URL" ];then
            Docker_NODE_URL=$(cat $tmp_file2|head -n 1|awk '{print $1}')
        fi

    rm -f $tmp_file1
    rm -f $tmp_file2
    mirror="$Docker_NODE_URL"
    echo $mirror
    case "$mirror" in
    mirrors.aliyun.com/docker-ce)
        Default_Download_Url="https://mirrors.aliyun.com/docker-ce"
        mirror="Aliyun"
        ;;
    mirror.azure.cn/docker-ce)
        Default_Download_Url="https://mirror.azure.cn/docker-ce"
        mirror="AzureChinaCloud"
        ;;
    mirrors.ustc.edu.cn/docker-ce)
        Default_Download_Url="https://mirrors.ustc.edu.cn/docker-ce"
        mirror="USTC"
        ;;
    mirrors.tuna.tsinghua.edu.cn/docker-ce)
        Default_Download_Url="https://mirrors.tuna.tsinghua.edu.cn/docker-ce"
        mirror="tsinghua"
        ;;
    *)
        Default_Download_Url="https://download.docker.com"
        mirror=""
        ;;
    esac

    DEFAULT_REPO_FILE="docker-ce.repo"

    if [ -z "$REPO_FILE" ]; then
        REPO_FILE="$DEFAULT_REPO_FILE"
    fi
}

Get_Distribution() {
    lsb_dist=""
    lsb_name=""

    if [ -r /etc/os-release ]; then
        lsb_dist="$(. /etc/os-release && echo "$ID")"
        lsb_name="$(. /etc/os-release && echo "$NAME")"
    fi
    echo "$lsb_dist $lsb_name"
}

Docker_Stop() {
    if Command_Exists docker || [ -e /var/run/docker.sock ] || [ -f /lib/systemd/system/docker.service ]; then
        if which systemctl; then
            systemctl stop docker
            systemctl stop docker.socket
        else
            service docker stop
        fi
    fi
}


Bored_waiting(){
    w_time="$wait_time"
    msg="$wait_msg"
    progress="."
    for ((i=0; i<${w_time}; i++))
    do
        printf "$msg %-10s %d\r" "$progress" "$((i+1))"
        sleep 1

        if [ "$progress" == ".........." ]; then
            progress="."
        else
            progress+="."
        fi
    done
    printf "$msg %-10s %d\r" ".........." "$w_time"
    #echo ""
}

Docker_Start() {
    if Command_Exists docker || [ -f /lib/systemd/system/docker.service ]; then
        if Command_Exists systemctl; then
            # systemctl mask getty@tty1.service
            systemctl enable docker
            systemctl reset-failed docker.service
            systemctl start docker.service
            if [ "$?" != "0" ];then
                systemctl reset-failed docker.service
                systemctl restart docker.service
                if [ "$?" != "0" ];then
                    docker_status=$(systemctl status docker.service)
                    echo "$docker_status"
                    if [ -f /etc/docker/daemon.json ]; then
                        echo "/etc/docker/daemon.json 文件内容:"
                        cat /etc/docker/daemon.json
                        echo -e "\033[33m建议检查以上 /etc/docker/daemon.json 文件内容是否正确？\033[0m"
                    fi
                    #等待100秒动画
                    echo -e "\033[31m启动 docker服务失败，可能启动太快导致\033[0m"
                    wait_msg="正等待100秒后自动重启docker服务"
                    wait_time="100"
                    Bored_waiting
                    systemctl reset-failed docker.service
                    systemctl restart docker.service
                    if [ "$?" != "0" ];then
                        docker_status=$(systemctl status docker.service)
                        echo "$docker_status"
                        Red_Error "docker启动失败" "请尝试等待2分钟执行重启docker命令：systemctl restart docker.service (无内容返回为正常)" "最后重新执行堡塔云WAF安装命令"
                    fi
                fi
            fi
        else
            chkconfig --add docker
            chkconfig --level 2345 docker on
            service docker start
            if [ "$?" != "0" ];then
                service docker.service status
                cat /etc/docker/daemon.json
                Red_Error "docker启动失败"
            fi
        fi
    fi
}


Is_Darwin() {
    case "$(uname -s)" in
    *darwin*) true ;;
    *Darwin*) true ;;
    *) false ;;
    esac
}

Check_Forked() {
    if Command_Exists lsb_release; then
        set +e
        lsb_release -a -u >/dev/null 2>&1
        lsb_release_exit_code=$?

        if [ "$lsb_release_exit_code" = "0" ]; then
            cat <<-EOF
You're using '$lsb_dist' version '$dist_version'.
EOF
            lsb_dist=$(lsb_release -a -u 2>&1 | tr '[:upper:]' '[:lower:]' | grep -E 'id' | cut -d ':' -f 2 | tr -d '[:space:]')
            dist_version=$(lsb_release -a -u 2>&1 | tr '[:upper:]' '[:lower:]' | grep -E 'codename' | cut -d ':' -f 2 | tr -d '[:space:]')
            cat <<-EOF
Upstream release is '$lsb_dist' version '$dist_version'.
EOF
        else
            if [ -r /etc/debian_version ] && [ "$lsb_dist" != "ubuntu" ] && [ "$lsb_dist" != "raspbian" ]; then
                if [ "$lsb_dist" = "osmc" ]; then
                    lsb_dist=raspbian
                else
                    lsb_dist=debian
                fi
                dist_version="$(sed 's/\/.*//' /etc/debian_version | sed 's/\..*//')"
                case "$dist_version" in
                12)
	                dist_version="bookworm"
                    ;;
                11)
                    dist_version="bullseye"
                    ;;
                10)
                    dist_version="buster"
                    ;;
                9)
                    dist_version="stretch"
                    ;;
                8)
                    dist_version="jessie"
                    ;;
                esac
            fi
        fi
    fi
}

Set_Centos_Repo(){
	HUAWEI_CHECK=$(cat /etc/motd |grep "Huawei Cloud")
	if [ "${HUAWEI_CHECK}" ] && [ "${is64bit}" == "64" ];then
		\cp -rpa /etc/yum.repos.d/ /etc/yumBak
		sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*.repo
		sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.epel.cloud|g' /etc/yum.repos.d/CentOS-*.repo
		rm -f /etc/yum.repos.d/epel.repo
		rm -f /etc/yum.repos.d/epel-*
	fi
	ALIYUN_CHECK=$(cat /etc/motd|grep "Alibaba Cloud ")
	if [  "${ALIYUN_CHECK}" ] && [ "${is64bit}" == "64" ] && [ ! -f "/etc/yum.repos.d/Centos-vault-8.5.2111.repo" ];then
		rename '.repo' '.repo.bak' /etc/yum.repos.d/*.repo
		wget --no-check-certificate https://mirrors.aliyun.com/repo/Centos-vault-8.5.2111.repo -O /etc/yum.repos.d/Centos-vault-8.5.2111.repo
		wget --no-check-certificate https://mirrors.aliyun.com/repo/epel-archive-8.repo -O /etc/yum.repos.d/epel-archive-8.repo
		sed -i 's/mirrors.cloud.aliyuncs.com/url_tmp/g'  /etc/yum.repos.d/Centos-vault-8.5.2111.repo &&  sed -i 's/mirrors.aliyun.com/mirrors.cloud.aliyuncs.com/g' /etc/yum.repos.d/Centos-vault-8.5.2111.repo && sed -i 's/url_tmp/mirrors.aliyun.com/g' /etc/yum.repos.d/Centos-vault-8.5.2111.repo
		sed -i 's/mirrors.aliyun.com/mirrors.cloud.aliyuncs.com/g' /etc/yum.repos.d/epel-archive-8.repo
	fi
	MIRROR_CHECK=$(cat /etc/yum.repos.d/CentOS-Linux-AppStream.repo |grep "[^#]mirror.centos.org")
	if [ "${MIRROR_CHECK}" ] && [ "${is64bit}" == "64" ];then
		\cp -rpa /etc/yum.repos.d/ /etc/yumBak
		sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*.repo
		sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.epel.cloud|g' /etc/yum.repos.d/CentOS-*.repo
	fi
}

CentOS_89check(){
    if [ -f "/etc/redhat-release" ]; then
        Centos8Check=$(cat /etc/redhat-release | grep ' 8.' | grep -iE 'centos|Red Hat')
        Centos9Check=$(cat /etc/redhat-release | grep ' 9' | grep -iE 'centos|Red Hat')
        if [ "${Centos8Check}" ];then
            podman_check=$(rpm -qa|grep podman-docker)
            if [ "$podman_check" != "" ];then
                echo '=================================================';
                echo -e "服务器内已经装有podman-docker！请备份好所有容器和镜像卸载podman-docker后再安装docker官方程序。"
                echo -e "podman-docker卸载命令(请务必备份好后再执行卸载命令)："
                echo -e "yum remove -y podman*"
                Red_Error "服务器内已经装有podman-docker！请备份好所有容器和镜像卸载podman-docker后再安装docker官方程序。"
            fi
            Set_Centos_Repo
        fi
    fi
}

Check_Sys_Packs_Docker(){
    if [ "$offline_install" == "offline" ]; then
        if [ "$is_docker" == "0" ] || [ "$is_docker_compose" == "0" ]; then
            echo "正在检查 docker 依赖包是否存在："
            if [ "$PM" == "yum" ]; then
                echo -e "$(rpm -qa |grep -Ew "docker-ce|docker-ce-cli|containerd.io|docker-buildx-plugin|docker-compose-plugin")"
            else
                echo -e "$(dpkg -l |grep -Ew "docker-ce|docker-ce-cli|containerd.io|docker-buildx-plugin|docker-compose-plugin")"
            fi
            Packs2="docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin"
            echo -e "\033[31m请检查是否安装：$Packs2 \033[0m"
            echo -e "\033[31mERROR: docker version 命令执行失败,请检查docker服务是否运行正常,如果未安装,请安装docker后,再安装堡塔云WAF\033[0m"
            echo -e "推荐使用更方便的在线安装命令(需要连接互联网)：bash install_cloudwaf.sh "
            exit 1;
        fi
    fi
}

Docker_Check(){

    # 默认值为：0 没有安装
    is_docker="0"
    docker_version="docker version"
    if Command_Exists $docker_version ; then
        is_docker="1"
    fi
    echo "docker 命令是否存在：$is_docker"

    # 如果文件存在将忽略离线安装，在线安装docker
    if [ -f /www/btw_docker_install_11111.pl ]; then
        is_docker="0"
        offline_install=""
        rm -f /www/btw_docker_install_11111.pl
    fi

    Check_Sys_Packs_Docker

}

Docker_Install() {

    lsb_dist=$(Get_Distribution|awk -F " " '{print $1}')
    lsb_dist="$(echo "$lsb_dist" | tr '[:upper:]' '[:lower:]')"

    case "$lsb_dist" in
    ubuntu)
        if Command_Exists lsb_release; then
            dist_version="$(lsb_release --codename | cut -f2)"
        fi
        if [ -z "$dist_version" ] && [ -r /etc/lsb-release ]; then
            dist_version="$(. /etc/lsb-release && echo "$DISTRIB_CODENAME")"
        fi
        ;;
    debian | raspbian)
        dist_version="$(sed 's/\/.*//' /etc/debian_version | sed 's/\..*//')"
        case "$dist_version" in
        12)
            dist_version="bookworm"
            ;;
        11)
            dist_version="bullseye"
            ;;
        10)
            dist_version="buster"
            ;;
        9)
            dist_version="stretch"
            ;;
        8)
            dist_version="jessie"
            ;;
        esac
        ;;
    centos | rhel | sles | ol | tencentos | alinux | anolis | rocky | euleros | almalinux | opencloudos |openeuler |hce | kylin |uos | kylinsecos |amzn )
        if [ -z "$dist_version" ] && [ -r /etc/os-release ]; then
            dist_version="$(. /etc/os-release && echo "$VERSION_ID")"
        fi
        ;;
    *)
        if Command_Exists lsb_release; then
            dist_version="$(lsb_release --release | cut -f2)"
        fi
        if [ -z "$dist_version" ] && [ -r /etc/os-release ]; then
            dist_version="$(. /etc/os-release && echo "$VERSION_ID")"
        fi
        ;;
    esac

    Check_Forked

    case "$lsb_dist" in
    ubuntu | debian | raspbian)
        docker_gpg="/usr/share/keyrings/docker-archive-keyring.gpg"
        apt_repo_file="/etc/apt/sources.list.d/docker.list"
        pre_reqs="apt-transport-https ca-certificates curl wget"

        if ! command -v gpg >/dev/null; then
            pre_reqs="$pre_reqs gnupg"
        fi

        apt_repo="deb [arch=$(dpkg --print-architecture) signed-by=$docker_gpg] $Default_Download_Url/linux/$lsb_dist $dist_version stable"
        (
            DEBIAN_FRONTEND=noninteractive apt-get install -y $pre_reqs
            if [ -f $docker_gpg ] && [ -f $apt_repo_file ]; then
                rm -rf $docker_gpg
                rm -rf $apt_repo_file
            fi

            #curl -fsSL --connect-time 10 --retry 5 $Default_Download_Url/linux/$lsb_dist/gpg | gpg --dearmor --yes -o $docker_gpg
            wget --no-check-certificate -qO - -t 5 -T 10 $Default_Download_Url/linux/$lsb_dist/gpg | gpg --dearmor --yes -o $docker_gpg
            chmod a+r $docker_gpg

            echo "$apt_repo" > $apt_repo_file

            apt-get update -y
        )
        pkg_version=""

        #先检查apt-get是否使用,不可放到子shell 即()执行，否则不会退出
        Check_apt_status

        (
            pkgs="$pkgs docker-ce${pkg_version%=}"
            Script_Command "DEBIAN_FRONTEND=noninteractive apt-get install -y $pkgs docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin"
        )

        ;;
    centos | fedora | rhel | ol | tencentos | alinux | anolis | rocky | almalinux | opencloudos |openeuler |hce |uos |amzn )
        pkg_version=""

        yum_repo="$Default_Download_Url/linux/$lsb_dist/$REPO_FILE"
        if [ "$lsb_dist" == "ol" ] || [ "$lsb_dist" == "tencentos" ] || [ "$lsb_dist" == "alinux" ] || [ "$lsb_dist" == "anolis" ] || [ "$lsb_dist" == "opencloudos" ] || [ "$lsb_dist" == "openeuler" ] || [ "$lsb_dist" == "hce" ] || [ "$lsb_dist" == "uos" ] || [ "$lsb_dist" == "amzn" ] ; then
            yum_repo="$Default_Download_Url/linux/centos/$REPO_FILE"
        fi
        if [ "$lsb_dist" == "rocky" ] || [ "$lsb_dist" == "almalinux" ]; then
            yum_repo="$Default_Download_Url/linux/centos/$REPO_FILE"
        fi
        if [ "$lsb_dist" = "fedora" ]; then
            pkg_manager="dnf"
            config_manager="dnf config-manager"
            enable_channel_flag="--set-enabled"
            disable_channel_flag="--set-disabled"
            pre_reqs="dnf-plugins-core"
            pkg_suffix="fc$dist_version"
        else
            pkg_manager="yum"
            config_manager="yum-config-manager"
            enable_channel_flag="--enable"
            disable_channel_flag="--disable"
            pre_reqs="yum-utils"
            pkg_suffix="el"
        fi
    
        wget --no-check-certificate -O /etc/yum.repos.d/docker-ce.repo $yum_repo -t 5 -T 10
        if [ $? -ne "0" ]; then
            cat <<EOF >/etc/yum.repos.d/docker-ce.repo
[docker-ce-stable]
name=Docker CE Stable - \$basearch
baseurl=https://download.docker.com/linux/centos/\$releasever/\$basearch/stable
enabled=1
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg

EOF
        fi

        sed -i "s|https://download.docker.com|$Default_Download_Url|g" /etc/yum.repos.d/docker-ce.repo
        # cat /etc/yum.repos.d/docker-ce.repo
       
        lsb_name=$(Get_Distribution|awk -F " " '{print $3}')
        echo $lsb_name
        echo $lsb_dist
        #if [ "$lsb_name" = "Stream" ] || [ "$lsb_dist" = "alinux" ] || [ "$lsb_dist" = "anolis" ];then
        #if [ "$lsb_name" = "Stream" ] || [ "$lsb_dist" = "anolis" ];then
        if [ "$lsb_name" = "Stream" ]; then
            conflicting="--allowerasing"
        fi
        if [ "$lsb_name" = "rocky" ] || [ "$lsb_dist" = "euleros" ] || [ "$lsb_dist" = "almalinux" ];then
            conflicting="--allowerasing"
        fi

        if [ "$lsb_dist" = "openeuler" ];then
            openeuler_v=$(cat /etc/os-release |grep "VERSION=")
            if [[ $openeuler_v =~ "23.0" ]]; then
                
                sed -i "s|\$releasever|8|g" /etc/yum.repos.d/docker-ce.repo
                $pkg_manager makecache
                
            elif [[ $openeuler_v =~ "22.0" ]]; then
                sed -i "s|\$releasever|7|g" /etc/yum.repos.d/docker-ce.repo
                $pkg_manager makecache
            else
                if [ -f "/etc/os-release" ]; then
                    cat /etc/os-release
                fi
                echo "ERROR: 暂不支持此系统使用yum安装docker."
            fi
        fi

        # Amazon Linux
        if [ "$lsb_dist" = "amzn" ];then
            #amzn_v=$(. /etc/os-release && echo "$VERSION_ID")

            sed -i "s|\$releasever|8|g" /etc/yum.repos.d/docker-ce.repo
            $pkg_manager makecache
        fi

        # Huawei Cloud EulerOS 
        if [ "$lsb_dist" = "hce" ];then
            hce_v=$(. /etc/os-release && echo "$VERSION_ID")
            if [[ $hce_v =~ "2.0" ]]; then
                sed -i "s|\$releasever|8|g" /etc/yum.repos.d/docker-ce.repo
                $pkg_manager makecache
            else
                if [ -f "/etc/os-release" ]; then
                    cat /etc/os-release
                fi
                echo "ERROR: 暂不支持此系统使用yum安装docker."
            fi
        fi

        # OpenCloudOS 9.0
        if [ "$lsb_dist" = "opencloudos" ];then
            pkg_manager="yum"
            opencloudos_v=$(. /etc/os-release && echo "$VERSION_ID")
            if [[ $opencloudos_v =~ "9.0" ]]; then

                sed -i "s|\$releasever|8|g" /etc/yum.repos.d/docker-ce.repo
                # centos 8
                download_container_selinux="$download_Url/cloudwaf/package/container-selinux-2.224.0-1.module_el8+712+4cd1bd69.noarch.rpm"
                wget --no-check-certificate -O container-selinux-2.224.0-1.module_el8+712+4cd1bd69.noarch.rpm ${download_container_selinux} -t 5 -T 10

                install_docker="1"
                $pkg_manager makecache
                
                Script_Command "$pkg_manager install -y docker-ce$pkg_version docker-ce-cli docker-buildx-plugin docker-compose-plugin container-selinux-2.224.0-1.module_el8+712+4cd1bd69.noarch.rpm"

                rm -f container-selinux-2.224.0-1.module_el8+712+4cd1bd69.noarch.rpm

            fi
        fi

        if [ "$lsb_dist" = "uos" ];then
            pkg_manager="yum"
            uos_v=$(. /etc/os-release && echo "$VERSION_ID")
            uos_NAME=$(. /etc/os-release && echo "$NAME")
            if [[ $uos_v =~ "20" ]] && [[ "$uos_NAME" == "UOS Server Euler" ]]; then
            # UOS Server Euler 20 使用默认源安装
                if [ -f /etc/yum.repos.d/docker-ce.repo ]; then
                    rm -f /etc/yum.repos.d/docker-ce.repo
                fi
                # 定义使用其他命令安装docker
                install_docker="1"
                $pkg_manager makecache

                Script_Command "$pkg_manager install -y docker* --skip-broken"

            elif [[ $uos_v =~ "20" ]]; then
                sed -i "s|\$releasever|8|g" /etc/yum.repos.d/docker-ce.repo

                # 定义使用其他命令安装docker
                install_docker="1"

                $pkg_manager makecache

                Script_Command "$pkg_manager install -y docker-ce$pkg_version docker-ce-cli docker-buildx-plugin docker-compose-plugin"


            else
                if [ -f "/etc/os-release" ]; then
                    cat /etc/os-release
                fi
                echo "ERROR: 暂不支持此系统使用yum安装docker."
            fi
        fi

        if [[ "$install_docker" != "1" ]]; then
        # 1时 会使用其他命令安装docker
            $pkg_manager makecache

            Script_Command "$pkg_manager install -y docker-ce$pkg_version docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin $conflicting" 

        fi
        ;;

    # 使用自带的 源安装 docker
    euleros)
        pkg_manager="yum"
        $pkg_manager makecache

        Script_Command "$pkg_manager install -y docker* --skip-broken"
        ;;

    KylinSecOS | kylinsecos)
        pkg_manager="yum"
        $pkg_manager makecache
        
        Script_Command "$pkg_manager install -y docker* --skip-broken"
        ;;
    
    kylin )
        pkg_manager="yum"
        $pkg_manager makecache
        
        Script_Command "$pkg_manager install -y docker* --skip-broken"
        ;;

    *)
        if [ -z "$lsb_dist" ]; then
            if Is_Darwin; then
                echo
                echo "ERROR: Unsupported operating system 'macOS', 错误：不支持的操作系统 macOS "
                echo
                exit 1
            fi
        fi
        echo
        Red_Error "ERROR: 暂不支持 '$lsb_dist' 自动安装docker, 您可以尝试自行参考教程手动安装docker."
        ;;
    esac

    if ! Command_Exists docker && [ ! -f /usr/bin/docker ]; then
        echo "正在尝试使用二进制包方式安装docker."
        
        Binary_package_install_docker
        
    fi

    if ! Command_Exists docker ; then
        Red_Error "docker 命令不存在,安装docker失败,请向上检查失败原因."
    fi
}

Binary_package_install_docker(){
# 二进制包方式安装docker
    DOCKER_VERSION="24.0.7"
    SYS_TYPE=$(uname -m)
    #download_Url="https://download.bt.cn"

    echo "建立docker用户组"
    groupadd docker

    echo "正在下载docker-${DOCKER_VERSION}.tgz文件,请稍等..."
    wget --no-check-certificate -O docker-${DOCKER_VERSION}.tgz ${download_Url}/src/docker-${DOCKER_VERSION}-${SYS_TYPE}.tgz -t 5 -T 10

    tmp_size=$(du -b docker-${DOCKER_VERSION}.tgz |awk '{print $1}')
    if [ $tmp_size -lt 60831072 ];then
        ls -l docker-${DOCKER_VERSION}.tgz
        Red_Error "ERROR: Failed to download, please try install again!" "ERROR: 下载 docker-${DOCKER_VERSION}.tgz文件失败，请尝试重新安装！"
    fi

    echo "解压docker-${DOCKER_VERSION}.tgz文件中,请稍等..."
    tar -xvf docker-${DOCKER_VERSION}.tgz
    \cp docker/* /usr/bin/

    # rm -rf docker
    rm -f docker-${DOCKER_VERSION}.tgz

    wget --no-check-certificate -O /usr/bin/docker-compose ${download_Url}/src/docker-compose-linux-${SYS_TYPE} -t 5 -T 10
    chmod +x /usr/bin/docker-compose

    wget --no-check-certificate -O /usr/lib/systemd/system/docker.service ${download_Url}/init/systemd/docker.service -t 5 -T 10
    wget --no-check-certificate -O /usr/lib/systemd/system/docker.socket ${download_Url}/init/systemd/docker.socket -t 5 -T 10
    wget --no-check-certificate -O /usr/lib/systemd/system/containerd.service ${download_Url}/init/systemd/containerd.service -t 5 -T 10

    systemctl enable docker.service
    systemctl enable docker.socket
    systemctl enable containerd.service
    
    systemctl start containerd.service
    systemctl start docker.socket
    systemctl start docker.service

}

Only_Docker(){
    if [ "$only_docker" == "docker" ]; then
        Docker_Download_Url_Check
        Docker_Install
        exit;
    fi
}

Docker_Compose_Check(){

    is_docker_compose="0"
    if Command_Exists docker-compose; then
        is_docker_compose="1"
    else 
        if Command_Exists docker; then
            Docker_compose="docker compose version"
            if $Docker_compose; then
                is_docker_compose="1"
            fi
        else
            is_docker_compose="0"
        fi

    fi

    Check_Sys_Packs_Docker
}

Docker_Compose_Install() {

    if [ $is_docker_compose == "0" ]; then
        Docker_Install
    fi

    Compose_Download_Url="$download_Url/install/src/docker-compose-$(uname -s)-$(uname -m)"
    Compose_Path="/usr/local/bin/docker-compose"
    New_Compose_Path="/usr/libexec/docker/cli-plugins/docker-compose"
    Compose_lin="/usr/bin/docker-compose"

    if [ ! -f $New_Compose_Path ]; then
        wget --no-check-certificate -t 5 -T 10 -O $New_Compose_Path $Compose_Download_Url
        chmod +x $New_Compose_Path
        rm -rf $Compose_lin
    fi

    if [ ! -f ${Compose_lin} ];then
        ln -s $New_Compose_Path $Compose_lin
    fi
}

Init_Docker_Manager() {
    docker_db="/www/server/panel/data/docker.db"

    if [ ! -f $docker_db ] || [ ! -s $docker_db ]; then
        wget --no-check-certificate -O $docker_db $download_Url/install/src/docker.db
    fi

}

Pip_Install() {
    curl -Ssk --connect-timeout 3 -m 60 $download_Url/install/pip_select.sh | bash
    if [ -f /usr/bin/btpip ]; then
        btpip install pytz
        btpip install docker
    else
        pip install pytz
        pip install docker
    fi
}

Set_Firewall(){
    if [ "$offline_install" != "offline" ]; then
        sshPort=$(cat /etc/ssh/sshd_config | grep 'Port '|awk '{print $2}')
        if [ "${PM}" = "apt-get" ]; then
            #apt-get install -y ufw
            if [ -f "/usr/sbin/ufw" ] || [ -f "/sbin/ufw" ] ; then
                ufw allow 22/tcp > /dev/null 2>&1
                ufw allow 80/tcp > /dev/null 2>&1
                ufw allow 443/tcp > /dev/null 2>&1
                ufw allow ${WAF_Port}/tcp > /dev/null 2>&1
                ufw allow ${sshPort}/tcp > /dev/null 2>&1
                ufw_status=`ufw status`
                echo y|ufw enable
                ufw default deny
                ufw reload
            fi
        else
            if [ -f "/etc/init.d/iptables" ]; then
                iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
                iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
                iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
                iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport ${WAF_Port} -j ACCEPT
                iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport ${sshPort} -j ACCEPT
                iptables -A INPUT -p icmp --icmp-type any -j ACCEPT
                iptables -A INPUT -s localhost -d localhost -j ACCEPT
                iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
                iptables -P INPUT DROP
                service iptables save
                sed -i "s#IPTABLES_MODULES=\"\"#IPTABLES_MODULES=\"ip_conntrack_netbios_ns ip_conntrack_ftp ip_nat_ftp\"#" /etc/sysconfig/iptables-config
                iptables_status=$(service iptables status | grep 'not running')
                if [ "${iptables_status}" == '' ]; then
                    service iptables restart
                fi
            else
                AliyunCheck=$(cat /etc/redhat-release|grep "Aliyun Linux")
                [ "${AliyunCheck}" ] && return
                #yum install firewalld -y
                [ "${Centos8Check}" ] && yum reinstall python3-six -y
                systemctl enable firewalld
                systemctl start firewalld
                firewall-cmd --set-default-zone=public > /dev/null 2>&1
                firewall-cmd --permanent --zone=public --add-port=22/tcp > /dev/null 2>&1
                firewall-cmd --permanent --zone=public --add-port=80/tcp > /dev/null 2>&1
                firewall-cmd --permanent --zone=public --add-port=443/tcp > /dev/null 2>&1
                firewall-cmd --permanent --zone=public --add-port=${WAF_Port}/tcp > /dev/null 2>&1
                firewall-cmd --permanent --zone=public --add-port=${sshPort}/tcp > /dev/null 2>&1
                firewall-cmd --reload
            fi
        fi

    else
        sshPort=$(cat /etc/ssh/sshd_config | grep 'Port '|awk '{print $2}')
        if [ "${PM}" = "apt-get" ]; then
            if [ -f "/usr/sbin/ufw" ] || [ -f "/sbin/ufw" ] ; then
                ufw allow 22/tcp > /dev/null 2>&1
                ufw allow 80/tcp > /dev/null 2>&1
                ufw allow 443/tcp > /dev/null 2>&1
                ufw allow ${WAF_Port}/tcp > /dev/null 2>&1
                ufw allow ${sshPort}/tcp > /dev/null 2>&1
                ufw_status=`ufw status`
                echo y|ufw enable
                ufw default deny
                ufw reload
            fi
        else
            if [ -f "/etc/init.d/iptables" ];then
                iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
                iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
                iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
                iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport ${WAF_Port} -j ACCEPT
                iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport ${sshPort} -j ACCEPT
                iptables -A INPUT -p icmp --icmp-type any -j ACCEPT
                iptables -A INPUT -s localhost -d localhost -j ACCEPT
                iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
                iptables -P INPUT DROP
                service iptables save
                sed -i "s#IPTABLES_MODULES=\"\"#IPTABLES_MODULES=\"ip_conntrack_netbios_ns ip_conntrack_ftp ip_nat_ftp\"#" /etc/sysconfig/iptables-config
                iptables_status=$(service iptables status | grep 'not running')
                if [ "${iptables_status}" == '' ];then
                    service iptables restart
                fi
            else
                AliyunCheck=$(cat /etc/redhat-release|grep "Aliyun Linux")
                [ "${AliyunCheck}" ] && return
                [ "${Centos8Check}" ]
                systemctl enable firewalld
                systemctl start firewalld
                firewall-cmd --set-default-zone=public > /dev/null 2>&1
                firewall-cmd --permanent --zone=public --add-port=22/tcp > /dev/null 2>&1
                firewall-cmd --permanent --zone=public --add-port=80/tcp > /dev/null 2>&1
                firewall-cmd --permanent --zone=public --add-port=443/tcp > /dev/null 2>&1
                firewall-cmd --permanent --zone=public --add-port=${WAF_Port}/tcp > /dev/null 2>&1
                firewall-cmd --permanent --zone=public --add-port=${sshPort}/tcp > /dev/null 2>&1
                firewall-cmd --reload
            fi
        fi

    fi
}

Get_Ip_Address(){
    if [ "$offline_install" != "offline" ]; then
        getIpAddress=""
        getIpAddress=$(curl -sSk --connect-timeout 10 -m 60 https://www.bt.cn/Api/getIpAddress)
        if [ -z "${getIpAddress}" ] || [ "${getIpAddress}" = "0.0.0.0" ]; then
            isHosts=$(cat /etc/hosts|grep 'www.bt.cn')
            if [ -z "${isHosts}" ];then
                echo "" >> /etc/hosts
                echo "116.213.43.206 www.bt.cn" >> /etc/hosts
                getIpAddress=$(curl -sSk --connect-timeout 10 -m 60 https://www.bt.cn/Api/getIpAddress)
                if [ -z "${getIpAddress}" ];then
                    sed -i "/bt.cn/d" /etc/hosts
                fi
            fi
        fi

        ipv4_regex="^([0-9]{1,3}\.){3}[0-9]{1,3}$"
        ipv6_regex="^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}$"
        ipv6Address=$(echo ${getIpAddress}|tr -d "[]")

        if [[ ${getIpAddress} =~ ${ipv4_regex} ]]; then        
            echo "${getIpAddress}" >/dev/null 2>&1            
        elif [[ ${ipv6Address} =~ ${ipv6_regex} ]]; then
            echo "${ipv6Address}" >/dev/null 2>&1
        else
            getIpAddress="SERVER_IP"
        fi

        if [ "${getIpAddress}" != "SERVER_IP" ];then
            echo "${getIpAddress}" > ${waf_path}/data/iplist.txt
            #echo "${getIpAddress}"
        fi

    else
        # 离线安装不获取外网IP
        getIpAddress="SERVER_IP"
    fi

    LOCAL_IP=$(ip addr | grep -E -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | grep -E -v "^127\.|^255\.|^0\." | head -n 1)

}

Container_Check(){
    nginx_container_exists=0
    mysql_container_exists=0
    #查找$Containers 列表的容器是否存在
    for container in ${Containers}; do
        if [[ ! -z "$container" ]]; then
            #精确匹配容器名称
            container_name=$(docker ps -a --filter "name=^${container}$" --format "{{.Names}}")
            #nginx
            if [ "$container_name" == "$NGINX_NAME" ];then
				nginx_container_exists=1
			fi
            
            #mysql
			if [ "$container_name" == "$MYSQL_NAME" ];then
				mysql_container_exists=1
			fi

        fi
	done
    # echo nginx_container_exists $nginx_container_exists
    # echo mysql_container_exists $mysql_container_exists
}

Container_Check_22(){
    docker_version="docker version"
    if Command_Exists $docker_version && [ ! -d "$setup_path" ]; then
        Container_info_2=""
        for container in ${Containers}; do
            #精确匹配容器名称
            container_name=$(docker ps -a --filter "name=^${container}$" --format "{{.Names}}")
            if [ -n "$container_name" ]; then
                Container_info_2+="容器已存在: $container_name \n"
                container_info+="1. 导出容器并压缩备份命令：\n   docker export $container_name | gzip > backup_$(date +%Y_%m_%d_%H_%M_%S)_$container_name.tar.gz \n"
                container_info+="2. 删除容器命令：\n   docker rm -f $container_name \n"
            fi
        done

        if [ -n "$Container_info_2" ]; then
            echo -e "$Container_info_2"
            echo ""
            echo -e "\033[31m$setup_path 目录不存在,检测到非堡塔云WAF创建的容器\033[0m"
            echo -e "\033[31m堡塔云WAF需要使用到 $Containers 容器,请先解决以上问题,再安装堡塔云WAF.\033[0m"
            exit 1;
        fi
    fi
    
}

Download_Copy_Files(){

    mkdir -p $setup_path
    cd $setup_path

    if [ "$offline_install" != "offline" ]; then
        echo "下载镜像中,请稍等..."

        echo ${Mirror_file} ${Cloudwaf_file}

        wget --no-check-certificate -c -O ${Mirror_file} $download_Url/cloudwaf/package/${Mirror_file} -t 5 -T 10 

        tmp_size=$(du -b "${Mirror_file}" |awk '{print $1}')
        if [ $tmp_size -lt 188132620 ];then
            ls -l ${Mirror_file}
            Red_Error "ERROR: Failed to download, please try install again!" "ERROR: 下载${Mirror_file}文件失败，请尝试重新安装！"
        fi

        wget --no-check-certificate -O ${Cloudwaf_file} $download_Url/cloudwaf/package/${Cloudwaf_file} -t 5 -T 10

        tmp_size=$(du -b "${Cloudwaf_file}" |awk '{print $1}')
        if [ $tmp_size -lt 30692352 ];then
            ls -l ${Cloudwaf_file} && rm -f ${Cloudwaf_file}
            Red_Error "ERROR: Failed to download, please try install again!" "ERROR: 下载${Cloudwaf_file}文件失败，请尝试重新安装！"
        fi

        if [ -f "$setup_path/offline.pl" ]; then
            rm -f $setup_path/offline.pl
        fi

    else
        # 离线文件复制
        echo -e "离线文件复制"
        if [ "${Mirror_file}" == "" ] || [ "${Cloudwaf_file}" == "" ]; then
            Red_Error "Mirror_file 或者 Cloudwaf_file 变量为空 "
        fi

        \cp -arpf "${PWD_d}/${Mirror_file}" $setup_path/
        if [ $? -ne "0" ]; then
            echo -e "\033[31m复制离线文件失败，请检查是否有此文件：${PWD_d}/${Mirror_file} \033[0m"
            exit 1;
        fi

        \cp -arpf "${PWD_d}/${Cloudwaf_file}" $setup_path/
        if [ $? -ne "0" ]; then
            echo -e "\033[31m复制离线文件失败，请检查是否有此文件：${PWD_d}/${Cloudwaf_file} \033[0m"
            exit 1;
        fi
        
        # 生成离线判断文件
        echo "Ture" > $setup_path/offline.pl

    fi
}

Optimize_waf_conf_file(){
# 根据内存优化waf.conf文件

    BTWAF_DATA_MEM="50m"
    IPINFO_MEM="30m";
    MEM_TOTAL=$(free -m | awk '/^Mem:/{print $2}')
    if [ -z "$MEM_TOTAL" ]; then
        MEM_TOTAL=$(free -m | awk '/^内存：/{print $2}')
    fi

    if [[ "${MEM_TOTAL}" -gt 4096 && "${MEM_TOTAL}" -le 8192 ]];then
        BTWAF_DATA_MEM="50m"
        IPINFO_MEM="50m";
    elif [[ "${MEM_TOTAL}" -gt 8192 && "${MEM_TOTAL}" -le 16384 ]]; then
        BTWAF_DATA_MEM="80m"
        IPINFO_MEM="80m";
    elif [[ "${MEM_TOTAL}" -gt 16384 && "${MEM_TOTAL}" -le 32768 ]]; then
        BTWAF_DATA_MEM="100m"
        IPINFO_MEM="100m";
    elif [[ "${MEM_TOTAL}" -gt 32768 && "${MEM_TOTAL}" -le 65536 ]]; then
        BTWAF_DATA_MEM="110m"
        IPINFO_MEM="110m";
    elif [[ "${MEM_TOTAL}" -gt 65536 && "${MEM_TOTAL}" -le 131072 ]]; then
        BTWAF_DATA_MEM="120m"
        IPINFO_MEM="120m";
    elif [ "${MEM_TOTAL}" -gt 131072 ]; then
        BTWAF_DATA_MEM="130m"
        IPINFO_MEM="130m";
    fi

    if [ ! -f $setup_path/nginx/conf.d/waf.conf_bak ]; then
        cp $setup_path/nginx/conf.d/waf.conf $setup_path/nginx/conf.d/waf.conf_bak
    fi

    sed -i "s/btwaf_data 100m/btwaf_data ${BTWAF_DATA_MEM}/g" $setup_path/nginx/conf.d/waf.conf
    sed -i "s/ipinfo 100m/ipinfo ${IPINFO_MEM}/g" $setup_path/nginx/conf.d/waf.conf

}

Install_Mirror(){
    ulimit -n 1000001
    tee -a /etc/security/limits.conf << EOF
*               hard    nofile          1000001
*               soft    nofile          1000001
root            hard    nofile          1000001
root            soft    nofile          1000001
EOF
    sysctl -p


    cd $setup_path

    mkdir -p $setup_path/wwwroot
    mkdir -p $setup_path/vhost
    mkdir -p $setup_path/mysql/{log,data,conf}
    mkdir -p $setup_path/nginx/{conf,logs,conf}
    mkdir -p $setup_path/nginx/conf.d/{vhost,user,pass,other}
    mkdir -p $waf_path/{logs,data,ssl}

    mkdir $setup_path/new_cloudwaf

    # 如果容器存在先停止
    if [ "$nginx_container_exists" == "1" ]; then
        echo -e "正在停止 $NGINX_NAME 容器..."
        docker stop $NGINX_NAME 2>&1 >/dev/null
    fi
    sleep 2
    if [ "$mysql_container_exists" == "1" ]; then
        echo -e "正在停止 $MYSQL_NAME 容器..."
        docker stop $MYSQL_NAME 2>&1 >/dev/null
    fi


	if [ "$re_install" != "yes" ]; then
        #全新安装或者覆盖安装
        echo -e "解压文件中,请稍等..."
        tar -zxf ${Cloudwaf_file} -C $setup_path/new_cloudwaf
        if [ $? -ne "0" ]; then
            Red_Error "解压 ${Cloudwaf_file} 失败"
        fi

        #覆盖安装时不复制
        # if [ -f "$setup_path/nginx/conf.d/vhost/0.default.conf" ]; then
        #     rm -f $setup_path/new_cloudwaf/nginx/conf.d/vhost/0.default.conf
        # fi

        # if [ -f "$setup_path/wwwroot/nginx/index.html" ]; then
        #     rm -f $setup_path/new_cloudwaf/wwwroot/nginx/index.html
        #     rm -f $setup_path/new_cloudwaf/wwwroot/nginx/fullchain.pem
        #     rm -f $setup_path/new_cloudwaf/wwwroot/nginx/privkey.pem
        # fi

        #覆盖安装时不复制，新安装时写文件
        if [ -f "$setup_path/nginx/conf.d/waf/config/site.json" ]; then
            rm -f $setup_path/new_cloudwaf/nginx/conf.d/waf/config/site.json
        else
            echo "{}" > $setup_path/new_cloudwaf/nginx/conf.d/waf/config/site.json
        fi
        
        #覆盖安装时不复制
        if [ -f "$setup_path/nginx/conf.d/waf/config/domains.json" ]; then
            rm -f $setup_path/new_cloudwaf/nginx/conf.d/waf/config/domains.json
        fi

        #覆盖安装时
        if [ -s "$setup_path/nginx/conf.d/waf/mysql_default.pl" ]; then
            #获取数据库密码
            MYSQL_PASS=$(cat $setup_path/nginx/conf.d/waf/mysql_default.pl)

            if [ -f "$setup_path/nginx/conf.d/waf/config/config.json" ]; then
                sed -i "s#1215454545454545444444444cn#${MYSQL_PASS}#g" $setup_path/nginx/conf.d/waf/config/config.json
                rm -f $setup_path/new_cloudwaf/nginx/conf.d/waf/config/config.json
            else
                sed -i "s#1215454545454545444444444cn#${MYSQL_PASS}#g" $setup_path/new_cloudwaf/nginx/conf.d/waf/config/config.json
            fi

        elif [ "$mysql_container_exists" == "1" ] ; then
            MYSQL_ROOT_PASSWORD=$(docker inspect $MYSQL_NAME |grep MYSQL_ROOT_PASSWORD)
            MYSQL_PASS=$(echo "$MYSQL_ROOT_PASSWORD" | sed -n 's/.*MYSQL_ROOT_PASSWORD=\([^",]*\).*/\1/p')
            echo "$MYSQL_PASS"
            echo "$MYSQL_PASS" > $setup_path/nginx/conf.d/waf/mysql_default.pl

            if [ -f "$setup_path/nginx/conf.d/waf/config/config.json" ]; then
                sed -i "s#1215454545454545444444444cn#${MYSQL_PASS}#g" $setup_path/nginx/conf.d/waf/config/config.json
                rm -f $setup_path/new_cloudwaf/nginx/conf.d/waf/config/config.json
            else
                sed -i "s#1215454545454545444444444cn#${MYSQL_PASS}#g" $setup_path/new_cloudwaf/nginx/conf.d/waf/config/config.json
            fi
            
        else
            #MYSQL_PASS=$(openssl rand -base64 32)
            MYSQL_PASS=$(cat /dev/urandom | head -n 32 | md5sum | head -c 32)
            # echo $MYSQL_PASS
            sed -i "s#1215454545454545444444444cn#${MYSQL_PASS}#g" $setup_path/new_cloudwaf/nginx/conf.d/waf/config/config.json
        fi


        \cp -arpf $setup_path/new_cloudwaf/* $setup_path
        if [ $? -ne "0" ]; then
            Red_Error "无法复制文件到 $setup_path"
        fi

        if [ ! -f "$waf_path/CloudWaf" ]; then
            Red_Error "$waf_path/CloudWaf 文件不存在"
        fi

    else

    #还要继续完善
        echo "还原安装中..."
        tar -zxf ${Cloudwaf_file} -C $setup_path/new_cloudwaf
        if [ $? -ne "0" ]; then
            Red_Error "解压 ${Cloudwaf_file} 失败"
        fi

        \cp -arpf $setup_path/new_cloudwaf/* $setup_path
        if [ $? -ne "0" ]; then
            Red_Error "无法复制文件到 $setup_path"
        fi

        if [ ! -f "$waf_path/CloudWaf" ]; then
            Red_Error "$waf_path/CloudWaf 文件不存在"
        fi
        ls $setup_path/*
        
        if [ -d "$old_dir/nginx/" ]; then
            echo "还原 nginx 配置及数据中..."
            \cp -arpf $old_dir/nginx/conf/* $setup_path/nginx/conf

            \cp -arpf $old_dir/nginx/conf.d/other/* $setup_path/nginx/conf.d/other
            \cp -arpf $old_dir/nginx/conf.d/pass/* $setup_path/nginx/conf.d/pass
            \cp -arpf $old_dir/nginx/conf.d/user/* $setup_path/nginx/conf.d/user
            \cp -arpf $old_dir/nginx/conf.d/vhost/* $setup_path/nginx/conf.d/vhost


            \cp -arpf $old_dir/nginx/conf.d/waf/config/* $setup_path/nginx/conf.d/waf/config
            \cp -arpf $old_dir/nginx/conf.d/waf/html/* $setup_path/nginx/conf.d/waf/html
            \cp -arpf $old_dir/nginx/conf.d/waf/rule/* $setup_path/nginx/conf.d/waf/rule

            #旧的密码恢复
            if [ -s "$old_dir/nginx/conf.d/waf/mysql_default.pl" ]; then
                MYSQL_PASS=$(cat $old_dir/nginx/conf.d/waf/mysql_default.pl)
                echo "$MYSQL_PASS"
                #sed -i "s#${OLD_MYSQL_PASS}#${MYSQL_PASS}#g" $setup_path/nginx/conf.d/waf/config/config.json
            else
                #MYSQL_PASS=$(openssl rand -base64 32)
                MYSQL_PASS=$(cat /dev/urandom | head -n 32 | md5sum | head -c 32)
            fi
            
        
        fi
        ls $setup_path/nginx/*

        if [ -d "$old_dir/mysql/" ] && [ -s "$old_dir/nginx/conf.d/waf/mysql_default.pl" ]; then
            echo "还原 mysql 配置及数据中..."
            \cp -arpf $old_dir/mysql/* $setup_path/mysql
            if [ $? -ne "0" ]; then
                Red_Error "Error: 还原 mysql 配置及数据出错！"
            fi
            
        else
            echo "未还原mysql配置：$old_dir/mysql 目录不存在或者无法获取到旧root密码"
        fi
        ls $setup_path/mysql/*


        if [ -d "$old_dir/console/" ]; then
            echo "还原 管理界面配置及数据中..."
            \cp -arpf $old_dir/console/ssl/* $setup_path/console/ssl
            \cp -arpf $old_dir/console/config/* $setup_path/console/config
            \cp -arpf $old_dir/console/data/* $setup_path/console/data
        fi
        ls $setup_path/console/data/

        if [ -d "$old_dir/wwwroot/" ]; then
            \cp -arpf $old_dir/wwwroot/* $setup_path/wwwroot
        fi
        ls $setup_path/wwwroot/*

        if [ -d "$old_dir/vhost/" ]; then
            \cp -arpf $old_dir/vhost/* $setup_path/vhost
        fi
        ls $setup_path/vhost/*

    fi
    
    # 根据内存优化waf.conf文件
    Optimize_waf_conf_file

    #开机启动文件
    \cp -arpf btw.init /etc/init.d/btw
    if [ $? -ne "0" ]; then
        Red_Error "无法复制文件到 /etc/init.d/btw"
    fi

    chmod +x /etc/init.d/btw
    ln -sf /etc/init.d/btw /usr/bin/btw
    if [ $? -ne "0" ]; then
        echo -e "/etc/init.d/btw软链接到/usr/bin/btw 失败,将无法正常使用btw命令."
    fi

    \cp -arpf btw.service /usr/lib/systemd/system/btw.service
    if [ $? -ne "0" ]; then
        echo -e "无法复制文件到 /usr/lib/systemd/system/btw.service,将无法设置开机启动."
    fi

    echo -e "正在解压文件中,请稍等..."
    tar -zxf ${Mirror_file}
    if [ $? -ne "0" ]; then
        Red_Error "解压 ${Mirror_file} 失败"
    fi


    echo -e "正在安装镜像中,请稍等..."
    docker load -i "btwaf-openresty:latest.tar"
    if [ $? -ne "0" ]; then
        Red_Error "ERROR: Failed import image!" "ERROR: 导入nginx镜像文件失败！"
    fi

    docker load -i "btwaf-mysql:latest.tar"
    if [ $? -ne "0" ]; then
        Red_Error "ERROR: Failed import image!" "ERROR: 导入mysql镜像文件失败！"
    fi

    rm -f ${Mirror_file} "btwaf-openresty:latest.tar" "btwaf-mysql:latest.tar"
    
    rm -f ${Cloudwaf_file}
    rm -rf $setup_path/new_cloudwaf
    
}


Start_Monitor(){
    # MYSQL
    if [ "$mysql_container_exists" == "1" ]; then
        echo -e "$MYSQL_NAME 容器已存在,正在启动..."
        docker start $MYSQL_NAME 2>&1 >/dev/null
        if [ $? -ne "0" ]; then
            echo "ERROR: 启动 $MYSQL_NAME 容器失败.尝试重启docker服务中..."
            systemctl reset-failed docker.service
            systemctl restart docker.service
            docker start $MYSQL_NAME 2>&1 >/dev/null
            if [ $? -ne "0" ]; then
                Red_Error "ERROR: Failed start $MYSQL_NAME container!" "ERROR: 启动 $MYSQL_NAME 容器失败！"
            fi
        fi

    else
        echo -e "正在创建 $MYSQL_NAME 容器..."
        #设置权限
        chmod 644 $setup_path/mysql/conf/conf.d/my.cnf

        Script_Command "docker run -p 127.0.0.1:33060:3306 --name $MYSQL_NAME --restart=always --privileged=true \
        -v $setup_path/mysql/log:/var/log/mysql \
        -v $setup_path/mysql/data:/var/lib/mysql \
        -v $setup_path/mysql/conf:/etc/mysql \
        -v /etc/localtime:/etc/localtime:ro \
        --hostname "$MYSQL_NAME" \
        -e MYSQL_ROOT_PASSWORD="$MYSQL_PASS" -d btwaf-mysql:latest"

        if [ "$exit_code" -ne "0" ]; then
            echo "ERROR: 创建 $MYSQL_NAME 容器失败.尝试重启docker服务与防火墙服务..."
            if Command_Exists "firewall-cmd"; then
                systemctl restart firewalld
            elif Command_Exists "ufw"; then
                systemctl restart ufw
            fi
            systemctl reset-failed docker.service
            systemctl restart docker.service
            Script_Command "docker start $MYSQL_NAME 2>&1 >/dev/null"
            if [ "$exit_code" -ne "0" ]; then
                Red_Error "ERROR: Failed create $MYSQL_NAME container!" "ERROR: 创建 $MYSQL_NAME 容器失败！"
            fi
        fi

        echo "$MYSQL_PASS" > $setup_path/nginx/conf.d/waf/mysql_default.pl

    fi
  
    # NGINX
    if [ "$nginx_container_exists" == "1" ]; then
        echo -e "$NGINX_NAME 容器已存在,正在启动..."
        docker start $NGINX_NAME 2>&1 >/dev/null
        if [ $? -ne "0" ]; then
            echo "ERROR: 启动 $NGINX_NAME 容器失败.尝试重启docker服务中..."
            systemctl reset-failed docker.service
            systemctl restart docker.service
            docker start $NGINX_NAME 2>&1 >/dev/null
            if [ $? -ne "0" ]; then
                Red_Error "ERROR: Failed start $NGINX_NAME container!" "ERROR: 启动 $NGINX_NAME 容器失败！"
            fi
        fi

    else
        echo "正在创建 $NGINX_NAME 容器..."

        if [[ "$LXC_install" == "yes" ]]; then
            # LXC容器 ulimit 要设置成100000 与 --net=host 有关 ulimit过大导致
            echo -e "在LXC容器安装"
            Script_Command "docker run --name $NGINX_NAME --net=host --restart=always \
            -v $setup_path/nginx/logs:/usr/local/openresty/nginx/logs \
            -v $setup_path/nginx/logs:/www/wwwlogs \
            -v $setup_path/wwwroot:/www/wwwroot \
            -v /waf/:/etc/nginx/waf/html \
            -v $setup_path/nginx/conf.d:/etc/nginx \
            -v $setup_path/nginx/conf:/usr/local/openresty/nginx/conf \
            -v /etc/localtime:/etc/localtime:ro \
            --ulimit nofile=100000 \
            --ulimit core=0 \
            --hostname "$NGINX_NAME" \
            -d btwaf-openresty:latest"

        else
            Script_Command "docker run --name $NGINX_NAME --net=host --restart=always \
            -v $setup_path/nginx/logs:/usr/local/openresty/nginx/logs \
            -v $setup_path/nginx/logs:/www/wwwlogs \
            -v $setup_path/wwwroot:/www/wwwroot \
            -v $setup_path/nginx/conf.d:/etc/nginx \
            -v /waf/:/etc/nginx/waf/html \
            -v $setup_path/nginx/conf:/usr/local/openresty/nginx/conf \
            -v /etc/localtime:/etc/localtime:ro \
            --ulimit nofile=1000001 \
            --ulimit core=0 \
            --hostname "$NGINX_NAME" \
            -d btwaf-openresty:latest"    
        fi

        if [ "$exit_code" -ne "0" ]; then
            echo "ERROR: 创建 $NGINX_NAME 容器失败.尝试重启docker服务中..."
            systemctl reset-failed docker.service
            systemctl restart docker.service
            Script_Command "docker start $NGINX_NAME 2>&1 >/dev/null"
            if [ "$exit_code" -ne "0" ]; then
                Red_Error "ERROR: Failed create $NGINX_NAME container!" "ERROR: 创建 $NGINX_NAME 容器失败！"
            fi
        fi

        sleep 3
        # docker exec $NGINX_NAME groupadd -g 1000 www
        # docker exec $NGINX_NAME useradd -r -s /sbin/nologin -g www -u 1000 www
        # if [ $? -ne "0" ]; then
        #     echo -e "ERROR: Failed create www user!" "ERROR: 创建 www 用户失败！请稍等正在重试中..."
        #     sleep 5
        #     docker exec $NGINX_NAME groupadd -g 1000 www
        #     docker exec $NGINX_NAME useradd -r -s /sbin/nologin -g www -u 1000 www
        #     if [ $? -ne "0" ]; then
        #         Red_Error "ERROR: Failed create www user!" "ERROR: 创建 www 用户失败！"
        #     fi
        # fi

    fi

}

Check_apt_status(){

    MAX_RETRIES=30
    retries=0

    while [ $retries -lt $MAX_RETRIES ]; do
        output=$(ps aux| grep -E '(apt|apt-get)\s' 2>&1)
        check_output=$(echo "$output" | grep -E '(apt|apt-get)\s')
        
        # 如果 check_output 为空，终止循环
        if [ -z "$check_output" ]; then
            break
        fi

        retries=$((retries + 1))

        echo "apt-get正在使用中,${retries}/${MAX_RETRIES}次后将自动退出,10秒后再尝试..."
        echo "$check_output"
        wait_msg="请耐心等待"
        wait_time="10"
        Bored_waiting
        
    done

    if [ $retries -ge $MAX_RETRIES ]; then
        echo "$output" > /tmp/waf_install_log.txt
        Red_Error "ERROR: apt-get命令超过最大等待次数: ${MAX_RETRIES}. 请勿在安装时使用apt/apt-get命令或者安装软件,请尝试重新安装!"
    fi

}

Check_Connect_mysql(){

    MAX_RETRIES=50
    retries=0

    while [ $retries -lt $MAX_RETRIES ]; do
        # 使用的错误密码
        output=$(docker exec -i $MYSQL_NAME mysql -u root -p"test" -e " SHOW DATABASES;" 2>&1)
        connect_mysql=$(echo "$output" |grep "connect to local MySQL server")
        
        # 如果 connect_mysql 为空，终止循环
        if [ -z "$connect_mysql" ]; then
            mysql_run="1"
            break
        fi

        retries=$((retries + 1))

        echo "MySQL is not running. mysql未启动完成, 10秒后再尝试, ${retries}/${MAX_RETRIES}..."

        if [[ "${retries}" == "1" ]] || [[ "${retries}" == "${MAX_RETRIES}" ]]; then
        # 仅第一次和最后一次打印信息
            echo "$connect_mysql"
        fi
        wait_msg="请耐心等待"
        wait_time="10"
        Bored_waiting
        
    done

    if [ $retries -ge $MAX_RETRIES ]; then
        Red_Error "ERROR: 超过最大重试次数,无法连接到MySQL. 请尝试重新安装！"
    fi

}

init_CloudWaf(){
    echo -e "正在初始化堡塔云WAF..."
    #检查用户是否存在
    cd $waf_path
    chmod 700 $waf_path/CloudWaf
    user_status=$($waf_path/CloudWaf default_user_created)
    # echo "$user_status"
    if [ "$user_status" = "0" ]; then
        #用户不存在时创建新用户
        default_user=$(cat /dev/urandom | head -n 16 | md5sum | head -c 8 )
        default_password=$(cat /dev/urandom | head -n 16 | md5sum | head -c 8 )
    
        create_user=$($waf_path/CloudWaf create_default_user "${default_user}" "${default_password}")
        get_username=$($waf_path/CloudWaf get_username)
        echo default_user: "$get_username"
        if [[ "$default_user" != "$get_username" ]]; then
                echo default_user: "$default_user"
                echo create_user: "$create_user" 
                echo get_username: "$get_username" 
                Red_Error "ERROR: 创建用户失败，请尝试重新安装！"
        fi

        password_check=$(echo "$create_user" |grep "password:"|awk -F ":" '{print $2}'|awk '{print $1}')
        echo default_password: "$password_check"
        if [ -z "$password_check" ]; then
            echo create_user: "$create_user"
            echo default_password_check: "$password_check"
            Red_Error "ERROR: 创建用户失败，密码为空，请尝试重新安装！"
        fi

    else
        #用户存在时重置用户名与密码
        echo -e "正在重置用户名与密码"
        default_user=$(cat /dev/urandom | head -n 16 | md5sum | head -c 8 )
        reset_new_user=$($waf_path/CloudWaf reset_username "${default_user}")
        get_username=$($waf_path/CloudWaf get_username)
        echo default_user: "$get_username"
        if [[ "$default_user" != "$get_username" ]]; then
            echo default_user: "$default_user"
            echo reset_new_user: "$reset_new_user"
            echo get_username: "$get_username" 
            Red_Error "ERROR: 重置用户失败，请尝试重新安装！"
        fi

        default_password=$(cat /dev/urandom | head -n 16 | md5sum | head -c 8 )
        reset_new_password=$($waf_path/CloudWaf reset_password "${default_password}")
        password_check=$(echo "$reset_new_password" |grep "Reset password success:" |awk -F ":" '{print $2}'|awk '{print $1}')
        echo Reset_password: "$password_check"
        if [ -z "$password_check" ]; then
            echo reset_new_password: "$reset_new_password"
            echo Reset_password_check: "$password_check"
            Red_Error "ERROR: 重置用户密码失败，请尝试重新安装！"
        fi
    fi

    # adminpath
    cd $waf_path
    adminpath=$(cat /dev/urandom | head -n 16 | md5sum | head -c 8 )
    set_adminpath=$($waf_path/CloudWaf set_auth_path "${adminpath}")
    get_auth_path=$($waf_path/CloudWaf get_auth_path)

    if [[ "$adminpath" =~ "$get_auth_path" ]]; then
        echo set_adminpath: "$set_adminpath"
        echo adminpath_check: "$get_auth_path"
        Red_Error "ERROR: 设置安全入口失败，请尝试重新安装！"
    fi

    #检查 WAF_Port 端口是否使用
    Check_WAF_Port=$(ss -ltnp | grep -E ":(${WAF_Port})\\s" |grep -v CloudWaf)
    if [ ! -z "$Check_WAF_Port" ]; then
        echo -e "$WAF_Port 已经被使用,正在使用随机端口"
        while true; do
        WAF_Port=$((RANDOM % 9000 + 1000))
        if ! ss -tln | grep -q ":$WAF_Port "; then
            echo "$WAF_Port"
            break
        fi
        done
    fi

    if [ ! -f "$waf_path/data/.server-port" ]; then
        echo "$WAF_Port" > $waf_path/data/.server-port
    fi

    # 检查是否可以连接到mysql
    Check_Connect_mysql

    check_database=$(ls "$setup_path/mysql/data/" |grep -w btwaf)
    if [ -z "$check_database" ]; then
        create_database="0"
    else
        echo "数据库已存在."    
    fi

    if [ "$mysql_run" == "1" ]; then
        check_database=$(docker exec -i $MYSQL_NAME mysql -u root -p"$MYSQL_PASS" -e " SHOW DATABASES LIKE 'btwaf';" 2>&1 )
        database=$(echo "$check_database" |grep btwaf)
        if [ -z "$database" ]; then
            create_database="0"
        fi
    fi    

    if [ "$create_database" == "0" ] && [ "$mysql_run" == "1" ]; then
    # 数据库不存在时，导入数据
        # echo -e "正在导入数据中"
        # wait_msg="请耐心等待"
        # wait_time="10"
        # Bored_waiting

        MAX_RETRIES=30
        retries=0

        while [ $retries -lt $MAX_RETRIES ]; do
        if docker exec -i $MYSQL_NAME mysql -u root -p"$MYSQL_PASS" -e " SHOW DATABASES;"  >/dev/null 2>&1; then
            echo "正在导入数据中,请耐心等待..."

            # 再检查是否可以连接到mysql
            sleep 2
            Check_Connect_mysql

            output=$(docker exec -i $MYSQL_NAME mysql -u root -p"$MYSQL_PASS" -e "CREATE DATABASE btwaf CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;" 2>&1 )
            if [ $? -ne "0" ]; then
                docker logs --tail=10 $MYSQL_NAME
                echo ""
                date
                echo "$output"
                Red_Error "ERROR: Failed create database!" "ERROR: 创建数据库失败，请尝试重新安装！"
            fi

            output=$(docker exec -i $MYSQL_NAME mysql -u root -p"$MYSQL_PASS" btwaf < $setup_path/nginx/conf.d/waf/inc/request_total.sql 2>&1 )
            if [ $? -ne "0" ]; then
                docker logs --tail=10 $MYSQL_NAME
                echo ""
                date
                echo "$output"
                Red_Error "ERROR: Failed import database!" "ERROR: 导入数据库失败"
            fi

            output=$(docker exec -i $MYSQL_NAME mysql -u root -p"$MYSQL_PASS" btwaf < $setup_path/nginx/conf.d/waf/inc/btwaf_black.sql 2>&1 )
            if [ $? -ne "0" ]; then
                docker logs --tail=10 $MYSQL_NAME
                echo ""
                date
                echo "$output"
                Red_Error "ERROR: Failed import database2!" "ERROR: 导入数据库失败2"
            fi

            #重启nginx
            /etc/init.d/btw ${NGINX_NAME}_restart

            break
        else
            retries=$((retries+1))
            echo "MySQL is not running. mysql未启动完成22, 10秒后再尝试, ${retries}/${MAX_RETRIES}..."
            wait_msg="请耐心等待"
            wait_time="10"
            Bored_waiting
            
        fi
        done

        if [ $retries -ge $MAX_RETRIES ]; then
            Red_Error "Error: 超过最大重试次数,无法连接到MySQL.导入数据库出错."
        fi

    fi


    #启动管理界面与四层拦截
    /etc/init.d/btw ip_restart
    if [ $? -ne "0" ]; then
        echo -e "ERROR: ipfilter出错,正在输出进程,日志信息"
        tail -n 10 ${waf_path}/logs/ipfilter_error.log
        ps aux|grep -v grep|grep -v panel|grep "ipfilter"

        echo "正在尝试重启ipfilter..."
        sleep 5
        /etc/init.d/btw ip_restart
        if [ $? -ne "0" ]; then
            echo "ERROR: 启动ipfilter出错！"
        fi
    fi

    /etc/init.d/btw admin_restart    
    if [ $? -ne "0" ]; then
        echo -e "ERROR: 启动堡塔云WAF管理界面出错,正在输出进程,日志信息"
        tail -n 10 ${waf_path}/logs/error.log

        current_date=$(date +"%Y%m/%d")
        tail -n 10 ${waf_path}/logs/debug/${current_date}.log
        echo ""
        ps aux|grep -v grep|grep -E "${waf_path}|CloudWaf"
        ss -tulnp|grep ${WAF_Port}

        echo "正在尝试重启堡塔云WAF管理界面..."
        if [ ! -s "${waf_path}/ssl/certificate.pem" ] || [ ! -s "${waf_path}/ssl/privateKey.pem" ]; then
            echo "ssl证书文件为空,正在重新处理 ssl certificate file is empty"
            rm -f ${waf_path}/ssl/*
            cp -arfp ${setup_path}/wwwroot/nginx/fullchain.pem ${waf_path}/ssl/certificate.pem
            cp -arfp ${setup_path}/wwwroot/nginx/privkey.pem ${waf_path}/ssl/privateKey.pem
        fi
        sleep 5
        /etc/init.d/btw admin_restart
        if [ $? -ne "0" ]; then
            Red_Error "ERROR: 启动堡塔云WAF管理界面出错！"
        fi
    fi

}

Service_Add(){
    if [ $Command_Exists systemctl ]; then
        systemctl daemon-reload
        systemctl enable btw

    else
        if [ "${PM}" == "yum" ] || [ "${PM}" == "dnf" ]; then
            chkconfig --add btw
            chkconfig --level 2345 btw on            
        elif [ "${PM}" == "apt-get" ]; then
            update-rc.d btw defaults
        fi
    fi
}

Service_Del(){
    if [ $Command_Exists systemctl ]; then
        rm -f /usr/lib/systemd/system/btw.service
        systemctl disable btw
    else
        if [ "${PM}" == "yum" ] || [ "${PM}" == "dnf" ]; then
            chkconfig --del btw
            chkconfig --level 2345 btw off
        elif [ "${PM}" == "apt-get" ]; then
            update-rc.d btw remove
        fi
    fi
}

Container_error_start(){
    echo -e "$container 运行出错,正在尝试重启..."
    docker restart $container 2>&1 >/dev/null
    sleep 1
}

Container_error(){
    echo -e "\033[33m$container log: \033[0m"
    # nginx容器 直接查看日志文件可以显示时间
    if [[ "$container" == "$NGINX_NAME" ]]; then
        Nginx_Viewed="1"
        if [[ -f "$setup_path/nginx/logs/error.log" ]]; then
            tail -n 10 $setup_path/nginx/logs/error.log
        else
            docker logs --tail=10 $container
        fi
    else        
        docker logs --tail=10 $container
    fi
    Red_Error "ERROR: Failed create $container container!" "ERROR: $container 容器未启动成功！"

}

Container_Status(){

    for container in ${Containers}; do
        if [ "$container" == "$NGINX_NAME" ]; then
            container_check_command=$nginx_command
        elif [ "$container" == "$MYSQL_NAME" ]; then
            container_check_command=$mysql_command
        fi

            $container_check_command
            if [ $? -ne "0" ]; then
                Container_error_start

                #尝试启动后再检查一次
                $container_check_command
                if [ $? -ne "0" ]; then
                    Container_error
                fi
            fi
	done 

}

Re_Install_Check(){
	echo -e "----------------------------------------------------"
	echo -e "\033[33m检测到上一次卸载堡塔云WAF时保留的旧数据,请按照选项选择安装方式!\033[0m"
    echo -e "\033[33m如果还原的版本跨度过大可能会导致启动失败!\033[0m"
    echo -e ""
	echo -e "1) 还原以前的备份并安装堡塔云WAF!"
    echo -e ""
	echo -e "2) 不使用原有备份,全新安装堡塔云WAF!"
    echo -e ""
	echo -e "----------------------------------------------------"
	read -p "请输入对应选项[1|2]进行安装或输入任意内容退出安装: " yes;
	if [ "$yes" == "1" ]; then
		re_install="yes"
		echo "开始安装堡塔云WAF并还原数据..."
	elif [ "$yes" == "2" ]; then
		echo "开始全新安装堡塔云WAF..."
	else
		echo -e "------------"
		echo "取消安装"
		exit;
	fi
}


Backup_WAF(){
	if [ -f "/etc/init.d/btw" ]; then
		/etc/init.d/btw stop
		sleep 1
    elif [ -f "${setup_path}/btw.init" ]; then
		bash ${setup_path}/btw.init stop
		sleep 1
	fi

    if [ ! -d "${setup_path}" ]; then
        echo "Error: ${setup_path} 不存在,无法进行备份"
        exit 1
    fi

	if [ -d "${old_dir}" ];then
        time_o=$(date +%Y_%m_%d_%H_%M_%S)
		mv ${old_dir} ${old_dir}_${time_o}
        echo -e "\033[33m存在${old_dir}目录，已移动至：${old_dir}_${time_o}\033[0m"
	fi
	
    mv ${setup_path} ${old_dir}
    if [ $? -ne "0" ]; then
        echo -e "\033[33m ${setup_path}目录，已备份至：${old_dir} \033[0m"
    fi

}

Container_Uninstall(){

    for container in ${Containers}; do
        echo -e  ""
        echo -e  "正在删除 $container"
        docker rm -f $container
	done 

}

WAf_Uninstall(){

    Container_Uninstall

    /etc/init.d/btw admin_stop
    /etc/init.d/btw ip_stop
    
    Service_Del

    rm -f /usr/bin/btw
    rm -f /etc/init.d/btw
    

    if [[ -d "${setup_path}" ]]; then
        cd $install_path
        rm -rf ${setup_path}
    fi

    echo -e "堡塔云WAF卸载成功!"
    exit

}

Offline_Install_Check(){
    cd ${PWD_d}

    if [[ "$Offline" == "offline" ]]; then
        echo -e "您正在使用离线安装模式 $Offline"
        echo -e " "
        offline_install="offline"
        
        if [[ ! -f "${Mirror_file}" ]] || [[ ! -f "${Cloudwaf_file}" ]] ; then
            ls -l
            echo -e "\033[31m"${Mirror_file}" "${Cloudwaf_file}" 文件不存在,\n请将 install_cloudwaf.sh、"${Mirror_file}"、"${Cloudwaf_file}" 放在相同的目录下\033[0m"
            #不支持带有目录,如：bash /tmp/install_cloudwaf.sh offline，否则无法找到文件
            echo -e "\033[31m最后执行此命令进行安装堡塔云WAF： bash install_cloudwaf.sh offline \033[0m"
            echo -e "推荐使用更方便的在线安装命令(需要连接互联网)：bash install_cloudwaf.sh "
            exit 1
        fi
    fi
}

Overlay_install(){
    # 检查文件是否存在，判断是否覆盖安装
    if [ -f "$waf_path/CloudWaf" ]; then

        echo -e "----------------------------------------------------"
        echo -e "\033[33m检测到您正在覆盖安装堡塔云WAF!\033[0m"
        echo -e " "
        echo -e "1) 清空配置并覆盖安装堡塔云WAF"
        echo -e " "
        echo -e "如果您想更新请使用 btw 17 命令进行更新或者执行以下命令更新\n curl -k https://download.bt.cn/cloudwaf/scripts/update_cloudwaf.sh |bash"
        echo -e " "
        echo -e "\033[33m提示: 如果上次执行命令安装失败,请输入 1 覆盖安装.\033[0m"
        echo -e "----------------------------------------------------"
        read -p "请输入 1 进行覆盖安装或输入任意内容退出覆盖安装: " yes;
        if [ "$yes" == "1" ]; then
            echo -e ""
            read -p "配置清空后将无法恢复,确认清空并覆盖安装?(y/n): " go;
            if [ "$go" == 'y' ];then
                echo -e ""
                echo "正在清空配置覆盖安装堡塔云WAF..."
                sleep 3
                O_install="rm"

            else
                echo -e "取消覆盖安装"
                exit;
                
            fi
        else
            echo -e "------------"
            echo -e "取消覆盖安装"
            exit;
        fi
    fi
}

Install_Main(){
    #先不开还没有写完 Re_Install_Check
    # if [ -d "${old_dir}" ]; then
	# 	Re_Install_Check
	# fi

    startTime=`date +%s`
    Check_Port
    Check_Sys_Write
    Check_Disk_Space

    # 检查是否有冲突软件包
    Conflicting_Package_Check

    if [ "$offline_install" != "offline" ]; then
        CentOS_89check
        echo -e " "
        echo -e "\033[33m如果系统源下载慢,建议参考此教程更换源：https://www.bt.cn/bbs/thread-58005-1-1.html \033[0m"
        echo -e " "
        if [ "$PM" == "yum" ]; then
            Install_RPM_Pack
        else
            Install_Deb_Pack
        fi
    fi

    Check_Sys_Packs

    if [ "$offline_install" != "offline" ]; then
        get_node_url
    fi

    set +e
    Docker_Check
    Docker_Compose_Check


    if [ "$is_docker" != "1" ] ||  [ "$is_docker_compose" != "1" ] && [ "$offline_install" != "offline" ]; then
        Docker_Download_Url_Check
    fi
    
    if [ "$is_docker" != "1" ] && [ "$offline_install" != "offline" ]; then
        Docker_Install
        Docker_Compose_Check
    fi

    if [ "$is_docker_compose" != "1" ] && [ "$offline_install" != "offline" ]; then
        Docker_Compose_Install
    fi
    
    Docker_Start
    
    Container_Check
    Download_Copy_Files
    Install_Mirror
    Start_Monitor
    init_CloudWaf
    Service_Add

    if [ -f "/www/server/panel/BT-Panel" ] && [ "$offline_install" != "offline" ]; then
        Init_Docker_Manager
        Pip_Install
    fi

    Set_Firewall
    Get_Ip_Address


    if [[ "$re_install" == "yes" ]] && [[ -d "${old_dir}" ]]; then
        cd $install_path
        time_f=$(date +%Y_%m_%d_%H_%M_%S)
        mv ${old_dir} ${old_dir}_${time_f}
        echo -e "\033[33m${old_dir} 目录，已移动至：${old_dir}_${time_f}\033[0m"
        echo -e "\033[33m如需要删除,请手动删除 ${old_dir}_${time_f} \033[0m"
        exit 0;
    fi
}


action="${1}"
Offline="${1}"
only_docker="${1}"
src_code="${1}"

#检查是否存在WAF类型
Check_Waf_Type
if [[ "$Slave" == "yes" ]]; then  
    # 有堡塔云WAF集群：被控
    echo -e "\033[33m不支持在被控上执行堡塔云WAF单机版安装命令，如需要切换到堡塔云WAF单机版请先卸载被控。\033[0m"
    exit 1;
fi

if [[ "$Master" == "yes" ]]; then  
    # 有堡塔云WAF集群：主控
    echo -e "\033[33m不支持在主控上执行堡塔云WAF单机版安装命令，如需要切换到堡塔云WAF单机版请先卸载主控。\033[0m"
    echo -e "\033[31m注意：卸载主控，请先确认此主控是处于弃用状态，否则可能导致堡塔云WAF集群无法进行管理。\033[0m"
    exit 1;
fi


if [ "$action" == "uninstall" ];then
	echo -e "----------------------------------------------------"
	echo -e "\033[33m检测到您正在卸载堡塔云WAF,请按照选项选择卸载方式!\033[0m"
    echo -e "\033[33m注意：$Containers 容器不会进行备份,仅备份配置及数据 \033[0m"
    echo -e " "
	echo -e "1) 备份数据后卸载：保存原有配置及数据并卸载堡塔云WAF"
    echo -e " "
	echo -e "2) 完全卸载：清空原有配置及数据并卸载堡塔云WAF"
        echo -e " "
	echo -e "----------------------------------------------------"
	read -p "请输入对应选项[1|2]进行卸载或输入任意内容退出卸载: " yes;
	if [ "$yes" == "1" ]; then
		Backup_WAF
		echo -e "----------------------------------------------------"
		echo -e "\033[33m已备份原有配置及数据至: ${old_dir}\033[0m"
	elif [ "$yes" == "2" ]; then
        echo -e ""
        read -p "配置及数据清空后将无法恢复,确认清空?(y/n): " go;
        if [ "$go" == 'y' ];then
            echo -e ""
            echo "正在清空堡塔云WAF配置及数据..."
            sleep 5
        else
            echo -e "------------"
            echo -e "取消卸载"
            exit;
        fi
	else
		echo -e "------------"
		echo -e "取消卸载"
		exit;
	fi
	
	WAf_Uninstall
	exit 0

else

#先检查是否存在相关容器与$setup_path目录
Container_Check_22

echo "
+--------------------------------------------------------------------------------------
| Bt-WAF FOR CentOS/Ubuntu/Debian
|
| Copyright © 2015-2099 BT-SOFT(https://www.bt.cn) All rights reserved.
|
| The Bt-WAF URL will be https://SERVER_IP:${WAF_Port} when installed.
|--------------------------------------------------------------------------------------
| 为了您的正常使用,建议使用全新或纯净的系统安装,不支持已使用80 443 33060端口的系统安装
|
| 堡塔云WAF使用 Docker 服务并创建 $Containers 容器
|
| 容器不存储数据,存储于宿主机:$setup_path,为了您的数据安全请勿在容器内存储数据
+--------------------------------------------------------------------------------------
"
echo "取消安装请输入 n, 确认安装请输入 Y 或 y, 最后按回车键执行."
while [ "$go" != 'Y' ] && [ "$go" != 'y' ] && [ "$go" != 'n' ]; do
	read -p "Do you want to install Bt-WAF to the $setup_path directory now? (Y/y/n): " go;
done

if [ "$go" == 'n' ];then
  exit;
fi
    LXC_install_tips
    Offline_Install_Check "$@"
    Only_Docker
    Overlay_install
    Install_Main "$@"

    status_01="1"
    Little_tail
    
    # 二维码
    qrencode

fi
echo -e "=================================================================="
echo -e "\033[32m堡塔云WAF安装完成! Installed successfully!\033[0m"
echo -e "=================================================================="
echo  "外网访问地址: https://${getIpAddress}:${WAF_Port}/${adminpath}"
echo  "内网访问地址: https://${LOCAL_IP}:${WAF_Port}/${adminpath}"
echo -e "username: ${default_user}"
echo -e "password: ${default_password}"
echo -e "\033[33mIf you cannot access the Bt-WAF \033[0m"
echo -e "\033[33mrelease the following Bt-WAF port [${WAF_Port},80,443] in the security group\033[0m"
echo -e "\033[33m若无法访问堡塔云WAF，请检查防火墙/安全组是否有放行[${WAF_Port},80,443]端口\033[0m"
echo -e ""
echo -e "=========================打开堡塔云WAF前请看======================="
echo -e ""
echo -e " 因默认启用自签证书https加密访问，浏览器将提示不安全"
echo -e " 点击【高级】-【继续访问】或【接受风险并继续】访问"
echo -e " 参考教程：https://www.bt.cn/bbs/thread-117246-1-1.html"
echo -e "" 
echo -e "=================================================================="

endTime=`date +%s`
((outTime=($endTime-$startTime)/60))
echo -e "Time consumed:\033[32m $outTime \033[0mMinute!"
rm -f /tmp/waf_install_log.txt
rm -f ${PWD_d}/install_cloudwaf.sh