centos7環境下jenkins實現golang編譯及發布
一.jenkins構建execute shell執行腳本
#!/bin/bash # 此腳本功能為根據構建時選擇的參數,同步 /data/www/vhosts/services/fic_server_http_gate/ 下的文件同步到遠程中轉機器 # 2021.01.11 初始化腳本 ## 1.定義變量 dir_name=bak.$(date +%Y-%m-%d-%H-%M-%S) project_dir=/data/www/vhosts/services/fic-server-http-gate ## 2.備份代碼函數 function func_project_backup(){ cp -a $project_dir/ /data/data_backup/services/fic_server_http_gate_$dir_name } func_project_backup ## 3.判斷代碼發布目錄變量是否為空 if [ ! $project_dir ];then echo "$project_dir IS NULL ,shell exit!!!!" exit 1 fi ## 2.判斷同步狀態 function func_rsync_status(){ if [[ $? == 0 || $? == 23 ]];then rsync_edit=1 else rsync_edit=0 echo "`date` 同步到本地目標失敗! " exit 1 fi } function func_node_build(){ source /etc/profile ## 注入golang相關的環境變量 source /etc/go/go.env source /etc/go/gitlab.env echo ${JOB_NAME} cd ${WORKSPACE} || exit 1 ## 判斷是回退還是發布 if [ ${Action} = "Rollback" ]; then if [ ! -n "${Version}" ]; then echo "請填入回退版本的commitId" exit 1 fi echo "開始回退..." git reset --hard ${Version} fi ## 將當前user的home目錄注入環境變量, 並將拉取私有庫依賴的相關配置寫入git的配置文件中 export HOME=/root source /etc/go/gitconfig echo "刪除 fic-http-gate 中..." rm -rf ./bin/fic-http-gate #移除之前打包的可執行文件 echo "編譯 fic-http-gate 中..." go build -o ./bin/fic-http-gate ./main.go ## 刪除git配置 source /etc/go/gitconfig.unset } func_node_build ## 4.同步到本地待發路徑 function func_rsync_project_local(){ echo "xxxxxxxxxxxxxx同步待發目錄開始xxxxxxxxxxxxxxxxxx" #同步目標代碼到jenkins中間服務器 echo "start rsync fic_server_http_gate" cd $WORKSPACE/ #同步結果到jenkins本機的發布目錄 /usr/bin/rsync -avu -progress --delete --exclude='.git' --exclude='.gitignore' --exclude='*.log' --exclude="*.map" $WORKSPACE/bin/fic-http-gate $project_dir/ /usr/bin/rsync -avu -progress --delete --exclude='.git' --exclude='.gitignore' --exclude='*.log' --exclude="*.map" $WORKSPACE/conf $project_dir/ /usr/bin/rsync -avu -progress --delete --exclude='.git' --exclude='.gitignore' --exclude='*.log' --exclude="*.map" $WORKSPACE/multienv $project_dir/ /usr/bin/rsync -avu -progress --delete --exclude='.git' --exclude='.gitignore' --exclude='*.log' --exclude="*.map" $WORKSPACE/script/cpconfig.sh $project_dir/ echo "end rsync fic_server_http_gate" func_rsync_status echo "xxxxxxxxxxxxxx同步待發目錄完成xxxxxxxxxxxxxxxxxx" } func_rsync_project_local ## 5.推送代碼到遠程中轉機並發布(發布到線上) echo "------------------------------------ rsync start prod -----------------------------------------" chown -R apache.users $project_dir/ sleep 1 /bin/bash /usr/local/worksh/jeninks_task/yt_rsync_pixso_fic_server_http_gate.sh echo "------------------------------------ rsync done prod -----------------------------------------" ## 7.通過插件執行遠程中轉機上的同步腳本
二.jenkins服務器的配置
# 環境變量 /etc/profile
#for jdk export JAVA_HOME=/usr/local/jdk1.8.0_161 export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar export PATH=$JAVA_HOME/bin:$PATH #MAVEN_HOME export MAVEN_HOME=/opt/maven/apache-maven-3.6.3 export PATH=${MAVEN_HOME}/bin:$PATH export PATH=$PATH:/root/node-v12.16.3/bin #emsdk export PATH=$PATH:/usr/local/emsdk export PATH=$PATH:/usr/local/emsdk/node/12.18.1_64bit/bin export PATH=$PATH:/usr/local/emsdk/upstream/emscripten PATH=/sbin:/bin:/usr/sbin:/usr/bin:/bin:/bin:/bin:/bin:/bin:/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin #go GOROOT=/usr/local/go GOPATH=/usr/local/gopath export PATH=$PATH:$GOROOT/bin:$GOPATH/bin export PATH=$PATH:/usr/local/allure-2.13.6/bin
# golang環境變量
# cat /etc/go/go.env export GO111MODULE="on" export GOARCH="amd64" export GOBIN="" export GOCACHE="/root/.cache/go-build" export GOENV="/root/.config/go/env" export GOEXE="" export GOFLAGS="" export GOHOSTARCH="amd64" export GOHOSTOS="linux" export GOINSECURE="" export GONOPROXY="" export GONOSUMDB="" export GOOS="linux" export GOPATH="/usr/local/gopath" export GOPRIVATE="" export GOPROXY="https://goproxy.cn,https://gocenter.io,https://goproxy.io,direct" export GOROOT="/usr/local/go" export GOSUMDB="off" export GOTMPDIR="" export GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64" export GCCGO="gccgo" export AR="ar" export CC="gcc" export CXX="g++" export CGO_ENABLED="1" export GOMOD="/dev/null" export CGO_CFLAGS="-g -O2" export CGO_CPPFLAGS="" export CGO_CXXFLAGS="-g -O2" export CGO_FFLAGS="-g -O2" export CGO_LDFLAGS="-g -O2" export PKG_CONFIG="pkg-config" export GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build932372373=/tmp/go-build -gno-record-gcc-switches"
# git配置
# cat /etc/go/gitlab.env
export GO111MODULE=on export GOPRIVATE=*.10086.cn/*,*.chinasoft.cn/* export GOINSECURE=*.10086.cn,*.chinasoft.cn export GOPROXY=https://goproxy.cn,https://gocenter.io,https://goproxy.io,direct export CGO_ENABLED=0 # cat /etc/go/gitconfig git config --global url."git@git.10086.cn:".insteadOf "http://git.10086.cn/" git config --global url."git@git.chinasoft.cn:".insteadOf "http://git.chinasoft.cn/" git config --global url."git@ytgit.10086.cn:".insteadOf "http://ytgit.10086.cn/" git config --global url."git@ytgit.chinasoft.cn:".insteadOf "http://ytgit.chinasoft.cn/" # cat /etc/go/gitconfig.unset git config --global --remove-section url."git@git.10086.cn:" git config --global --remove-section url."git@git.chinasoft.cn:" git config --global --remove-section url."git@ytgit.10086.cn:" git config --global --remove-section url."git@ytgit.chinasoft.cn:"
三.發布到中間服務器腳本
# cat /usr/local/worksh/jeninks_task/yt_rsync_pixso_fic_server_http_gate.sh
#!/bin/bash ############################################# ## 設置變量和GET請求過來的變量 ## GET請求傳過來的文件所在目錄,目錄路徑寫全路徑了 #dir=$1 ## 設置目標服務器,即中間服務器IP,alisz_jenkins_publish01 ip='1.1.1.1' # 非apache用戶運行腳本,則退出 #if [ `whoami` != "apache" ];then #echo " only apache can run me" #exit 1 #fi # 判斷目錄是否為空函數 function func_is_empty_dir(){ return `ls -A $1|wc -w` } # 代碼發目錄 project_dir="/data/www/vhosts/services/" find /data/www/vhosts/services/ -name "cpconfig.sh"|xargs chmod +x # 判斷待發目錄是否為空,為空則退出 if func_is_empty_dir $project_dir then echo " $project_dir is empty , exit!!!!" exit 1 else echo " $project_dir 可以發布" fi passfile="/data/www/.rsync/pass.fic_server_http_gate.sz_publish" # 啟用 function rsync_fic_server_http_gate_edrawsoft_cn { /usr/local/bin/rsync -zavP --bwlimit=1000 --exclude='.git/' --exclude='.gitignore' --exclude='*.log' --exclude="./core/*" --exclude="./js/*" --exclude='*.map' --password-file=${passfile} /data/www/vhosts/services/fic-server-http-gate/ apache@$ip::apache_fic_server_http_gate if [[ $? == 0 || $? == 23 ]];then rsync_edit=1 else rsync_edit=0 echo "`date` fic_server_http_gate 發布到中間服務器 sz_publish 失敗" exit 1 fi } echo "-- start pub --- 預發布到外網 $ip ----------------" rsync_fic_server_http_gate_edrawsoft_cn echo -e "-- end pub 預發布到外網 $ip ---------\n\n" echo "####預發布到 sz_publish 完成####" exit 0
# 最終的go二進制運行結構
fic-server-http-gate/ ├── conf │ ├── logconf.xml │ └── settings.yml ├── cpconfig.sh ├── fic-http-gate └── multienv └── alisz └── conf ├── logconf.xml └── settings.yml
# 根據機房標識進行發布的腳本
# more cpconfig.sh
#!/bin/sh if [ $# -ne 2 ] then echo "Cpconfig fail! The reason for the failure is a missing parameter!" exit 1 fi Rootpath=$1 Env=$2 sourceDir=${Rootpath}/multienv/$Env targetDir=${Rootpath} echo "========= start apply confg ============" echo "yes | cp -fa ${sourceDir}/. ${targetDir}/" yes | cp -fa ${sourceDir}/. ${targetDir}/ if [ $? -ne 0 ] then echo "Cpconfig fail! The reason for the failure is copy config error!" exit 1 fi cd ${sourceDir} configfiles=$(find ./ -type f -print) for configfile in $configfiles do currentMd5=$(md5sum ${sourceDir}/$configfile | cut -d ' ' -f1) targetMd5=$(md5sum ${targetDir}/$configfile | cut -d ' ' -f1) echo $configfile echo $currentMd5 echo $targetMd5 if [ "$currentMd5" != "$targetMd5" ] then echo "Cpconfig fail! The reason for the failure is $configfile md5sum errro" exit 1 fi done echo "Config copy success!" echo "========== end apply config ================"
四.中間服務器推送到最終腳本
# cat /usr/local/worksh/jenkins_rsync/alisz_rsync_pixso_fic_server_http_gate.sh
#!/bin/bash # 腳本中最后一個管道命令返回非0 就退出 set -e # 腳本中管道命令返回非0 也退出 set -o pipefail # 腳本中變量存在空 就退出 set -u ########################################################################################### # jenkins拉取git代碼同步到 代碼中轉機 上 然后觸發 代碼中轉機 上的該腳本進行 目標 機房的同步# # 1.2020.07.17初始化模板 # 2.修改版本記錄 ########################################################################################### ## 腳本中最后一個管道命令返回非0 就退出 set -e ## 腳本中管道命令返回非0 也退出 set -o pipefail ## 腳本中變量存在空 就退出 set -u ## 非apache用戶運行腳本,則退出 if [ `whoami` != "apache" ];then echo " only apache user can run me" exit 1 fi src_path="/data/www/vhosts/services/fic-server-http-gate" config_script=${src_path}/cpconfig.sh # cp multiconfig to alisz function cp_config_alisz() { ${config_script} ${src_path} alisz } ## 密碼以及排除文件 passwd="/data/www/.rsync/rsyncd.pixso_core_server" exclude_list="--exclude=.svn --exclude=.git --exclude=.gitignore --exclude=*.log --exclude='logs/' --exclude=.gitattributes --exclude="node_modules"" ## cn all yt_cn_ip_list_all="1.1.1.1 1.1.1.2" yt_ip_list_cn_web01="1.1.1.1" yt_ip_list_cn_web02="1.1.1.2" ## src directory 源 src_directory="services/fic-server-http-gate" ## dst directory 暫不需要 dst_directory="services/fic-server-http-gate" ## 時間變量 Date=$(date +'%Y%m%d%H%M%S') DATE_Y=$(date +'%Y') DATE_M=$(date +'%m') DATE_D=$(date +'%d') ## 日志目錄 pubMsgDir=/data/www/logs/rsync_log/$DATE_Y/$DATE_M/$DATE_D pubMsgFile=${pubMsgDir}/${Date}.log src_path="/data/www/vhosts/services/fic-server-http-gate" config_script=${src_path}/cpconfig.sh # cp multiconfig to alisz function cp_config_alisz() { ${config_script} ${src_path} alisz } if [ ! -d ${pubMsgDir} ];then mkdir -p ${pubMsgDir} fi ## code同步狀態 function func_rsync_status() { if [[ $? == 0 || $? == 23 ]];then rsync_edit=1 else rsync_edit=0 echo "`date` 同步到目標失敗! " | tee -a ${pubMsgFile} exit 1 fi } ## 同步所有機房,目前只有AWS一個機房 function rsync_yt_cn_all() { cp_config_alisz for ip in ${yt_cn_ip_list_all} do echo "#################### Run rsync ${ip} start ################################" | tee -a ${pubMsgFile} rsync -zavP --delete $exclude_list --password-file=$passwd /data/www/vhosts/${src_directory}/ apache@${ip}::apache/data/www/vhosts/${dst_directory}/ | tee -a ${pubMsgFile} func_rsync_status echo "################### Run rsync ${ip} end #######################" | tee -a ${pubMsgFile} done } ## 同步AWS機房的第1台web機器 function rsync_yt_cn_web1() { cp_config_alisz for ip in ${yt_ip_list_cn_web01} do echo "#################### Run rsync ${ip} start ################################" | tee -a ${pubMsgFile} rsync -zavP --delete $exclude_list --password-file=$passwd /data/www/vhosts/${src_directory}/ apache@${ip}::apache/data/www/vhosts/${dst_directory}/ | tee -a ${pubMsgFile} func_rsync_status echo "################### Run rsync ${ip} end #######################" | tee -a ${pubMsgFile} done } ## 同步AWS機房的第2台web機器 function rsync_yt_cn_web2() { cp_config_alisz for ip in ${yt_ip_list_cn_web02} do echo "#################### Run rsync ${ip} start ################################" | tee -a ${pubMsgFile} rsync -zavP --delete $exclude_list --password-file=$passwd /data/www/vhosts/${src_directory}/ apache@${ip}::apache/data/www/vhosts/${dst_directory}/ | tee -a ${pubMsgFile} func_rsync_status echo "################### Run rsync ${ip} end #######################" | tee -a ${pubMsgFile} done } ##################### MAIN ############################### usage () { echo "" echo " Please Input server infomation!" echo "" echo " USAGE: `basename $0` [all|yt_cn_web1|yt_cn_web2]" echo "" } if [ $# != 1 ] then usage >&2 exit 1 fi OPT=$1 case $OPT in all) echo "start rsync `basename $0` to all servers" rsync_yt_cn_all ;; yt_cn_web1) echo "start rsync `basename $0` to yt_cn_web1 servers" rsync_yt_cn_web1 ;; yt_cn_web2) echo "start rsync `basename $0` to yt_cn_web2 servers" rsync_yt_cn_web2 ;; *) echo "Usage:`basename $0` [all|yt_cn_web1|yt_cn_web2]" ;; esac