基于sh脚本对项目进行一键部署

在(https://blog.csdn.net/fwhezfwhez/article/details/80841578)中,谈到了每当有新的项目,都需要进行如下命令:
交叉编译:
GOOS=linux GOARCH=amd64 go build -o helloworld
上传文件
scp -P 22 helloworld [email protected]:/home/tonnn/projects/helloworld
登陆服务终端,配置supervisor文件并重启
vim /etc/supervisor/conf.d/helloworld.ini
内容为:

[program:helloworld]
directory = /home/tonnn/projects/helloworld
command = /home/tonnn/projects/helloworld/helloworld -port=:8088 
autostart = true
autorestart = true
redirect_stderr = true
stdout_logfile = /data/log/helloworld.log

vim /data/log/helloworld.log
内容:

[log for helloworld]

最后重载supervisor
supervisorctl reload

那么该如何把这一块重复性质的部署任务给一键处理呢,来进行第一级脚本的试写.

需求一:对helloworld项目一键更新
首先,我们假定项目已经成功部署过,现在需要进行更新和修改bug,重新发布。

把执行的语句依次写进bat或者sh文件里是最初的想法,解决的第一个问题就是:
本地跑交叉编译和上传命令,重启服务确是在服务端
通过百度,得知ssh的带命令登陆 ssh -tt [email protected] “命令1&&命令2&&命令3”
在开发端的项目路径下,新建
ex.sh
内容为:

GOOS=linux GOARCH=amd64 go build -o helloworld
scp -P 22 helloworld tonnn@xx.xx.xx.xx:/home/tonnn/projects/helloworld 
ssh -tt tonnn@xx.xx.xx.xx "sudo supervisorctl restart helloworld"

在该路径下git bash here,并执行./ex.sh
执行结果:
重新交叉编译了helloworld,并上传至服务器的/home/tonnn/projects/helloworld ,并且使用supervisor重新启动该服务。
踩到的坑,就是,脚本文件须是.sh而不能是.bat,因为git执行的环境是模拟linux,使用.bat编辑脚本会有意想不到的bug,比如交叉编译失败。

需求二:对任意已经部署好的项目一键更新
通过百度,我们得知,sh中可以使用$1,$2,$3来进行内容置换,提取出来得到第二级脚本
basicDeploy.sh:

GOOS=linux GOARCH=amd64 go build -o $1
scp -P 22 $1 tonnn@10.0.2.122:/home/tonnn/projects/$1
ssh -tt tonnn@10.0.2.122 "sudo supervisorctl restart $1&&sudo supervisorctl restart productsrv

同样的方式执行./basicDeploy.sh helloworld
得到了如同第一级脚本相同的结果,并且,通过命令参数可以改成./basicDeploy.sh helloworld2之类的

需求三:对新开发好的项目一键部署
交叉编译和上传,重启supervisor都会了,对新项目来说,唯一不同的就是需要手动创建xxxx.ini和xxxx.log了,
百度后得知linux创建文件touch xxx.ini,touch xxx.log可以新建文件
echo ‘xxxxxxxxxx’ >> xxx.ini 可以把该内容追加的方式写进xxx.ini
echo ‘xxxxxxxx’ >xxx.ini 可以把内容覆盖的方式写进xxx.ini

写这段脚本遇到的坑有两个:首先是命令之间的回车可能会造成一些小小的错误,所以下面的脚本对齐缩进我也是小心谨慎地这样写完了,第二个是权限,因为登陆的tonnn拥有sudo权限,但本身不是root,所以所有命令前都要加sudo
最后得到如下脚本:
commonDeploy.sh

#交叉编译 $1表示编译结果的项目名称
GOOS=linux GOARCH=amd64 go build -o $1

#上传到指定路径下
scp -P 22 $1 tonnn@10.0.2.122:/home/tonnn/projects/$1

#远程登陆并依次执行命令
ssh -tt tonnn@10.0.2.122 "sudo touch /etc/supervisor/config.d/$1.ini&&
                          sudo chmod 777 /etc/supervisor/config.d/$1.ini&&
                          sudo echo '[program:$1]
directory = /home/tonnn/projects/$1
command = /home/tonnn/projects/$1/$1 -port=:8088 
autostart = true
autorestart = true
redirect_stderr = true
stdout_logfile = /data/log/$1.log'>/etc/supervisor/config.d/$1.ini&&
sudo touch /data/log/$1.log&&sudo chmod 777 /data/log/$1.log&&
sudo echo '[log for $1]' >/data/log/$1.log&&
sudo supervisorctl reload&&
sudo supervisorctl restart $1&&
sudo supervisorctl restart productsrv"

下面来研究一下需求四
需求四.如果xx.ini和xx.log已存在并且有内容,则echo不执行任何操作,并且将脚本的架构方式,从ssh xxxxx “command1&&command2…”改造成脚本内容写在服务端->commonDeploy.sh,然后ssh只需要带上该脚本命令:ssh [email protected] “./data/script/commonDeploy.sh”
晚点更新上来

百度了一下shell的if语法,了解到使用if [ -f “/x/x/x/x/” ] 可以判断某文件是否存在
于是很快地写完了服务端的脚本代码
首先,
vim /data/script/deploy.sh
内容:

#!/bin/sh

if [ -f "/etc/supervisor/config.d/$1.ini" ];then
echo "file "$1".ini exist \n"
else
sudo touch /etc/supervisor/config.d/$1.ini
sudo chmod 777 /etc/supervisor/config.d/$1.ini
sudo echo "[program:"$1"]
directory = /home/tonnn/projects/"$1"
command = /home/tonnn/projects/"$1"/"$1" -port=:8088
autostart = true
autorestart = true
redirect_stderr = true
stdout_logfile = /data/log/"$1".log">/etc/supervisor/config.d/$1.ini
echo "success echo in $1.ini"
fi
if [ -f "/data/log/$1.log" ];then
echo "file "$1".log exist \n"
else
sudo touch /data/log/$1.log
sudo chmod 777 /data/log/$1.log
sudo echo "[log for "$1"]" >/data/log/$1.log
echo "success echo in $1.log"
fi
sudo supervisorctl reload
sudo supervisorctl restart $1

编写本段脚本有两个坑,首先if [ -f “xxx/xx/xx” ]这个中括号里一共有3个空格,少了报错,其次,echo命令还是要规范的使用双引号了,不能再使用单引号,因为使用单引号无法适配占位符,通过脚本生成的文件内容,$1还是$1,不会适配到传的参数上面去

修改一下权限
sudo chmod 777 /data/script/deploy.sh
可以测试一下
cd /data/script/
./deploy.sh projectx
执行后,就会在/etc/supervisor/config.d/下生成projectx.ini

 [program:projectx]
directory = /home/tonnn/projects/projectx
command = /home/tonnn/projects/"$1"/projectx -port=:8088
autostart = true
autorestart = true
redirect_stderr = true
stdout_logfile = /data/log/projectx.log

以及/data/log/projectx.log
这里写图片描述

之所以会报no such file,是因为这个file是go交叉编译之后的呢个程序包,而在服务端仅仅是测试能不能通过这个脚本生成正确的文件。结果是正常的

最后,我们把之前windows开发环境下的脚本稍微那么修改一丢丢:
假设你已经准备好了go程序,之前是helloworld,现在是projectx
那么在该工程路径下,新建deploy.sh

#交叉编译 $1表示编译结果的项目名称
GOOS=linux GOARCH=amd64 go build -o $1

#上传到指定路径下
scp -P 22 $1 tonnn@10.0.2.122:/home/tonnn/projects/$1

# 执行服务端上的脚本
ssh -tt tonnn@10.0.2.122 "cd /data/script/&&sudo ./deploy.sh $1"

继续在该路径上,git bash here ,执行 ./deploy.sh helloworld 或者./deply.sh projectx,总之你的项目是什么,就写什么,服务器上就自动部署好了!
是不是比前面的一大堆脚本写一起,清新多了呢~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

需求五 对开发好的服务,一键部署A,B,测试,三项,A,B表示版本迭代的前代和后代,测试表示测试服

猜你喜欢

转载自blog.csdn.net/fwhezfwhez/article/details/80857017