fab是一個python庫,強大好使,可以做很多幫助你減輕工作量的事情,比如在多台服務器上部署web項目,這里就講講使用它簡單的方法來執行部署的過程。
關於fab的安裝的基本使用,網上一搜一大把,內容都差不多,所以這里就不介紹,下載去官網:http://www.fabfile.org/
本文會涉及到以下幾個內容:
- 自動SSH登錄
- 運行命令
- 錯誤處理
- 帶顏色輸出
自動ssh登錄
一般自動部署都不會只有一台機器,所以這里主要說多台機器,當然,一台也是一樣的
首先,導入庫
1 from fabric.api import *
fabric.api里封裝了很多的方法,用來做一般的事情,兩個方法就夠了
1. run() 用於執行命令 2. cd() 用於進入目錄
跑題了,基本操作用這兩個就可以了,具體操作后面再講,回到ssh登錄上,我們知道,登錄3要素,用戶,地址和密碼,所以先就定義一下。當然,不能隨便定義,得按fab的方法來
1 # 定義host 2 # 方法 env.hosts = ['user@host1', 'user@host2'] 3 # 示例 4 env.hosts = ['onlyfu@unjs.dinlei.com', 'root@unjs.dinlei.com'] 5 6 # 設置密碼 7 # 方法 env.passwords = {'host1:22': 'password1', 'host2:22': 'password2'} 8 # 示例 9 env.passwords = {'onlyfu@unjs.dinlei.com:22': '1234565', 'root@unjs.dinlei.com': 'ojoajewpb'}
這里要特別說明一下,在passwords里host一定要帶上端口,默認端口本身來講是不用帶的,但在這里,如果要讓密碼跟host對上,就必須帶着端口號才能成功。
env.passwords用於服務器的密碼不一至的情況,如果幾台服務器的密碼都是相同的,可以直接使用env.password = '123456'
運行命令
正如前面所說,主要命令是run,它可以執行命令,如
1 # 執行單條命令 2 run("ls -l") 3 run("echo 'hello'") 4 5 # 執行多條命令 6 run("ls -l; echo 'hello'") 7 8 # 帶變量的也一樣,看看kill tomcat進程的命令 9 # 獲取到pid,然后執行kill命令,就這么簡單 10 run("pid=`(ps -ef | grep tomcat | grep -v \"grep\") | awk '{print $2}'`; kill -9 $pid")
再來說說cd命令,可能有人會說,既然run可以運行命令,那直接run("cd deploy")不就可以了嘛。事實證明,看上去對的,不一定真對,這個命令沒錯,是執行了,但它沒進去,真的,很假,等於是告訴你:哥,我進去了哦,但沒動,所以后面要做的操作,還是在當前目錄下的,不信可以試
1 run('cd deploy') 2 run('ls -l')
看輸出的目錄是哪兒就明白了。不過雖然沒進去,但如果執行run('cd deploy')時,沒有deploy這個目錄,程序是會報錯的,有病,是不是。那要怎么做呢,這里就到cd方法出場了,不過光是它也不行,還要和with一起用:
1 with cd('deploy'): 2 run('ls -l')
看看輸出,是不是已經到deploy目錄了,這樣就可以執行艇作用於該目錄的命令了
錯誤的處理
標准Python程序,出錯程序就停止結束了,很多時間,也許並不想讓它就此結束,想讓它跳過繼續執行后面的,那這里就要用到fab的錯誤處理方法了
使用錯誤處理,首先得告訴fab,我要進行這樣的處理,它才會去處理,所以先得說一下:
1 with settings(warn_only = true): 2 pass
warn_only = true就是在告訴fab這個事情,有了這一句,后面的語句都能享受到。
再說一個,run的每一條命令都有返回,成功或失敗,判斷,如果失敗,執行confirm方法,來提示確認要不要繼續,如:
1 # 導入confirm 2 from fabric.contrib.console import confirm 3 4 res = run('cd deploy') # 沒有deploy這個目錄 5 if res.failed and not confirm("cd deploy failed, Continue?"): 6 abort('Abort')
運行上面的程序,res就會得到返回,這時候用res.failed來判斷是否失敗,如果失敗,執行comfirm等待確認,如果選擇N,執行abort終止程序
帶顏色輸出
這個其沒什么用,只是想讓輸出漂亮一點,所以就說一下,方法很簡單,使用colors包
1 # 導入包 2 from fabric.colors import * 3 4 print green('green txt') 5 print red('red txt') 6 print yellow('yellow txt')
太簡單了
看一個完整一點的示例
應用場景: 共有4台服務器,要做Java Spring項目部署,服務器使用的tomcat 1. 登錄第一台服務器 2. 進入jar包的目錄 3. 使用git拉取新的jar包 4. 停止tomcat 5. 刪除web目錄,有可能多個 6. 將jar包拷到服務目錄中,有可能性於多個不同的目錄 7. 啟動tomcat 登錄下一台服務器循環
# -*- coding:utf-8 -*- from fabric.api import * from fabric.contrib.console import confirm from fabric.colors import * env.hosts = ['host1', 'host2', 'host3', 'host4'] env.passwords = {'host1:22': 'password1', 'host2:22': 'password2', 'host3:22': 'password3', 'host4:22': 'password4'} def getRedMessage(txt, t): return "[%s] faield, Continue?" % txt if t == 'msg' else "Aborting at [%s]" % txt def gitPull(): actionName = "get pull" res = run('git pull origin master') if res.failed and not confirm(getRedMessage(actionName, 'msg')): abort(getRedMessage(actionName, 'abort')) def copyFile(): actionName = "copy file" res = run('cp -rf jar/* /jardir/; cp -rf war/* /warjar/') if res.failed and not confirm(getRedMessage(actionName, 'msg')): abort(getRedMessage(actionName, 'abort')) def delWeb(): actionName = "delete web" res = run('rm -rf /webapps/*') if res.failed and not confirm(getRedMessage(actionName, 'msg')): abort(getRedMessage(actionName, 'abort')) def stopTomcat(): actionName = "stop tomcat" res = run("pid=`(ps -ef | grep tomcat | grep -v \"grep\") | awk '{print $2}'`; kill -9 $pid") if res.failed and not confirm(getRedMessage(actionName, 'msg')): abort(getRedMessage(actionName, 'abort')) def startTomcat(): action = "start tomcat" res = run("set -m; /sh/start.sh") # 啟動另外的程序,需加上set -m;因為如果不加,啟動會隨着python進程的結束而結束,達不到啟動的目的。關於set -m,可以去查查資料 if res.failed and not confirm(getRedMessage(actionName, 'msg')): abort(getRedMessage(actionName, 'abort')) def doploy(): with settings(warn_only = true): with cd('cd deploy'): res = run('ls -l') if res.failed and not confirm(getRedMessage('cd deploy', 'msg')): abort(getRedMessage('cd deploy', 'abort')) gitPull() stopTomcat() delWeb() copyFile() startTomcat()
將上面的代碼保存為fabfile.py文件,只有這個文件名,fab默認才能找到它,不然就要使用參數-f來加載文件名,在終端里運行:
fab deploy
好了,fab還有很多方法可以實現一些更加方便的操作,沒事可以翻翻Docs,http://docs.fabfile.org/en/latest/tutorial.html