jenkins推送脚本 优化版

#!/bin/bash
# Source function library.
. /etc/init.d/functions

# 定义分割线
separator(){
    for ((i=1;i<=100;i++))
    do
        echo -n "="
    done
        echo -e
}

separator

# 定义后端服务器列表
group_list="ip1 ip2"

# 定义变量
port="端口"
prog="****"            # 项目目录名  格式java-xxx
prog_path="****"            # 转发路径
package_name="****.war"
source_dir="${JENKINS_HOME}/jobs/${PROMOTED_JOB_NAME}/builds/${PROMOTED_NUMBER}/archive/contract-type-web/target"
source_file="${PROMOTED_JOB_NAME}/builds/${PROMOTED_NUMBER}/archive/contract-type-web/target/$package_name"
destination_dir="/data/icourt/project/backend"
logsprog="contract-type"
destination_log_dir="/data/logs"
back_dir="/data/icourt/backup/backend/$prog"
back_prog="backend-contract-type"
back_time=`date +"%Y-%m-%d-%s"`
script_dir="/usr/lib/systemd/system"
timecheck=$(date "+%Y-%m-%d %H:%M" | cut -b 1-15)     # 过滤日志错误时间戳

NOW=`date +"%Y/%m/%d %T"`
echo -e "$NOW: 后端 $prog 代码上线将开始 ... "

# 动态创建启动脚本
service_script(){
    cat > ${script_dir}/${prog}.service << EOF
[Unit]
Description=Spring-Cloud Web Application Container
After=syslog.target network.target

[Service]
Type=simple
User=tomcat
Group=tomcat
PIDFile=/var/run/${prog_path}.pid
ExecStart=/usr/bin/java -jar ${destination_dir}/${prog}/${package_name} -Xms1024M -Xmx1024M -server -XX:+UseParallelGC
SuccessExitStatus=143
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF
}

# 检查探活页
check_Live(){
    for n in $(seq 20)
    do
        sleep 15
        echo "检查 'http://${node}:${port}/$prog_path/index.html' http 状态码 ... "
        curl_status=`curl --max-time 1 -o /dev/null -s -w %{http_code} http://${node}:${port}/$prog_path/index.html`
        echo "http 状态码 $curl_status ."

        separator

        salt $node cmd.run "grep -E -A 15 '${timecheck}' ${destination_log_dir}/${logsprog}/ssf-console.log | grep -E -A 15 'ERROR' | tail -n 50"
        if [[ ${curl_status} -eq 404 ]]
        then
            echo "$node 后端 $prog 应用启动失败,http 状态码 :${curl_status},请查看 ${destination_log_dir}/${logsprog} 日志文件 !"
            echo -e "拷贝 $package_name 到 $destination_dir 并删除代码目录 $destination_dir/$prog"
            salt $node cmd.run "cd $destination_dir && cp -f $prog/$package_name . && rm -rf $prog"
            echo "错误!退出当前脚本 …… "
            exit 8
        fi

        if [[ ${curl_status} -eq 200 ]]
        then
            separator
            echo "$node 后端 $prog 应用启动成功."
            break
        fi
        NOW=`date +"%Y/%m/%d %T"`
        echo "$NOW: 完成第 $n 次应用测试页检查 ... "
        separator
    done
}

# 第一次部署前测试能否正常启动
deploy_PreTest(){
    cat << EOF
------------------------------------------------------
|********** 开始测试程序是否能正常启动 $prog **********|
------------------------------------------------------
EOF
    echo -e "开发环境后端 $prog 代码 $package_name 在 $source_dir 目录下."
    separator
    echo -e "$node 进入测试程序步骤 ...\n$node '$destination_dir/$prog' 目录不存在,将新建代码目录 ... "
    echo "salt $node file.mkdir $destination_dir/$prog"
    salt $node file.mkdir $destination_dir/$prog

    echo -e "当前将推送版本目录 '$source_dir'\n当前将推送版本文件 ' …… $source_file'\n目标目录 '$destination_dir/$prog'\n开始拷贝推送 $prog $package_name 到 $node ... "
    echo -e "salt $node cp.get_file salt://$source_file $destination_dir/$prog/$package_name"
    salt $node cp.get_file salt://$source_file $destination_dir/$prog/$package_name

    echo -e "创建日志目录 $destination_log_dir/$logsprog"
    echo -e "salt $node file.mkdir $destination_log_dir/$logsprog"
    salt $node file.mkdir $destination_log_dir/$logsprog
    salt $node cmd.run "chown -R tomcat:root $destination_log_dir/$logsprog"

    echo -e "创建 $prog 服务启动文件"
    service_script
    mv ${script_dir}/${prog}.service /data/development/jenkins/jobs/service_dir
    salt $node cp.get_file salt://service_dir/${prog}.service ${script_dir}/${prog}.service
    

    echo "$node 开始启动 $prog 服务进行测试 ... "
    salt $node service.start $prog
    java_status=$(salt $node service.status ${prog} --out=json|awk 'NR==2 {print $NF}')
    echo -e "服务状态 $java_status"
    if [[ $java_status == 'true' ]]
    then
        echo "$node $prog 服务启动成功."
    else [[ $java_status == 'false' ]]
        echo "$node $prog 服务启动失败!"
        echo -e "拷贝 $package_name 到 $destination_dir 并删除代码目录 $destination_dir/$prog"
        salt $node cmd.run "cd $destination_dir && cp -f $prog/$package_name . && rm -rf $prog"
        echo "错误!退出当前脚本 …… "
        exit 7
    fi

    NOW=`date +"%Y/%m/%d %T"`
    echo "$NOW: $node 测试代码部署完成,程序服务启动成功,开始检查应用测试页 ... "
    check_Live

    if [[ ${curl_status} -eq 200 ]]
    then 
        echo "$node 后端 $prog 测试成功,接下来正式部署"
    else
        echo "$node 后端 $prog 测试失败,http 状态码 :${curl_status},请查看 ${destination_log_dir}/${logsprog} 日志文件!!!"
        echo -e "拷贝 $package_name 到 $destination_dir 并删除代码目录 $destination_dir/$prog"
        salt $node cmd.run "cd $destination_dir && cp -f $prog/$package_name . && rm -rf $prog"
        echo "错误!退出当前脚本 …… "
        exit 9
    fi
}

# 进行部署的函数
deploy_Distribute(){
    cat << EOF
------------------------------------------------------
|************ 开始部署开发环境后端 $prog ************|
------------------------------------------------------
EOF
    echo -e "开发环境后端 $prog 代码 $package_name 在 $source_dir 目录下."
    separator
    echo "$node 检测备份目录是否已存在 ... "
    chk_back_dir=$(salt $node file.directory_exists $back_dir --out=json|awk 'NR==2 {print $NF}')
    echo 检测备份目录 = $chk_back_dir
    if [[ $chk_back_dir == 'true' ]]
    then
        echo "$node '$back_dir' 备份目录已存在."
    elif [[ $chk_back_dir == 'false' ]]
    then
        echo "$node '$back_dir' 备份目录不存在,将新建代码备份目录 ... "
        salt $node file.mkdir $back_dir
    else
        echo "错误!现在退出脚本 …… "
        exit 3
    fi

    echo "$node 检测 $prog 程序服务是否为可用 ... "
    chk_java=$(salt $node service.available ${prog} --out=json|awk 'NR==2 {print $NF}')
    echo 检测java = $chk_java
    if [[ $chk_java == 'true' ]]
    then
        echo "$node $prog 服务可用并处于活跃状态,即将停止 $prog 服务 ... "
    else [[ $chk_java == 'false' ]]
        echo "$node $prog 服务不可用或不存在, 请检查 $prog 程序!"
        echo "错误!现在退出 …… "
        exit 4
    fi

    echo "开始停止 $prog 服务 ... "
    salt  $node service.stop ${prog}
    java_status=$(salt $node service.status $prog --out=json|awk 'NR==2 {print $NF}')
    echo java 服务状态 = $java_status
    if [[ $java_status == 'false' ]]
    then
        echo "$node $prog 服务停止成功."
    else [[ $java_status == 'true' ]]
        echo "$node $prog 服务停止失败!"
        echo "错误!现在退出脚本 …… "
        exit 5
    fi

    echo "$node 删除之前版本 '$destination_dir/$package_name' 文件 ... "
    salt $node file.remove $destination_dir/$package_name

    echo -e "当前将推送版本目录 '$source_dir'\n当前将推送版本文件 ' …… $source_file'\n目标目录 '$destination_dir'"
    echo -e "开始拷贝推送 $prog $package_name 到 $node ... "
    salt $node cp.get_file salt://$source_file $destination_dir/$package_name

    chk_copy=$(salt $node file.file_exists $destination_dir/$package_name --out=json|awk 'NR==2 {print $NF}')
    echo 验证推送文件 = $chk_copy
    if [[ $chk_copy == 'true' ]]
    then
        echo "推送 $prog $package_name 到 $node 成功."
    else [[ $chk_copy == 'false' ]]
        echo "拷贝 $prog $package_name 到 $node 失败!"
        echo "错误!现在退出脚本 …… "
        exit 6
    fi

    echo -e "$node 开始备份当前 $prog 代码 ... "
    salt $node cmd.run "cd $destination_dir && zip -rq ${back_prog}.${back_time}.zip ./$prog && mv -v $destination_dir/${back_prog}.${back_time}.zip $back_dir"

    echo -e "$node 开始部署 $prog 代码 ... "
    salt $node cmd.run "cd $destination_dir && rm -rf $prog/*"
    salt $node cmd.run "cp -v $destination_dir/$package_name $destination_dir/$prog && chown -R tomcat:root $destination_dir/$prog"

    echo "$node 代码部署完成,开始启动 $prog 服务 ... "
    salt $node service.start $prog
    java_status=$(salt $node service.status ${prog} --out=json|awk 'NR==2 {print $NF}')
    echo 服务状态 $java_status
    if [[ $java_status == 'true' ]]
    then
        echo "$node $prog 服务启动成功."
    else [[ $java_status == 'false' ]]
        echo "$node $prog 服务启动失败!"
        echo "错误!退出当前脚本 …… "
        exit 7
    fi

    NOW=`date +"%Y/%m/%d %T"`
    echo "$NOW: $node 代码部署完成,程序服务启动成功,开始检查应用测试页 ... "
    check_Live
    if [[ ${curl_status} -eq 200 ]]
    then 
        continue
    fi

    separator     

    echo "$node 后端 $prog 应用启动失败,http 状态码 :${curl_status},请查看 ${destination_log_dir}/${logsprog} 日志文件!!!"
    exit 9
}


# 总启动函数(判断项目目录是否存在)
# 根据判断项目目录判断是否第一次部署
main_Define(){
    for node in $group_list;
    do
        separator
        echo "$node 检测项目目录是否已存在 ... "
        chk_prog_dir=$(salt $node file.directory_exists $destination_dir/$prog --out=json|awk 'NR==2 {print $NF}')
        echo 检测代码目录 = $chk_prog_dir
        if [[ $chk_prog_dir == 'true' ]]
        then
            echo "$node '$destination_dir/$prog' 目录已存在,将进行部署步骤"
            deploy_Distribute                   # 部署
        elif [[ $chk_prog_dir == 'false' ]]
        then
            echo "$node '$destination_dir/$prog' 目录不存在,将先进行测试程序步骤 ... "
            deploy_PreTest                      # 测试
            echo "$node 将进行部署步骤"
            deploy_Distribute                   # 部署
            separator
        else
            echo "错误!现在退出脚本 …… "
            exit 2
        fi
    done
}

main_Define                                     # 总启动

separator
NOW=`date +"%Y/%m/%d %T"`
echo -e "$NOW: 后端 $prog 代码部署上线任务完成."
separator
 

你可能感兴趣的:(linux)