您好,登錄后才能下訂單哦!
本文小編為大家詳細介紹“如何用paramiko模塊寫發版機”,內容詳細,步驟清晰,細節處理妥當,希望這篇“如何用paramiko模塊寫發版機”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。
說明:為了安全,本文敏感信息如ip、用戶名密碼等做了轉換處理。
一、場景:每次發版時,都需要發版人一個一個文件的往生產機上拷貝,這樣不僅費時,而且容易出錯,降低工程師的工作積極性。
二、解決方法:需用python腳本寫一個發版機,自動發版。
三、腳本實現的功能:自動合并develop_svn(開發svn)代碼到online_svn(生產svn)下,自動備份遠程服務器代碼,手工通過ecplice編譯online_svn代碼,然后自動把編譯后的class文件根據filelist里面的路徑拷貝到生產機,并自動重啟服務器上的tomcat服務。
四、具體步驟:
1、開發提供類似如下svn文件列表:
filelist.txt里面的內容:
/trunk/src/ha/lalala/controller/BoardController.java
/trunk/src/ha/lalala/pda/PdaWaybillController.java
/trunk/WebRoot/jsp/productReview/list.jsp
2、建立develop_svn和online_svn目錄;
3、編寫faban.py腳本
點擊(此處)折疊或打開
#-*-coding:utf-8-*-
import Crypto #paramiko模塊依賴Crypto模塊
import paramiko #paramiko模塊是wnidows 遠程linux機器用的模塊
import os
import sys
import shutil #shutil模塊下有copy文件夾的方法
import time #這里使用其休眠函數sleep
import subprocess
import glob
#Update SVN
def UpdateSVN(path):
p = subprocess.Popen(['svn','update',path],shell=True,stdout=subprocess.PIPE)
print p.stdout.readlines()
#定義函數用來合并svn
def MergeSVN(develop_svn,online_svn):
with open('filelist.txt') as f:
for index,line in enumerate(f,1): #1表示索引值從1開始
line = line.replace('/trunk','') #替換路徑
line = line.replace('\n','') #把換行替換掉,\n是換行符的意思
develop_svn_path=develop_svn + line #拼接路徑
online_svn_path = online_svn + line #拼接路徑
print "%d copying: %s ---> %s" % (index,develop_svn_path,online_svn_path)
if not os.path.exists(os.path.dirname(online_svn_path)) : #如果目錄不存在,就建立一個目錄,注意exists方法返回的是布爾值,所以用Not進行否定
os.mkdir(os.path.dirname(online_svn_path)) #建立目錄
shutil.copy(develop_svn_path,online_svn_path) #將develop_svn_path里面的代碼拷貝到online_svn_path目錄下
print('\n') #輸出一個換行
print("合并SVN目錄已完成,請手工通過ecplice編譯代碼".decode('utf-8').encode('gb2312'))
print('\n') #輸出一個換行
#定義函數用來遠程備份代碼--給北京的機器備份
def BackupCode(hostname,port,username,password):
ssh = paramiko.SSHClient() #創建一個從客戶端連接服務器端的對象,也就是類的實例化
ssh.load_system_host_keys() #加載主機秘鑰
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #接受不在本地Known_host文件下的主機。否則ssh需要手工輸入一次yes
ssh.connect(hostname,port,username,password) #ssh連接
stdin,stdout,stderr = ssh.exec_command(get_pty=False,command='dir=$(date +%Y%m%d%H%M%S) && \
rsync -zrtopg --exclude geadPortrait/ \
--exclude=idcard/ --exclude=temp/ --exclude=upload \
--exclude=files --exclude=temporary_zip/ \
/opt/apache-tomcat-8.0.27/webapps/ROOT /backup/tms/$dir') #執行遠程機器的rsync命令進行備份,rsync命令沒加-v參數,所以正常信息不會輸出,只有報錯才輸出內容
result = stdout.read() #內容輸出
error = stderr.read() #錯誤輸出
print result
print error
#判斷是否有錯誤輸出,沒有就說備份成功,否則說備份失敗
if result.strip()=="" and error.strip()=="":
print "%s 完美,備份成功,備份位置在遠程機器的/backup目錄下".decode('utf-8').encode('gb2312') % hostname
print('\n')
else:
print "%s 不好了,備份失敗了".decode('utf-8').encode('gb2312') % hostname
print('\n')
ssh.close() #記得關閉paramiko的ssh連接
#定義函數用來遠程備份代碼--給香港騰訊的機器備份
def BackupCode_HK_QQ(hostname,port,username,password):
ssh = paramiko.SSHClient() #創建一個從客戶端連接服務器端的對象,也就是類的實例化
ssh.load_system_host_keys() #加載主機秘鑰
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #接受不在本地Known_host文件下的主機。否則ssh需要手工輸入一次yes
ssh.connect(hostname,port,username,password) #ssh連接
stdin,stdout,stderr = ssh.exec_command(get_pty=False,command='dir=$(date +%Y%m%d%H%M%S) && \
rsync -zrtopg --exclude geadPortrait/ \
--exclude=idcard/ --exclude=temp/ --exclude=upload \
--exclude=files --exclude=temporary_zip/ \
/opt/tomcat-9090-tms/webapps/ROOT /backup/tms/$dir') #執行遠程機器的rsync命令進行備份,rsync命令沒加-v參數,所以正常信息不會輸出,只有報錯才輸出內容
result = stdout.read() #內容輸出
error = stderr.read() #錯誤輸出
print result
print error
#判斷是否有錯誤輸出,沒有就說備份成功,否則說備份失敗
if result.strip()=="" and error.strip()=="":
print "%s 完美,備份成功,備份位置在遠程機器的/backup目錄下".decode('utf-8').encode('gb2312') % hostname
print('\n')
else:
print "%s 不好了,備份失敗了".decode('utf-8').encode('gb2312') % hostname
print('\n')
ssh.close() #記得關閉paramiko的ssh連接
#定義函數用來遠程執行發版動作
def Publish(hostname,port,username,password,local_base_path,remote_base_path):
count = 0
trans = paramiko.Transport(hostname,port) #建立paramiko的transport方式連接
trans.connect(username=username,password=password) #建立連接
sftp = paramiko.SFTPClient.from_transport(trans) #建立連接
with open('filelist.txt','r') as f:
for line in f:
#本地路徑預處理
localpath_filename = line.replace('/trunk/src','WebRoot/WEB-INF/classes')
localpath_filename = localpath_filename.replace('/trunk/WebRoot','WebRoot')
localpath_filename = localpath_filename.replace('.java','.class')
localpath_filename = localpath_filename.replace('\n','') #把換行替換掉
#構造真正的父類本地路徑
localpath_filename = local_base_path + localpath_filename
#構造真正的父類遠程路徑
remotepath_filename = remote_base_path + localpath_filename.replace('online_svn/WebRoot/','')
#拷貝父類到遠程機器上
print "%s is publishing: %s ---> %s " % (hostname,localpath_filename,remotepath_filename)
try:
sftp.listdir(os.path.dirname(remotepath_filename)) #加個錯誤處理,如果目錄不存在,就建立一個目錄
except IOError:
sftp.mkdir(os.path.dirname(remotepath_filename))
sftp.put(localpath_filename,remotepath_filename)
count += 1
print "***********第%s個文件發版成功***************" % count
#用glob模塊尋找子類
path_filename = os.path.split(localpath_filename) #split:返回一個二元組,包含文件的路徑與文件名
filename_splitext = os.path.splitext(path_filename[1]) #去掉文件擴展名
localpath_subclassfilenames = glob.glob('%s/%s$*' % (path_filename[0],filename_splitext[0]))
#把子類拷貝到遠程機器的目錄下
for localpath_subclassfilename in localpath_subclassfilenames:
localpath_subclassfilename = localpath_subclassfilename.replace('\\',r'/')
remotepath_subclassfilename = remote_base_path + localpath_subclassfilename.replace('online_svn/WebRoot/','')
print "%s is publishing: %s ---> %s " % (hostname,localpath_subclassfilename,remotepath_subclassfilename)
sftp.put(localpath_subclassfilename,remotepath_subclassfilename)
count += 1
print "***********第%s個文件拷貝成功,注意該文件是子類哦^_^ *****************************************" % count
print " %s機器發版完成!!!".decode('utf-8').encode('gb2312') % hostname
print('\n')
trans.close() #記得關閉paramiko的transport連接
#定義函數用來重啟服務
def RestartService(hostname,port,username,password):
ssh = paramiko.SSHClient() #創建一個從客戶端連接服務器端的對象,也就是類的實例化
ssh.load_system_host_keys() #加載主機秘鑰
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #接受不在本地Known_host文件下的主機。否則ssh需要手工輸入一次yes
ssh.connect(hostname,port,username,password) #ssh連接
stdin,stdout,stderr = ssh.exec_command(get_pty=False,command='/usr/local/shell/restartservice.sh')
result = stdout.read() #內容輸出
error = stderr.read() #錯誤輸出
print "%s 在重啟服務...".decode('utf-8').encode('gb2312') % hostname
print result
print error
print('\n')
ssh.close() #記得關閉paramiko的ssh連接
#主程序
if __name__ == '__main__':
#Update SVN
while True:
temp = str(raw_input('1) 請問你要Update SVN嗎?[yes/no]:'.decode('utf-8').encode('gb2312')))
tips = temp.strip().lower()
if tips == 'yes':
print "Now begin Update SVN..."
UpdateSVN('develop_svn')
break
elif tips == 'no':
break
#合并svn
while True:
temp = str(raw_input('2) 請問你要把開發svn合并到生產svn里面嗎?[yes/no]:'.decode('utf-8').encode('gb2312')))
tips = temp.strip().lower()
if tips == 'yes':
print "Now begin Merge SVN..."
MergeSVN('develop_svn','online_svn')
break
elif tips == 'no':
break
#備份遠程機器上的代碼
while True:
temp = str(raw_input('3)請問你要在發版前,備份一下遠程服務器上的代碼嗎?[yes/no]:'.decode('utf-8').encode('gb2312')))
tips = temp.strip().lower()
if tips == 'yes':
print "Now begin backup code..."
BackupCode(hostname = '10.2.88.2',port = '22',username = 'tms',password = 'xxx')
BackupCode(hostname = '10.2.88.3',port = '22',username = 'tms',password = 'xxx')
BackupCode(hostname = '10.2.88.13',port = '22',username = 'tms',password = 'xxx')
BackupCode(hostname = '10.2.88.14',port = '22',username = 'tms',password = 'xxx')
BackupCode_HK_QQ(hostname = '10.144.89.252',port = '22',username = 'tms',password = 'xxx')
break
elif tips == 'no':
break
#提示是否eclipse編譯代碼
while True:
temp = str(raw_input('4) 提示:請問你手工通過eclse編譯tms代碼了嗎[yes/no]:'))
tips = temp.strip().lower()
if tips == 'yes':
break
elif tips == 'no':
break
#預發版
while True:
temp = str(raw_input('5)請問你需要先單獨在預發版機器10.2.88.3上測試一下子發版嗎?[yes/no]:'.decode('utf-8').encode('gb2312')))
tips = temp.strip().lower()
if tips == 'yes':
print "Now begin publish code..."
Publish(hostname='10.2.88.3',port='22',username='tms',password='tmsOo798',local_base_path='online_svn/',remote_base_path='/opt/apache-tomcat-8.0.27/webapps/ROOT/')
print "Now begin restart service..."
RestartService(hostname = '10.2.88.3',port = '22',username = 'tms',password = 'tmsOo798')
break
elif tips == 'no':
break
#生產全發版
while True:
temp = str(raw_input('6)請問你要開始在所有正式服務器上進行發版嗎,包括10.2.88.13/14/2/3,10.144.89.252?[yes/no]:'.decode('utf-8').encode('gb2312')))
tips = temp.strip().lower()
if tips == 'yes':
print "Now begin publish code..."
Publish(hostname='10.2.88.13',port='22',username='tms',password='xxx',local_base_path='online_svn/',remote_base_path='/opt/apache-tomcat-8.0.27/webapps/ROOT/')
Publish(hostname='10.2.88.14',port='22',username='tms',password='xxx',local_base_path='online_svn/',remote_base_path='/opt/apache-tomcat-8.0.27/webapps/ROOT/')
Publish(hostname='10.2.88.2',port='22',username='tms',password='xxx',local_base_path='online_svn/',remote_base_path='/opt/apache-tomcat-8.0.27/webapps/ROOT/')
Publish(hostname='10.2.88.3',port='22',username='tms',password='xxx',local_base_path='online_svn/',remote_base_path='/opt/apache-tomcat-8.0.27/webapps/ROOT/')
Publish(hostname='10.144.89.252',port='22',username='tms',password='xxx',local_base_path='online_svn/',remote_base_path='/opt/tomcat-9090-tms/webapps/ROOT/')
break
elif tips == 'no':
break
#重啟服務
while True:
temp = str(raw_input('7)請問你要開始在所有正式服務器上重啟服務嗎,包括10.2.88.13/14/2/3,10.144.89.252?[yes/no]:'.decode('utf-8').encode('gb2312')))
tips = temp.strip().lower()
if tips == 'yes':
print "Now begin restart service..."
RestartService(hostname = '10.2.88.13',port = '22',username = 'tms',password = 'xxx')
print "please wait 60s..."
time.sleep(60)
RestartService(hostname = '10.2.88.14',port = '22',username = 'tms',password = 'xxx')
print "please wait 60s..."
time.sleep(60)
RestartService(hostname = '10.2.88.2',port = '22',username = 'tms',password = 'xxx')
print "please wait 60s..."
time.sleep(60)
RestartService(hostname = '10.2.88.3',port = '22',username = 'tms',password = 'xxx')
print "please wait 60s..."
time.sleep(60)
RestartService(hostname = '10.144.89.252',port = '22',username = 'tms',password = 'xxx')
break
elif tips == 'no':
break
#提示是否手工提交online_svn代碼
while True:
temp = str(raw_input('8) 提示:請問你手工提交online_svn代碼了嗎?[yes/no]:'))
tips = temp.strip().lower()
if tips == 'yes':
break
elif tips == 'no':
break
#退出本程時要說的話
print "\n"
print "*" * 50
print "親,您的完版完成,記得測試業務是否正常哦!!!"
print "*" * 50
sys.exit()
#加入下面這句話,才能用windows雙擊運行python腳本,否則雙擊腳本會一閃而過
raw_input()
讀到這里,這篇“如何用paramiko模塊寫發版機”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。