#!/bin/bash

#
#   bmc update script
#

# update path
update_tmp_dir=`mktemp -d /share/data/update.XXXXXX`
db_backup_dir=
java_ver=
html_ver=
bmc_yml=/share/data/docker/bmcinit/bmc.yml
application_yml=/share/data/docker/bmcinit/resources/application.yml
application_test_yml=/share/data/docker/bmcinit/resources/application-test.yml
my_cnf=/share/data/docker/mariadb/mysql_conf/my.cnf
redis_conf=/share/data/docker/redis/redis_conf/redis.conf
d=`date +'%Y%m%d%H%m%S'`
bmc_bak_dir=/share/data/bmc_bak_${d}
rm_update=

check_some_command(){
    type tar >/dev/null 2>&1 || { echo >&2 "tar 命令没有安装，升级程序中断。"; exit 1; }
    type curl >/dev/null 2>&1 || { echo >&2 "curl 命令没有安装，升级程序中断。"; exit 1; }
    type docker >/dev/null 2>&1 || { echo >&2 "docker 命令没有安装，升级程序中断。"; exit 1; }
    type docker-compose >/dev/null 2>&1 || { echo >&2 "docker-compose 命令没有安装，升级程序中断。"; exit 1; }
}

check_update_zip(){
    [ -e $1 ] || { echo >&2 "升级压缩包不存在，升级程序中断。请检查参数 $1 是否存在。"; exit 1; }

    tar -xvf $1 -C $update_tmp_dir
    if [ -d ${update_tmp_dir}/update ]; then
		rm_update=${update_tmp_dir}
        update_tmp_dir=${update_tmp_dir}/update
    fi

    [ -d "$update_tmp_dir" ] || { echo >&2 "解压升级压缩包目录 'update' 不存在，升级程序中断。" exit 1; }

    # check bmc.yml
    [ -e "${update_tmp_dir}/bmc/bmc.yml" ] || { echo >&2 "bmc.yml 文件不存在，升级程序中断。"; exit 1; }

    # check java
    if [ -d "${update_tmp_dir}/java" ]; then
        if [ "$(ls -A ${update_tmp_dir}/java)" ]; then
            java_ver=`cat ${update_tmp_dir}/java/version.txt`
            [ -e ${update_tmp_dir}/java/${java_ver/:/_}.tar ] || { echo >&2 "java 升级目录文件格式错误，升级程序中断。"; exit 1; }
        fi
    fi

    # check html
    if [ -d "${update_tmp_dir}/html" ]; then
        if [ "$(ls -A ${update_tmp_dir}/html)" ]; then
            html_ver=`cat ${update_tmp_dir}/html/version.txt`
            [ -e ${update_tmp_dir}/html/${html_ver/:/_}.tar ] || { echo >&2 "hmtl 升级目录文件格式错误，升级程序中断。"; exit 1; }
        fi
    fi
	
	# check resources
	if [ -d "${update_tmp_dir}/resources" ]; then
        if [ "$(ls -A ${update_tmp_dir}/resources)" ]; then
            [ -e ${update_tmp_dir}/resources/application.yml ] || { echo >&2 "application.yml 升级目录文件格式错误，升级程序中断。"; exit 1; }
            [ -e ${update_tmp_dir}/resources/application-test.yml ] || { echo >&2 "application-test.yml 升级目录文件格式错误，升级程序中断。"; exit 1; }
            [ -e ${update_tmp_dir}/resources/my.cnf ] || { echo >&2 "my.cnf 升级目录文件格式错误，升级程序中断。"; exit 1; }
            [ -e ${update_tmp_dir}/resources/redis.conf ] || { echo >&2 "redis.conf升级目录文件格式错误，升级程序中断。"; exit 1; }
        fi
    fi

    [ ! -n $java_ver -a ! -n $html_ver ] && { echo >&2 "java 和 html 目录不能同时为空，升级程序中断。"; exit 1; }
}

update_db(){
    if [ -d ${update_tmp_dir}/sql ]; then
        for f in `find ${update_tmp_dir}/sql -name "*.sql"`
        do
            docker exec -i mariadb sh -c 'mysql -uroot -proot -Dbmc-iaas' < $f
            [ $? -ne 0 ] && return $?
        done
    fi
    return 0
}

rollback(){
    docker-compose -f ${bmc_yml} rm -fs bmc_html
    docker-compose -f ${bmc_yml} rm -fs bmc_java
    docker-compose -f ${bmc_yml} rm -fs mariadb

    cp ${bmc_bak_dir}/bmc.yml ${bmc_yml}
    rm -rf /share/data/docker/mariadb/mysql_data
    cp -rd ${bmc_bak_dir}/mysql_data /share/data/docker/mariadb/mysql_data
	rm -rf /share/data/docker/mariadb/mysql_conf
    cp -rd ${bmc_bak_dir}/mysql_conf /share/data/docker/mariadb/mysql_conf
	rm -rf /share/data/docker/bmcinit/resources
    cp -rd ${bmc_bak_dir}/resources /share/data/docker/bmcinit/resources
	rm -rf /share/data/docker/redis/redis_conf
    cp -rd ${bmc_bak_dir}/redis_conf /share/data/docker/redis/redis_conf


    docker-compose -f ${bmc_yml} up -d mariadb
    docker-compose -f ${bmc_yml} up -d bmc_java
    docker-compose -f ${bmc_yml} up -d bmc_html

    echo >&2 "升级失败..."
	rm -rf ${update_tmp_dir}
	rm -rf ${bmc_bak_dir}
    exit 1
}

# script start

# 1. check user privilege
[ $UID -ne 0 ] && { echo >&2 "非root用户，升级程序中断，请使用root用户执行脚本。"; exit 1; }

# 2. check command
check_some_command

# 3. check update zip
[ $# -ne 1 ] && { echo >&2 "必须输入升级压缩包文件路径参数，升级程序中断。"; exit 1; }

echo "开始检查升级压缩包..."
check_update_zip $1
echo "升级压缩包正常..."


[ -e $bmc_yml ] || { echo >&2 "旧版镜像脚本 ${bmc_yml} 不存在，升级程序中断。"； exit 1; }

echo "开始加载镜像..."
if [ -n "$java_ver" ]; then
    docker load -i ${update_tmp_dir}/java/${java_ver/:/_}.tar
    [ $? -ne 0 ] && { echo >&2 "加载bmc_java镜像失败，升级程序中断。"; exit 1; }
fi

if [ -n "$html_ver" ]; then
    docker load -i ${update_tmp_dir}/html/${html_ver/:/_}.tar
    [ $? -ne 0 ] && { echo >&2 "加载bmc_html镜像失败，升级程序中断。"; exit 1; }
fi
echo "加载镜像成功..."

# 4. stop service
echo "停止所有服务..."
docker-compose -f ${bmc_yml} rm -fs bmc_html
docker-compose -f ${bmc_yml} rm -fs bmc_java
docker-compose -f ${bmc_yml} rm -fs mariadb

# 5. backup db
echo "开始备份数据..."
[ -d ${bmc_bak_dir} ] && rm -rf ${bmc_bak_dir}
mkdir -p -m 755 ${bmc_bak_dir}

cp -rd /share/data/docker/mariadb/mysql_data ${bmc_bak_dir}/mysql_data
cp -rd /share/data/docker/mariadb/mysql_conf ${bmc_bak_dir}/mysql_conf
cp -rd /share/data/docker/bmcinit/resources ${bmc_bak_dir}/resources
cp -rd /share/data/docker/redis/redis_conf ${bmc_bak_dir}/redis_conf
cp ${bmc_yml} ${bmc_bak_dir}/bmc.yml

# 6. update
echo "开始升级..."
cp ${update_tmp_dir}/bmc/bmc.yml ${bmc_yml}
# update resources document
rm -rf /share/data/docker/bmcinit/resources/application.yml
cp ${update_tmp_dir}/resources/application.yml ${application_yml}
rm -rf /share/data/docker/bmcinit/resources/application-test.yml
cp ${update_tmp_dir}/resources/application-test.yml ${application_test_yml}
rm -rf /share/data/docker/redis/redis_conf/redis.conf
cp ${update_tmp_dir}/resources/redis.conf ${redis_conf}
rm -rf /share/data/docker/mariadb/mysql_conf/my.cnf
cp ${update_tmp_dir}/resources/my.cnf ${my_cnf}

echo "启动mariadb服务..."
docker-compose -f ${bmc_yml} up -d mariadb
sleep 10s
while [ 1 == 1 ];
do
    tmp=`docker ps -a | grep Up | grep mariadb`
    if [ -n "${tmp}" ]; then
        break
    fi
    sleep 5s
done
echo "mariadb 服务上线..."

tmp=`find ${update_tmp_dir}/sql -name "*.sql"`
if [ -n "$tmp" ]; then
    #read -p "是否需要升级数据库? Y/N: " yes
    #if [ "${yes}X" == "YX" -o "${yes}X" == "yX" ]; then  
    update_db
    if [ $? -ne 0 ]; then
        echo "数据库升级失败，开始回退..."
        rollback
    fi
    #fi
fi

# 7. start all service
echo "启动bmc_java服务..."
docker-compose -f ${bmc_yml} up -d bmc_java
echo "启动bmc_html服务..."
docker-compose -f ${bmc_yml} up -d bmc_html

echo "等待服务上线, 大约60s..."
sleep 60s
tmp=`docker ps -a | grep Up | grep bmc_java | awk '{print $2}'`
if [ ${tmp} != ${java_ver} ]; then
    echo "bmc_java 服务启动失败，开始回退..."
    rollback
else
    echo "bmc_java 服务上线..."
fi

tmp=`docker ps -a | grep Up | grep bmc_html | awk '{print $2}'`
if [ ${tmp} != ${html_ver} ]; then
    echo "bmc_html 服务启动失败，开始回退..."
    rollback
else
    echo "bmc_html 服务上线..."
fi

ct=0
while [ $ct -lt 60 ];
do
    tmp=`curl http://127.0.0.1:80/captchaImage 2>/dev/null | grep '"code":200'`
    if [ -n "$tmp" ]; then
        echo "所有服务启动成功..."
        break
    fi
    sleep 1s
    ct=$((ct+1))
done
if [ $ct -eq 60 ]; then
    echo >&2 "服务接口访问失败，开始回退..."
    rollback
fi

# 8. update ok
rm -rf ${update_tmp_dir}
rm -rf ${rm_update}
rm -rf ${bmc_bak_dir}
echo "success"

