天天看点

基于git的代码上线脚本一例

  简单分享下我们之前的采用的基于git的开发上线流程,以及所采用的的上线脚本。流程只简单说下,只能希望是抛砖引玉了;上线脚本是本文“重点”。之所以想分享这套脚本,因为个人感觉这套脚本提供了一种目录间“备份--更新/同步--回滚”的实现思路,对其中的细节稍作修改,应该可以适用到其他地方。

总结了两张图来说明基于git的开发流程和上线流程

<a href="http://s3.51cto.com/wyfs02/M01/76/B1/wKiom1ZZcfixzaTKAAClXbP22xI942.png" target="_blank"></a>

<a href="http://s4.51cto.com/wyfs02/M02/76/B1/wKiom1ZZcg3ysKPiAAEP-Kum-S4914.png" target="_blank"></a>

下面一起来看上线脚本  

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

<code>#!/bin/sh</code>

<code>###定义检查上一条命令是否执行成功的函数</code>

<code>function</code> <code>check {</code>

<code>    </code><code>if</code> <code>[ $? -</code><code>ne</code> <code>0 ];</code><code>then</code> 

<code>        </code><code>echo</code> <code>-e </code><code>"\e[1;31m `date +%Y%m%d_%H:%M:%S`  $1 exec failed,please check it ! \e[0m"</code><code>|</code><code>tee</code> <code>-a </code><code>/root/shells/update_online/logs/www</code><code>.err</code>

<code>        </code><code>exit</code> <code>-1</code>

<code>    </code><code>fi</code>

<code>}</code>

<code>ips=</code><code>"192.xxx.xx.x  192.xxx.xx.x  192.xxx.xx.x"</code>

<code>domain=www.xxx.com    </code><code>###项目域名</code>

<code>app_base_dir=</code><code>/app</code>    <code>###线上server:项目所在目录,如$app_base_dir/$app_dir拼起来即为项目所在绝对路径/app/www</code>

<code>app_dir=www    </code><code>###线上server:项目相对目录</code>

<code>local_dir=</code><code>/home/update/to_online/www</code>    <code>###本地server:该目录是从远程git库检出的master分支,即“随时可上线的代码”</code>

<code>bak_dir=</code><code>/update_bak</code>    <code>###线上server:备份目录</code>

<code>cat</code> <code>&lt;&lt;update</code>

<code>+------------------------------------------+</code>

<code>+                 A) 备份                  +</code>

<code>+                 B) 更新                  +</code>

<code>+                 C) 回滚                  +</code>

<code>+                 Q) 退出                  +</code>

<code>update</code>

<code>read</code> <code>-p </code><code>"请输入 (A|B|C|Q) ,再按ENTER键: "</code> <code>INPUT</code>

<code>###备份</code>

<code>if</code> <code>[ $INPUT = </code><code>"A"</code> <code>]; </code><code>then</code>

<code>    </code><code>for</code> <code>ip </code><code>in</code> <code>$ips</code>

<code>    </code><code>do</code>

<code>        </code><code>###在远程服务器备份,留三次的备份</code>

<code>        </code><code>echo</code> <code>-e </code><code>"\e[1;33m\n-----------backup  $ip $domain------------\e[0m"</code>

<code>        </code><code>ssh</code> <code>$ip "</code><code>if</code> <code>[ ! -z $bak_dir ] &amp;&amp; [ ! -z $app_dir ];</code><code>then</code><code>\</code>

<code>                     </code><code>mkdir</code> <code>$bak_dir &amp;&gt; </code><code>/dev/null</code><code>; </code><code>cd</code> <code>$bak_dir;</code>

<code>                     </code><code>ls</code> <code>-d $base_dir*|</code><code>sort</code> <code>-r|</code><code>cat</code> <code>-n |</code><code>awk</code> <code>'\$1 &gt; 2 {print \$NF}'</code><code>|</code><code>xargs</code> <code>rm</code> <code>-rf;</code>

<code>                     </code><code>rsync</code> <code>-a --delete $app_base_dir/$app_dir/ $bak_dir/$app_dir-`</code><code>date</code> <code>+%Y%m%d_%H.%M`/ --exclude </code><code>'xxx'</code> <code>--exclude </code><code>'xxx/xxx'</code>

<code>                 </code><code>else</code><code>\</code>

<code>                     </code><code>exit</code> <code>-1;</code>

<code>                 </code><code>fi</code><code>"               </code>

<code>        </code> 

<code>        </code><code>check </code><code>"backup $ip $domain"</code><code>;</code>

<code>        </code><code>echo</code> <code>-e </code><code>"\e[1;32m\n------backup $ip $domain success--------\e[0m\n"</code>

<code>    </code><code>done</code>

<code>###更新</code>

<code>elif</code> <code>[ $INPUT = </code><code>"B"</code> <code>]; </code><code>then</code>

<code>    </code><code>###拉取最新代码</code>

<code>    </code><code>echo</code> <code>-e </code><code>"\e[1;33m\n---------------git pull--------------\e[0m"</code>

<code>    </code><code>cd</code> <code>$local_dir </code>

<code>    </code><code>git pull</code>

<code>    </code><code>check </code><code>"git pull"</code><code>;</code>

<code>    </code><code>echo</code> <code>-e </code><code>"\e[1;32m\n-----------git pull success------------\e[0m"</code>

<code>    </code> 

<code>    </code><code>###执行更新操作</code>

<code>        </code><code>echo</code> <code>-e </code><code>"\e[1;33m----------update $ip $domain--------------\e[0m\n"</code>

<code>        </code><code>cd</code> <code>$local_dir</code>

<code>        </code><code>if</code> <code>[ ! -z $app_base_dir ] &amp;&amp; [ ! -z $app_dir ];</code><code>then</code>    <code>###此处因有--delete参数,故而先判断目录变量是否存在</code>

<code>            </code><code>rsync</code> <code>-avz --delete  --exclude </code><code>".gitignore"</code> <code>--exclude </code><code>".git"</code>  <code>./  $ip:$app_base_dir/$app_dir/</code>

<code>            </code><code>check </code><code>"rsync to $ip"</code><code>;</code>

<code>        </code><code>else</code>

<code>            </code><code>exit</code> <code>-1</code>

<code>        </code><code>fi</code>

<code>        </code><code>echo</code> <code>-e </code><code>"\e[1;32m\n--------update $ip $domain success----------\e[0m"</code>

<code>###回滚</code>

<code>elif</code> <code>[ $INPUT = </code><code>"C"</code> <code>]; </code><code>then</code>

<code>        </code><code>echo</code> <code>-e </code><code>"\e[1;33m\n--------$ip $domain Start Rollback----------\e[0m"</code>

<code>        </code><code>###在远程获取备份目录的倒序排列,这里没有将命令集成到下面的远程命令代码块中是因为远程for i in `cat`操作需用单引号,进而无法使用awk,故而放到这里,多了一次ssh链接</code>

<code>        </code><code>ssh</code> <code>$ip </code><code>"cd /update_bak &amp;&amp; ls -d $base_dir*|sort -r|cat -n|awk '{print \"-\"\$1\",\"\$NF}' &gt; /tmp/bak_dirs.txt"</code>

<code>                 </code> 

<code>        </code><code>ssh</code> <code>$ip 'app_dir=www;</code>

<code>        </code><code>app_base_dir=</code><code>/app</code><code>;</code>

<code>        </code><code>app_dir=www;</code>

<code>        </code><code>bak_dir=</code><code>/update_bak</code><code>;</code>

<code>        </code><code>info_file=</code><code>/tmp/bak_dirs</code><code>.txt;    </code><code>###以倒序排列记录备份目录的文件</code>

<code>                </code> 

<code>        </code><code>unset</code> <code>bak_arr &amp;&amp; </code><code>declare</code> <code>-A bak_arr;    </code><code>###定义以(-1,-2,-3)为key,以备份文件名称为value的关联数组</code>

<code>                           </code> 

<code>        </code><code>###下面的for循环用于给关联数组赋值</code>

<code>        </code><code>for</code> <code>i </code><code>in</code> <code>$(</code><code>cat</code> <code>$info_file);</code><code>do</code> <code>\</code>

<code>            </code><code>bak_arr[$(</code><code>echo</code> <code>$i|</code><code>cut</code> <code>-d </code><code>","</code> <code>-f 1)]=$(</code><code>echo</code> <code>$i|</code><code>cut</code> <code>-d </code><code>","</code> <code>-f 2);</code>

<code>        </code><code>done</code><code>;</code>

<code>        </code><code>echo</code> <code>-e </code><code>"\e[1;33m\n There are ${#bak_arr[@]} old version \n\e[0m"</code><code>;</code>

<code>        </code><code>cat</code> <code>$info_file|</code><code>sed</code> <code>"s/,/)  /"</code><code>;    </code><code>###显示本台机器上旧版本倒序排列</code>

<code>        </code><code>echo</code> <code>-e </code><code>"\e[1;33m\n Which one do you want to roolback ?\n Input one of \"-1, -2, -3\"\n \e[0m"</code><code>;</code>

<code>        </code><code>read</code> <code>INPUT;</code>

<code>        </code><code>###下面对输入以及目录存在性做判断</code>

<code>        </code><code>if</code> <code>[[ -z </code><code>"${bak_arr[$INPUT]}"</code> <code>]];</code><code>then</code> <code>\</code>

<code>            </code><code>echo</code> <code>-e </code><code>"\e[1;31m Your input is wrong !\e[0m"</code><code>;</code>

<code>        </code><code>elif</code> <code>[[ ! -d </code><code>"$bak_dir/${bak_arr[$INPUT]}"</code> <code>]];</code><code>then</code> <code>\</code>

<code>            </code><code>echo</code> <code>-e </code><code>"\e[1;31m  $bak_dir/${bak_arr[$INPUT]} not exist ! \e[0m"</code><code>;</code>

<code>        </code><code>else</code> <code>\</code>

<code>            </code><code>###执行回滚操作</code>

<code>            </code><code>cd</code> <code>$bak_dir/${bak_arr[$INPUT]};</code>

<code>            </code><code>rsync</code> <code>-av --delete ./  $app_base_dir/$app_dir/ --exclude </code><code>"xxx"</code> <code>--exclude </code><code>"xxx/xxx"</code>

<code>        </code><code>fi</code><code>'</code>

<code>        </code><code>check </code><code>"$ip rollback"</code><code>;</code>

<code>        </code><code>echo</code> <code>-e </code><code>"\e[1;32m\n--------$ip $domain rollback success----------\e[0m"</code>

<code>elif</code> <code>[ $INPUT = </code><code>"Q"</code> <code>]; </code><code>then</code> 

<code>    </code><code>echo</code> <code>-e </code><code>"\n -----bye bye-----"</code>

<code>    </code><code>exit</code> <code>0</code>

<code>else</code>

<code>    </code><code>exit</code> <code>1</code>

<code>fi</code>

以下是使用截图

备份:

<a href="http://s4.51cto.com/wyfs02/M02/89/0C/wKioL1gGPgyDampGAAE5CqwJal0744.png" target="_blank"></a>

更新:

<a href="http://s5.51cto.com/wyfs02/M00/76/B1/wKioL1ZZecKhM8ovAAFkugCC84A926.png" target="_blank"></a>

<a href="http://s1.51cto.com/wyfs02/M00/89/0C/wKioL1gGPg_wDzGYAAQhUT8Q5c8342.png" target="_blank"></a>

回滚:

     本文转自kai404 51CTO博客,原文链接:http://blog.51cto.com/kaifly/1717650,如需转载请自行联系原作者