1. #!/usr/bin/python2.7
  2. #coding=utf-8
  3. '''
  4. Created on Oct 19
  5. @author wangyunhua@smeyun.com Update Version TO Wan
  6. Version 1.1
  7. '''
  8. import os
  9. import time
  10. import MySQLdb
  11. import json
  12. import logging
  13. import paramiko
  14. import traceback as tb
  15. from argparse import ArgumentParser
  16. l = logging.getLogger('web')
  17. #获取时间用于打包备份命名
  18. D_TIME = time.strftime('%Y%m%d%H%M')
  19. #作为结果输出
  20. logs = []
  21. #获取脚本当前目录
  22. cfd = os.path.dirname(os.path.abspath(__file__))
  23. SystemUpdatePath="/data/BusinesstoCustomer/program/"
  24. Version_Url='http://192.168.200.141:8557/webdir/'
  25. update_service = []
  26. Service_Names = []
  27. GROUPS_Names = []
  28. MYSQLHOST='127.0.0.1'
  29. MYSQLUSER='root'
  30. MYSQLPASSWD='Feng!1900'
  31. def Server_sql():
  32. conn = MySQLdb.connect(host=MYSQLHOST,user=MYSQLUSER,passwd=MYSQLPASSWD,db='ccdb')
  33. curs = conn.cursor()
  34. try:
  35. 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;''')
  36. conn.commit()
  37. data = curs.fetchall()
  38. #print u'fetchall()返回的数据:',data
  39. conn.close()
  40. jsonData = []
  41. for row in data:
  42. result = {}
  43. result['WebName'] = str(row[0])
  44. result['WD_path'] = str(row[1])
  45. result['webhosts'] = row[2]
  46. result['WI_path'] = str(row[3])
  47. result['Wsystem_class'] = str(row[4])
  48. result['muser'] = str(row[5])
  49. result['mpass'] = str(row[6])
  50. result['rpass'] = str(row[7])
  51. jsonData.append(result)
  52. #l.debug('转换为列表字典的原始数据 : %r',jsonData)
  53. return json.dumps(jsonData)
  54. except:
  55. print 'MySQL connect fail...'
  56. else:
  57. #使用json.dumps将数据转换为json格式,json.dumps方法默认会输出成这种格式"\u5377\u76ae\u6298\u6263",加ensure_ascii=False,则能够防止中文乱码。
  58. #JSON采用完全独立于语言的文本格式,事实上大部分现代计算机语言都以某种形式支持它们。这使得一种数据格式在同样基于这些结构的编程语言之间交换成为可能。
  59. #json.dumps()是将原始数据转为json(其中单引号会变为双引号),而json.loads()是将json转为原始数据。
  60. jsondatar=json.dumps(jsonData,ensure_ascii=False,sort_keys=True)
  61. #去除首尾的中括号
  62. return jsondatar[1:len(jsondatar)-1]
  63. def pack(ob,webnames):
  64. #取出相关服务器信息和状态
  65. file_data=json.loads(Server_sql())
  66. for wname in webnames:
  67. for aa in file_data:
  68. for obi in ob:
  69. if aa['WebName'] == wname and aa['Wsystem_class'] == obi:
  70. service_object = services(aa['WebName'],aa['WD_path'],aa['webhosts'],aa['WI_path'],aa['Wsystem_class'],aa['muser'],aa['mpass'],aa['rpass'])
  71. update_service.append(service_object)
  72. def pack_info():
  73. #取出相关服务器信息和状态
  74. file_data=json.loads(Server_sql())
  75. for aa in file_data:
  76. service_name = aa['WebName']
  77. groups_name = aa['Wsystem_class']
  78. Service_Names.append(service_name)
  79. Service_Names.append('all')
  80. GROUPS_Names.append(str(groups_name))
  81. GROUPS_Names.append('all')
  82. def scall(CMD_LINE):
  83. '''linux shell '''
  84. l.debug('CMD_LINE : %r',CMD_LINE)
  85. return call(CMD_LINE,shell=True)
  86. def os_system(cmd):
  87. result = os.popen(cmd)
  88. res = result.read()
  89. #for line in res.splitlines():
  90. #print line
  91. return res.splitlines()
  92. #封装的自定义打印模块
  93. def head_print():
  94. print '\033[1;31;40m'
  95. #print '*' * 50
  96. #print '\n'
  97. #封装的自定义打印模块
  98. def tail_print():
  99. #print '\n'
  100. #print '*' * 50
  101. print '\033[0m'
  102. #输出操作结果
  103. def output_result():
  104. head_print()
  105. for count in range(len(logs)):
  106. print "\n"
  107. for content in logs[count]:
  108. if 'MD5校验成功!' in content:
  109. print content
  110. break
  111. print content
  112. tail_print()
  113. class services:
  114. def __init__(self,WebName,WD_path,webhosts,WI_path,Wsystem_class,muser,mpass,rpass):
  115. self.WebName = WebName
  116. self.WD_path = WD_path
  117. self.WI_path = WI_path
  118. self.webhosts = webhosts
  119. self.Wsystem_class = Wsystem_class
  120. self.muser = muser
  121. self.mpass = mpass
  122. self.rpass = rpass
  123. def connect(self,cmd,allow_agent=False,look_for_keys=False):
  124. s=paramiko.SSHClient()
  125. s.load_system_host_keys()
  126. s.set_missing_host_key_policy(paramiko.AutoAddPolicy())
  127. s.connect(hostname=self.webhosts,port=22,username=self.muser, password=self.mpass)
  128. if self.muser != 'root':
  129. ssh = s.invoke_shell()
  130. time.sleep(0.1)
  131. ssh.send('su - \n')
  132. buff = ''
  133. while not buff.endswith('Password: '):
  134. resp = ssh.recv(9999)
  135. buff +=resp
  136. ssh.send(self.rpass)
  137. ssh.send('\n')
  138. buff = ''
  139. while not buff.endswith('# '):
  140. resp = ssh.recv(9999)
  141. buff +=resp
  142. ssh.send(cmd)
  143. ssh.send('\n')
  144. buff = ''
  145. while not buff.endswith('# '):
  146. resp = ssh.recv(9999)
  147. buff +=resp
  148. s.close()
  149. result = buff
  150. else:
  151. stdin, stdout, stderr = s.exec_command(cmd)
  152. result = stdout.read()
  153. s.close()
  154. print result
  155. return result
  156. def execute(self,*cmd):
  157. stdin, stdout, stderr = self.client.exec_command(*cmd)
  158. print stdout.readlines()
  159. print stderr.readlines()
  160. def putFile(self,localPath,remotePath):
  161. ftp = self.client.open_sftp()
  162. ftp.chmod(remotePath,777)
  163. if os.path.isdir(localPath):
  164. for f in os.listdir(localPath):
  165. remotefile = os.path.join(remotePath,f)
  166. localf = os.path.join(localPath,f)
  167. if os.path.isfile(localf):
  168. ftp.put(localf,remotefile)
  169. else:
  170. files = os.path.split(localPath)[-1]
  171. remotefile = os.path.join(remotePath,fles)
  172. ftp.put(localPath,'%s/'%remotefile)
  173. #关闭远端服务器tomcat
  174. def test_remote(self):
  175. #关闭远端进程
  176. shl='''ifconfig eth0|grep inet'''
  177. l.debug('%r',shl)
  178. self.connect(cmd=shl)
  179. def ps_prcee(self):
  180. shl='''ps aux|grep nginx'''
  181. l.debug('%r',shl)
  182. self.connect(cmd=shl)
  183. def push_prcee(self):
  184. shl='''wget -NP %s %s'''%(self.WI_path,Version_Url+self.WebName+'/'+self.WebName+'.zip')
  185. l.debug('%r',shl)
  186. self.connect(cmd=shl)
  187. def backup_prcee(self):
  188. 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)
  189. l.debug('%r',shl)
  190. self.connect(cmd=shl)
  191. def unzip_prcee(self):
  192. shl='''cd %s;unzip -o %s.zip'''%(self.WI_path,self.WebName)
  193. l.debug('%r',shl)
  194. self.connect(cmd=shl)
  195. #检测参数,执行操作
  196. def handle(args):
  197. logging.basicConfig(format="%(message)s")
  198. l.level = logging.INFO
  199. if args.verbose:
  200. l.level =logging.DEBUG
  201. op = args.operation
  202. ob = args.object
  203. webnames = args.webname
  204. ss = services
  205. if 'all' in webnames:
  206. pack_info()
  207. Service_Names.remove('all')
  208. webname = set(Service_Names)
  209. pack(ob,webname)
  210. else:
  211. pack(ob,webnames)
  212. if op == 'test':
  213. for content in update_service:
  214. ss.test_remote(content)
  215. if op == 'cupdate':
  216. for content in update_service:
  217. ss.backup_prcee(content)
  218. for content in update_service:
  219. ss.push_prcee(content)
  220. for content in update_service:
  221. ss.unzip_prcee(content)
  222. for content in update_service:
  223. ss.ps_prcee(content)
  224. if op == 'backup':
  225. for content in update_service:
  226. ss.backup_prcee(content)
  227. if op == 'ps':
  228. for content in update_service:
  229. ss.ps_prcee(content)
  230. if op == 'push':
  231. for content in update_service:
  232. ss.push_prcee(content)
  233. if op == 'unzip':
  234. for content in update_service:
  235. ss.unzip_prcee(content)
  236. #检测输入,
  237. def main():
  238. pack_info()
  239. ACTIONS = ['test','ps','push','cupdate','backup','unzip']
  240. webname = set(Service_Names)
  241. GROUPS = set(GROUPS_Names)
  242. parser = ArgumentParser()
  243. try:
  244. parser.add_argument('-v','--verbose',action='store_true',help='detail output')
  245. parser.add_argument('operation',choices=ACTIONS,help='action name')
  246. parser.add_argument('-o','--object',nargs='+',choices=GROUPS,help='object name')
  247. parser.add_argument('-w','--webname',nargs='+',choices=webname,help='update servername')
  248. except:
  249. print '%r'%tb.format_exc()
  250. args = parser.parse_args()
  251. handle(args)
  252. output_result()
  253. if __name__ == '__main__':
  254. main()