微服務釋出指令碼
阿新 • • 發佈:2020-07-17
#!/usr/bin/python2.7
#coding=utf-8
'''
Created on Oct 19
@author [email protected] Update Version TO Wan
Version 1.1
'''
import os
import time
import MySQLdb
import json
import logging
import paramiko
import traceback as tb
from argparse import ArgumentParser
l = logging.getLogger('online')
#獲取時間用於打包備份命名
D_TIME = time.strftime('%Y%m%d%H%M')
#作為結果輸出
logs = []
#獲取腳本當前目錄
cfd = os.path.dirname(os.path.abspath(__file__))
SystemUpdatePath="/data/BusinesstoCustomer/program/"
update_service = []
Service_Names = []
GROUPS_Names = []
result=[]
MYSQLHOST='127.0.0.1'
MYSQLUSER='root'
MYSQLPASSWD='Feng!1900'
Version_Url='http://192.168.200.141:8557/program/'
def Server_sql():
conn = MySQLdb.connect(host=MYSQLHOST,user=MYSQLUSER,passwd=MYSQLPASSWD,db='ccdb')
curs = conn.cursor()
try:
curs.execute('''select d.servername,d.SD_path,e.serverhosts,e.SI_path,g.Jenkins_name,e.SL_status,e.Ssystem_class,f.muser,f.mpass,f.rpass,f.wuser,f.muserkey from t_server_ID_name d,t_server_list e,t_password f,t_jenkins_server_list g where e.serverID = d.serverID and e.servername = g.servername and e.serverhosts = f.ip and e.SL_status =1;''')
conn.commit()
data = curs.fetchall()
#print u'fetchall()返回的資料:',data
conn.close()
jsonData = []
for row in data:
result = {}
result['servername'] = str(row[0])
result['SD_path'] = str(row[1])
result['serverhosts'] = row[2]
result['SI_path'] = str(row[3])
result['Jenkins_name'] = str(row[4])
result['SL_status'] = str(row[5])
result['Ssystem_class'] = str(row[6])
result['muser'] = str(row[7])
result['mpass'] = str(row[8])
result['rpass'] = str(row[9])
result['wuser'] = str(row[10])
result['muserkey'] = str(row[11])
jsonData.append(result)
#l.debug('轉換為列表字典的原始資料 : %r',jsonData)
return json.dumps(jsonData)
except:
print 'MySQL connect fail...'
else:
#使用json.dumps將資料轉換為json格式,json.dumps方法預設會輸出成這種格式"\u5377\u76ae\u6298\u6263",加ensure_ascii=False,則能夠防止中文亂碼。
#JSON採用完全獨立於語言的文字格式,事實上大部分現代計算機語言都以某種形式支援它們。這使得一種資料格式在同樣基於這些結構的程式語言之間交換成為可能。
#json.dumps()是將原始資料轉為json(其中單引號會變為雙引號),而json.loads()是將json轉為原始資料。
jsondatar=json.dumps(jsonData,ensure_ascii=False,sort_keys=True)
#去除首尾的中括號
return jsondatar[1:len(jsondatar)-1]
def pack(ob,webnames):
#取出相關伺服器資訊和狀態
file_data=json.loads(Server_sql())
for wname in webnames:
for aa in file_data:
for obi in ob:
if aa['servername'] == wname and aa['Ssystem_class'] == obi:
service_object = services(aa['servername'],aa['SD_path'],aa['serverhosts'],aa['SI_path'],aa['Jenkins_name'],
aa['SL_status'],aa['Ssystem_class'],aa['muser'],aa['mpass'],aa['rpass'],aa['wuser'],aa['muserkey'])
update_service.append(service_object)
def pack_info():
#取出相關伺服器資訊和狀態
file_data=json.loads(Server_sql())
for aa in file_data:
service_name = aa['servername']
groups_name = aa['Ssystem_class']
Service_Names.append(service_name)
Service_Names.append('all')
GROUPS_Names.append(str(groups_name))
GROUPS_Names.append('all')
def scall(CMD_LINE):
'''linux shell '''
l.debug('CMD_LINE : %r',CMD_LINE)
return call(CMD_LINE,shell=True)
def os_system(cmd):
result = os.popen(cmd)
res = result.read()
#for line in res.splitlines():
#print line
return res.splitlines()
#封裝的自定義列印模組
def head_print():
print '\033[1;31;40m'
#print '*' * 50
#print '\n'
#封裝的自定義列印模組
def tail_print():
#print '\n'
#print '*' * 50
print '\033[0m'
#輸出操作結果
def output_result():
head_print()
for count in range(len(logs)):
print "\n"
for content in logs[count]:
if 'MD5校驗成功!' in content:
print content
break
print content
tail_print()
class services:
def __init__(self,servername,SD_path,serverhosts,SI_path,Jenkins_name,SL_status,Ssystem_class,muser,mpass,rpass,wuser,muserkey):
self.servername = servername
self.SD_path = SD_path
self.SI_path = SI_path
self.serverhosts = serverhosts
self.Jenkins_name = Jenkins_name
self.SL_status = SL_status
self.Ssystem_class = Ssystem_class
self.muser = muser
self.mpass = mpass
self.rpass = rpass
self.wuser = wuser
self.muserkey = muserkey
self.LOG_PATH = '/data/logs'
self.SPRINT_PATH = '/tmp/'
def connect(self,cmd):
s=paramiko.SSHClient()
s.load_system_host_keys()
s.set_missing_host_key_policy(paramiko.AutoAddPolicy())
if 'pro' in self.Ssystem_class:
pkey = paramiko.RSAKey.from_private_key_file(self.muserkey)
s.connect(hostname=self.serverhosts,port=22,username=self.muser,pkey=pkey,allow_agent=False)
else:
s.connect(hostname=self.serverhosts,port=22,username=self.muser, password=self.mpass,allow_agent=False,look_for_keys=False)
if self.muser != 'root':
ssh = s.invoke_shell()
time.sleep(0.1)
ssh.send('su - \n')
buff = ''
while not buff.endswith('Password: '):
resp = ssh.recv(9999)
buff +=resp
ssh.send(self.rpass)
ssh.send('\n')
buff = ''
while not buff.endswith('# '):
resp = ssh.recv(9999)
buff +=resp
ssh.send(cmd)
ssh.send('\n')
buff = ''
while not buff.endswith('# '):
resp = ssh.recv(9999)
buff +=resp
s.close()
result = buff
else:
stdin, stdout, stderr = s.exec_command(cmd)
result = stdout.read()
s.close()
l.debug('result %r',result)
print self.serverhosts, cmd
return result
#關閉遠端伺服器tomcat
def test_remote(self):
#關閉遠端程序
shl='''ifconfig eth0|grep inet'''
l.debug('%r',shl)
self.connect(cmd=shl)
def stop_prcee(self):
shl='''pkill -f %(name)s'''%{'name':self.servername}
shl2='''ps aux|grep %(name)s|grep -v grep'''%{'name':self.servername}
l.debug('%r',shl)
l.debug('%r',shl2)
self.connect(cmd=shl)
self.connect(cmd=shl2)
def start_prcee(self):
'''su - user -c'''
if self.wuser == 'root':
shl='''/usr/bin/sh -l %(path)s/bin/start.sh '''%{'path':self.SI_path}
else:
shl='''runuser -l %(user)s -c "/usr/bin/sh -l %(path)s/bin/start.sh" '''%{'path':self.SI_path,'user':self.wuser}
#shl='''su -c %(user)s "/usr/bin/sh -l %(path)s/bin/start.sh" '''%{'path':self.SI_path,'user':self.wuser}
shl2='''ps aux|grep %(name)s|grep -v grep'''%{'name':self.servername}
l.debug('%r',shl)
l.debug('%r',shl2)
self.connect(cmd=shl)
self.connect(cmd=shl2)
def ps_prcee(self):
shl='''ps aux|grep %(name)s|grep -v grep'''%{'name':self.servername}
l.debug('%r',shl)
self.connect(cmd=shl)
def chown_set(self):
sh3 = '''chown -R %s %s''' %(self.wuser,self.SPRINT_PATH)
sh1 = '''chown -R %s %s''' %(self.wuser,self.SI_path)
sh2 = '''chown -R %s %s''' %(self.wuser,self.LOG_PATH)
self.connect(cmd=sh3)
self.connect(cmd=sh2)
self.connect(cmd=sh1)
def get_file(self):
shl='''wget -NP %s %s'''%(self.SI_path+'/lib/',Version_Url+self.servername+'/'+self.Jenkins_name)
l.debug('%r',shl)
self.connect(cmd=shl)
def get_md5(self):
shl1='''/usr/bin/md5sum %s |cut -d ' ' -f1'''%(self.SD_path +'/' +self.Jenkins_name)
local_md5 = os_system(shl1)[0]
l.debug('local_md5 %r',local_md5)
shl='''/usr/bin/md5sum %s |cut -d ' ' -f1'''%(self.SI_path +'/lib/'+self.Jenkins_name)
remote_md5 = self.connect(cmd=shl).split()[8]
l.debug('remote_md5 %r',remote_md5)
print self.Jenkins_name
print "本地檔案MD5",local_md5
print "遠端檔案MD5",remote_md5
return cmp(local_md5,remote_md5)
def back_file(self):
shl1="if [ ! -d %s/lib/backup/ ];then mkdir %s/lib/backup/;fi" %(self.SI_path,self.SI_path)
shl='''scp %s %s'''%(self.SI_path +'/lib/'+self.Jenkins_name,self.SI_path +'/lib/backup/'+self.Jenkins_name+'_%s'%D_TIME)
l.debug('%r',shl)
self.connect(cmd=shl1)
self.connect(cmd=shl)
#檢測引數,執行操作
def handle(args):
logging.basicConfig(format="%(message)s")
l.level = logging.INFO
if args.verbose:
l.level =logging.DEBUG
op = args.operation
ob = args.object
webnames = args.webname
ss = services
if 'all' in webnames:
pack_info()
Service_Names.remove('all')
webname = set(Service_Names)
pack(ob,webname)
else:
pack(ob,webnames)
if not op:
'''利用列表的方式實現swith功能'''
comlist = ['stop','scp','ps','start',]
else:
comlist = [op]
if op == 'test':
for content in update_service:
ss.test_remote(content)
if op == 'stop':
for content in update_service:
ss.stop_prcee(content)
if op == 'start':
for content in update_service:
if 'pro1' in ob or 'pro2' in ob:
print "許可權更新"
ss.chown_set(content)
ss.start_prcee(content)
if op == 'ps':
for content in update_service:
ss.ps_prcee(content)
if op == 'scp':
for content in update_service:
if ss.get_md5(content) != 0:
l.debug('開始拷貝檔案')
ss.back_file(content)
ss.get_file(content)
print "更新完成MD5檔案校驗"
ss.get_md5(content)
#if 'pro' in ob:
# print "許可權更新"
# ss.chown_set(content)
else:
l.debug('無需更新檔案')
if op == 'md5':
for content in update_service:
ss.get_md5(content)
#檢測輸入,
def main():
pack_info()
ACTIONS = ['test','stop','start','ps','scp','md5']
webname = set(Service_Names)
webname = list(webname)
webname.sort()
GROUPS = set(GROUPS_Names)
parser = ArgumentParser()
try:
parser.add_argument('-v','--verbose',action='store_true',help='detail output')
parser.add_argument('operation',choices=ACTIONS,help='action name')
parser.add_argument('-o','--object',nargs=1,choices=GROUPS,help='object name')
parser.add_argument('-w','--webname',nargs="+",choices=webname,help='update servername')
except:
print '%r'%tb.format_exc()
args = parser.parse_args()
handle(args)
output_result()
if __name__ == '__main__':
main()