#!/usr/bin/python2.7#coding=utf-8'''Created on Oct 19@author wangyunhua@smeyun.com Update Version TO WanVersion 1.1'''import osimport timeimport MySQLdbimport jsonimport loggingimport paramikoimport traceback as tbfrom argparse import ArgumentParserl = logging.getLogger('web')#获取时间用于打包备份命名D_TIME = time.strftime('%Y%m%d%H%M')#作为结果输出logs = []#获取脚本当前目录cfd = os.path.dirname(os.path.abspath(__file__))SystemUpdatePath="/data/BusinesstoCustomer/program/"Version_Url='http://192.168.200.141:8557/webdir/'update_service = []Service_Names = []GROUPS_Names = []MYSQLHOST='127.0.0.1'MYSQLUSER='root'MYSQLPASSWD='Feng!1900'def Server_sql():conn = MySQLdb.connect(host=MYSQLHOST,user=MYSQLUSER,passwd=MYSQLPASSWD,db='ccdb')curs = conn.cursor()try:curs.execute('''select d.WebName,d.WD_path,e.webhosts,e.WI_path,e.Wsystem_class,f.muser,f.mpass,f.rpass from t_web_ID_name d,t_web_list e,t_password f where d.WebID = e.WebID and f.ip = e.webhosts and e.WL_status =1;''')conn.commit()data = curs.fetchall()#print u'fetchall()返回的数据:',dataconn.close()jsonData = []for row in data:result = {}result['WebName'] = str(row[0])result['WD_path'] = str(row[1])result['webhosts'] = row[2]result['WI_path'] = str(row[3])result['Wsystem_class'] = str(row[4])result['muser'] = str(row[5])result['mpass'] = str(row[6])result['rpass'] = str(row[7])jsonData.append(result)#l.debug('转换为列表字典的原始数据 : %r',jsonData)return json.dumps(jsonData)except:print 'MySQL connect fail...'else:#使用json.dumps将数据转换为json格式,json.dumps方法默认会输出成这种格式"u5377u76aeu6298u6263",加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['WebName'] == wname and aa['Wsystem_class'] == obi:service_object = services(aa['WebName'],aa['WD_path'],aa['webhosts'],aa['WI_path'],aa['Wsystem_class'],aa['muser'],aa['mpass'],aa['rpass'])update_service.append(service_object)def pack_info():#取出相关服务器信息和状态file_data=json.loads(Server_sql())for aa in file_data:service_name = aa['WebName']groups_name = aa['Wsystem_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 linereturn res.splitlines()#封装的自定义打印模块def head_print():print ' 33[1;31;40m'#print '*' * 50#print ' '#封装的自定义打印模块def tail_print():#print ' '#print '*' * 50print ' 33[0m'#输出操作结果def output_result():head_print()for count in range(len(logs)):print " "for content in logs[count]:if 'MD5校验成功!' in content:print contentbreakprint contenttail_print()class services:def __init__(self,WebName,WD_path,webhosts,WI_path,Wsystem_class,muser,mpass,rpass):self.WebName = WebNameself.WD_path = WD_pathself.WI_path = WI_pathself.webhosts = webhostsself.Wsystem_class = Wsystem_classself.muser = muserself.mpass = mpassself.rpass = rpassdef connect(self,cmd,allow_agent=False,look_for_keys=False):s=paramiko.SSHClient()s.load_system_host_keys()s.set_missing_host_key_policy(paramiko.AutoAddPolicy())s.connect(hostname=self.webhosts,port=22,username=self.muser, password=self.mpass)if self.muser != 'root':ssh = s.invoke_shell()time.sleep(0.1)ssh.send('su - ')buff = ''while not buff.endswith('Password: '):resp = ssh.recv(9999)buff +=respssh.send(self.rpass)ssh.send(' ')buff = ''while not buff.endswith('# '):resp = ssh.recv(9999)buff +=respssh.send(cmd)ssh.send(' ')buff = ''while not buff.endswith('# '):resp = ssh.recv(9999)buff +=resps.close()result = buffelse:stdin, stdout, stderr = s.exec_command(cmd)result = stdout.read()s.close()print resultreturn resultdef execute(self,*cmd):stdin, stdout, stderr = self.client.exec_command(*cmd)print stdout.readlines()print stderr.readlines()def putFile(self,localPath,remotePath):ftp = self.client.open_sftp()ftp.chmod(remotePath,777)if os.path.isdir(localPath):for f in os.listdir(localPath):remotefile = os.path.join(remotePath,f)localf = os.path.join(localPath,f)if os.path.isfile(localf):ftp.put(localf,remotefile)else:files = os.path.split(localPath)[-1]remotefile = os.path.join(remotePath,fles)ftp.put(localPath,'%s/'%remotefile)#关闭远端服务器tomcatdef test_remote(self):#关闭远端进程shl='''ifconfig eth0|grep inet'''l.debug('%r',shl)self.connect(cmd=shl)def ps_prcee(self):shl='''ps aux|grep nginx'''l.debug('%r',shl)self.connect(cmd=shl)def push_prcee(self):shl='''wget -NP %s %s'''%(self.WI_path,Version_Url+self.WebName+'/'+self.WebName+'.zip')l.debug('%r',shl)self.connect(cmd=shl)def backup_prcee(self):shl='''cd %s/backup;tar zcvf %s %s;cd ..;rm -rf *.zip'''%(self.WI_path,self.WebName+D_TIME+'.tar',self.WI_path+'/'+self.WebName)l.debug('%r',shl)self.connect(cmd=shl)def unzip_prcee(self):shl='''cd %s;unzip -o %s.zip'''%(self.WI_path,self.WebName)l.debug('%r',shl)self.connect(cmd=shl)#检测参数,执行操作def handle(args):logging.basicConfig(format="%(message)s")l.level = logging.INFOif args.verbose:l.level =logging.DEBUGop = args.operationob = args.objectwebnames = args.webnamess = servicesif 'all' in webnames:pack_info()Service_Names.remove('all')webname = set(Service_Names)pack(ob,webname)else:pack(ob,webnames)if op == 'test':for content in update_service:ss.test_remote(content)if op == 'cupdate':for content in update_service:ss.backup_prcee(content)for content in update_service:ss.push_prcee(content)for content in update_service:ss.unzip_prcee(content)for content in update_service:ss.ps_prcee(content)if op == 'backup':for content in update_service:ss.backup_prcee(content)if op == 'ps':for content in update_service:ss.ps_prcee(content)if op == 'push':for content in update_service:ss.push_prcee(content)if op == 'unzip':for content in update_service:ss.unzip_prcee(content)#检测输入,def main():pack_info()ACTIONS = ['test','ps','push','cupdate','backup','unzip']webname = set(Service_Names)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='+',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()