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