简单分享下我们之前的采用的基于git的开发上线流程,以及所采用的的上线脚本。流程只简单说下,只能希望是抛砖引玉了;上线脚本是本文“重点”。之所以想分享这套脚本,因为个人感觉这套脚本提供了一种目录间“备份--更新/同步--回滚”的实现思路,对其中的细节稍作修改,应该可以适用到其他地方。
总结了两张图来说明基于git的开发流程和上线流程
下面一起来看上线脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
#!/bin/sh
###定义检查上一条命令是否执行成功的函数
function
check {
if
[ $? -
ne
0 ];
then
echo
-e
"\e[1;31m `date +%Y%m%d_%H:%M:%S` $1 exec failed,please check it ! \e[0m"
|
tee
-a
/root/shells/update_online/logs/www
.err
exit
-1
fi
}
ips=
"192.xxx.xx.x 192.xxx.xx.x 192.xxx.xx.x"
domain=www.xxx.com
###项目域名
app_base_dir=
/app
###线上server:项目所在目录,如$app_base_dir/$app_dir拼起来即为项目所在绝对路径/app/www
app_dir=www
###线上server:项目相对目录
local_dir=
/home/update/to_online/www
###本地server:该目录是从远程git库检出的master分支,即“随时可上线的代码”
bak_dir=
/update_bak
###线上server:备份目录
cat
<<update
+------------------------------------------+
+ A) 备份 +
+ B) 更新 +
+ C) 回滚 +
+ Q) 退出 +
+------------------------------------------+
update
read
-p
"请输入 (A|B|C|Q) ,再按ENTER键: "
INPUT
###备份
if
[ $INPUT =
"A"
];
then
for
ip
in
$ips
do
###在远程服务器备份,留三次的备份
echo
-e
"\e[1;33m\n-----------backup $ip $domain------------\e[0m"
ssh
$ip "
if
[ ! -z $bak_dir ] && [ ! -z $app_dir ];
then
\
mkdir
$bak_dir &>
/dev/null
;
cd
$bak_dir;
ls
-d $base_dir*|
sort
-r|
cat
-n |
awk
'\$1 > 2 {print \$NF}'
|
xargs
rm
-rf;
rsync
-a --delete $app_base_dir/$app_dir/ $bak_dir/$app_dir-`
date
+%Y%m%d_%H.%M`/ --exclude
'xxx'
--exclude
'xxx/xxx'
else
\
exit
-1;
fi
"
check
"backup $ip $domain"
;
echo
-e
"\e[1;32m\n------backup $ip $domain success--------\e[0m\n"
done
###更新
elif
[ $INPUT =
"B"
];
then
###拉取最新代码
echo
-e
"\e[1;33m\n---------------git pull--------------\e[0m"
cd
$local_dir
git pull
check
"git pull"
;
echo
-e
"\e[1;32m\n-----------git pull success------------\e[0m"
###执行更新操作
for
ip
in
$ips
do
echo
-e
"\e[1;33m----------update $ip $domain--------------\e[0m\n"
cd
$local_dir
if
[ ! -z $app_base_dir ] && [ ! -z $app_dir ];
then
###此处因有--delete参数,故而先判断目录变量是否存在
rsync
-avz --delete --exclude
".gitignore"
--exclude
".git"
./ $ip:$app_base_dir/$app_dir/
check
"rsync to $ip"
;
else
exit
-1
fi
echo
-e
"\e[1;32m\n--------update $ip $domain success----------\e[0m"
done
###回滚
elif
[ $INPUT =
"C"
];
then
for
ip
in
$ips
do
echo
-e
"\e[1;33m\n--------$ip $domain Start Rollback----------\e[0m"
###在远程获取备份目录的倒序排列,这里没有将命令集成到下面的远程命令代码块中是因为远程for i in `cat`操作需用单引号,进而无法使用awk,故而放到这里,多了一次ssh链接
ssh
$ip
"cd /update_bak && ls -d $base_dir*|sort -r|cat -n|awk '{print \"-\"\$1\",\"\$NF}' > /tmp/bak_dirs.txt"
ssh
$ip 'app_dir=www;
app_base_dir=
/app
;
app_dir=www;
bak_dir=
/update_bak
;
info_file=
/tmp/bak_dirs
.txt;
###以倒序排列记录备份目录的文件
unset
bak_arr &&
declare
-A bak_arr;
###定义以(-1,-2,-3)为key,以备份文件名称为value的关联数组
###下面的for循环用于给关联数组赋值
for
i
in
$(
cat
$info_file);
do
\
bak_arr[$(
echo
$i|
cut
-d
","
-f 1)]=$(
echo
$i|
cut
-d
","
-f 2);
done
;
echo
-e
"\e[1;33m\n There are ${#bak_arr[@]} old version \n\e[0m"
;
cat
$info_file|
sed
"s/,/) /"
;
###显示本台机器上旧版本倒序排列
echo
-e
"\e[1;33m\n Which one do you want to roolback ?\n Input one of \"-1, -2, -3\"\n \e[0m"
;
read
INPUT;
###下面对输入以及目录存在性做判断
if
[[ -z
"${bak_arr[$INPUT]}"
]];
then
\
echo
-e
"\e[1;31m Your input is wrong !\e[0m"
;
elif
[[ ! -d
"$bak_dir/${bak_arr[$INPUT]}"
]];
then
\
echo
-e
"\e[1;31m $bak_dir/${bak_arr[$INPUT]} not exist ! \e[0m"
;
else
\
###执行回滚操作
cd
$bak_dir/${bak_arr[$INPUT]};
rsync
-av --delete ./ $app_base_dir/$app_dir/ --exclude
"xxx"
--exclude
"xxx/xxx"
fi
'
check
"$ip rollback"
;
echo
-e
"\e[1;32m\n--------$ip $domain rollback success----------\e[0m"
done
elif
[ $INPUT =
"Q"
];
then
echo
-e
"\n -----bye bye-----"
exit
0
else
exit
1
fi
|
以下是使用截图
备份:
回滚:
本文转自kai404 51CTO博客,原文链接:http://blog.51cto.com/kaifly/1717650,如需转载请自行联系原作者