Chinaunix首页 | 论坛 | 博客
  • 博客访问: 140616
  • 博文数量: 31
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 309
  • 用 户 组: 普通用户
  • 注册时间: 2014-06-06 11:27
个人简介

开启暴走模式。

文章分类

全部博文(31)

文章存档

2017年(19)

2016年(1)

2015年(11)

我的朋友

分类: Python/Ruby

2017-02-28 19:26:12


点击(此处)折叠或打开

  1. #!/usr/bin/env python
  2. # -*-coding:utf-8 -*-
  3. # Author: Dily
  4. #  Email: 312797697@qq.com
  5. “”“ 实现在线业务批量升级”“”

  6. import time
  7. import sys
  8. import socket
  9. import subprocess
  10. import logging
  11. import json
  12. import urllib2
  13. import hashlib
  14. import os

  15. Threshold = 1280
  16. ip = ''
  17. port = 9999

  18. fcd_file = "/etc/fcd.conf"
  19. fcd_par_file = "/home/dily/fcd_private"
  20. annotation_fcd = "sed -i '/fw_cluster/s/^/#/'" + " " + fcd_file
  21. annotation_fcd_par = "sed -i '/fw_cluster/s/^/#/'" + " " + fcd_par_file
  22. remove_anno_fcd = "sed -i '/fw_cluster/s/^#//'" + " " + fcd_file
  23. remove_anno_fcd_par = "sed -i '/fw_cluster/s/^#//'" + " " + fcd_par_file
  24. reload_fcd = "/usr/local/fcd/sbin/fcd -r"
  25. to_time = time.strftime('%Y%m%d',time.localtime(time.time()))
  26. backup_fcd_file = "cp -f" + " " + fcd_file + " " + fcd_file + "." + to_time
  27. backup_par_file = "cp -f" + " " + fcd_par_file + " " + fcd_par_file + "." + to_time
  28. diff_fcd_file = "diff" + " " + fcd_file + " " + fcd_file + "." + to_time + "| grep '^<'"
  29. diff_par_file = "diff" + " " + fcd_par_file + " " + fcd_par_file + "." + to_time + "| grep '^<'"
  30. STATS = []

  31. host = ''
  32. fcname = 'dily'
  33. fkey = 'xxxxxx'
  34. mytime=time.strftime('%Y%m%d',time.localtime(time.time()))

  35. def Get_token(_key=fkey,salt=mytime):
  36.     """获取BOSS_API的token值"""
  37.     m = hashlib.md5()
  38.     m.update(salt + hashlib.new('md5',_key).hexdigest())
  39.     fctoken = m.hexdigest()
  40.     return fctoken

  41. def Suspend_parsing():
  42.     """通过BOSS_API暂停BOSS解析"""
  43.     domain_data = json.dumps({
  44.         "fctoken" : Get_token(),
  45.         "fcname" : fcname,
  46.         "hostname": socket.gethostname().split(".")[0],
  47.         "op" : "pause",
  48.         "remark" : "fcd自动升级。联系人:Dily"
  49.     })

  50.     request = urllib2.Request(host,domain_data)
  51.     try:
  52.         response = urllib2.urlopen(request,timeout = 30)
  53.     except urllib2.URLError as e:
  54.         if hasattr(e,'reason'):
  55.             logging.error(' Forward API server no response.')
  56.             logging.error(' Reason: %s',e.reason)
  57.         elif hasattr(e,'code'):
  58.             logging.error(' The server could not fulfill the request.')
  59.             logging.error(' Error code: %s',e.code)
  60.     else:
  61.         resp = response.read()
  62.         res = json.loads(resp)
  63.         response.close()

  64.         if res['status'] == 1:
  65.             logging.info(' %s Suspend parsing OK',res['info'])
  66.             return True
  67.         else:
  68.             logging.error(' %s Suspend parsing Faild',res['info'])
  69.             return False

  70. def Restore_parsing():
  71.     """通过BOSS_API恢复BOSS解析"""
  72.     domain_data = json.dumps({
  73.         "fctoken" : Get_token(),
  74.         "fcname" : fcname,
  75.         "hostname": socket.gethostname().split(".")[0],
  76.         "op" : "recover",
  77.         "remark" : "fcd自动升级。联系人:Dily"
  78.     })

  79.     request = urllib2.Request(host,domain_data)
  80.     try:
  81.         response = urllib2.urlopen(request,timeout = 30)
  82.     except urllib2.URLError as e:
  83.         if hasattr(e,'reason'):
  84.             logging.error(' Forward API server no response.')
  85.             logging.error(' Reason: %s',e.reason)
  86.         elif hasattr(e,'code'):
  87.             logging.info(' The server could not fulfill the request.')
  88.             logging.error(' Error code: %s',e.code)
  89.     else:
  90.         resp = response.read()
  91.         res = json.loads(resp)
  92.         response.close()

  93.         if res['status'] == 1:
  94.             logging.info(' %s Suspend parsing OK',res['info'])
  95.             return True
  96.         else:
  97.             logging.error(' %s Suspend parsing Faild',res['info'])
  98.             return False

  99. def nic():
  100.     """自动识别在用的网卡名"""
  101.     s = {}
  102.     with open("/proc/net/dev") as f:
  103.         lines = f.readlines()
  104.     for line in lines[2:]:
  105.         colon = line.rfind(':')
  106.         assert colon > 0, repr(line)
  107.         name = line[:colon].strip()
  108.         fields = line[colon + 1:].strip().split()
  109.         if name != 'lo':
  110.             s[name] = int(fields[0])
  111.     rx = (lambda x: max(x))(s.values())
  112.         
  113.     for key in s:
  114.         if s[key] == rx:
  115.             return key

  116. def net_io(_INTERFACE=nic()):
  117.     """网卡进出流量计数器"""
  118.     with open("/proc/net/dev") as f:
  119.         lines = f.readlines()
  120.     for line in lines[2:]:
  121.         colon = line.rfind(':')
  122.         assert colon > 0, repr(line)
  123.         name = line[:colon].strip()
  124.         if _INTERFACE in name:
  125.           fields = line[colon + 1:].strip().split()
  126.           bytes_recv = int(fields[0])
  127.           bytes_sent = int(fields[8])
  128.     return bytes_recv,bytes_sent
  129.  
  130. def rx():
  131.     """网卡接收流量"""
  132.     ifstat = open('/proc/net/dev').readlines()
  133.     for interface in ifstat:
  134.         if INTERFACE in interface:
  135.             stat,b = net_io()
  136.             STATS[0:] = [stat]
  137.  
  138. def tx():
  139.     """网卡传输流量"""
  140.     ifstat = open('/proc/net/dev').readlines()
  141.     for interface in ifstat:
  142.         if INTERFACE in interface:
  143.             a,stat = net_io()
  144.             STATS[1:] = [stat]

  145. def IsOpen(ip,port):
  146.     """服务检测"""
  147.     s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
  148.     try:
  149.         s.connect((ip,int(port)))
  150.         s.shutdown(2)
  151.         logging.info(' %d port is open',port)
  152.         return True
  153.     except:
  154.         logging.info(' %d port is close',port)
  155.         return False

  156. def netM(_Threshold=Threshold):
  157.     """按网卡传输5次的平均值监控流量"""
  158.     rx()
  159.     tx()
  160.  
  161.     while True:
  162.         time.sleep(5)
  163.         rxstat_o = list(STATS)
  164.         rx()
  165.         tx()
  166.         RX = float(STATS[0])
  167.         RX_O = rxstat_o[0]
  168.         TX = float(STATS[1])
  169.         TX_O = rxstat_o[1]
  170.         RX_RATE = round((RX - RX_O)/1024/5,2)
  171.         TX_RATE = round((TX - TX_O)/1024/5,2)
  172.         logging.info(' recv traffic is %s KB, send traffic is %s KB.', RX_RATE,TX_RATE)
  173.         if TX_RATE <= _Threshold:
  174.             print '流量切换完成,执行下一步操作!'
  175.             logging.info(' 流量切换完成,执行下一步操作!')
  176.             break

  177. def Suspend_cluster():
  178.     """暂停集群"""
  179.     logging.info(' 本机器有集群设置')
  180.     logging.info(' 备份fcd配置文件 %s 到 %s.%s',fcd_file,fcd_file,to_time)
  181.     subprocess.call(backup_fcd_file,shell=True)
  182.     logging.info(' 备份fcd_par配置文件 %s 到 %s.%s',fcd_par_file,fcd_par_file,to_time)
  183.     subprocess.call(backup_par_file,shell=True)
  184.     logging.info(' 注释fcd集群')
  185.     subprocess.call(annotation_fcd,shell=True)
  186.     logging.info(' 注释fcd_par集群')
  187.     subprocess.call(annotation_fcd_par,shell=True)
  188.     logging.info(' diff fcd新旧配置文件 starting')
  189.     fcd = subprocess.Popen(diff_fcd_file,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
  190.     for line in fcd.stdout.readlines():
  191.         logging.info(' %s',line.strip())
  192.     logging.info(' diff fcd新旧配置文件 ending')
  193.     logging.info(' diff fcd_par新旧配置文件 starting')
  194.     par = subprocess.Popen(diff_par_file,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
  195.     for line in par.stdout.readlines():
  196.         logging.info(' %s',line.strip())
  197.     logging.info(' diff fcd_par新旧配置文件 ending')
  198.     logging.info(' starting reload fastcache')
  199.     fcd_reload_after = subprocess.Popen(reload_fcd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
  200.     for line in fcd_reload_after.stdout.readlines():
  201.         logging.info(' %s',line.strip())
  202.     logging.info(' ending reload fastcache')

  203. def Restore_cluster():
  204.     """恢复集群"""
  205.     subprocess.call(remove_anno_fcd,shell=True)
  206.     subprocess.call(remove_anno_fcd_par,shell=True)
  207.     logging.info(' diff fcd新旧配置文件 starting')
  208.     fcd_after = subprocess.Popen(diff_fcd_file,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
  209.     for line in fcd_after.stdout.readlines():
  210.         logging.info(' %s',line.strip())
  211.     logging.info(' diff fcd新旧配置文件 ending')
  212.     logging.info(' diff fcd_par新旧配置文件 starting')
  213.     par_after = subprocess.Popen(diff_par_file,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
  214.     for line in par_after.stdout.readlines():
  215.         logging.info(' %s',line.strip())
  216.     logging.info(' diff fcd_par新旧配置文件 ending')
  217.     logging.info(' starting reload fastcache')
  218.     fcd_reload_after = subprocess.Popen(reload_fcd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
  219.     for line in fcd_reload_after.stdout.readlines():
  220.         logging.info(' %s',line.strip())
  221.     logging.info(' ending reload fastcache')

  222. def mylog_init():
  223.     """日志格式初始化"""
  224.     logging.basicConfig(level=logging.DEBUG,
  225.     format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s:%(name)s:%(message)s',
  226.     datefmt='%a, %d %b %Y %H:%M:%S',
  227.     filename='fcd_test.log',
  228.     filemode='w')

  229. def Usage():
  230.     """fcd自动升级用法"""
  231.     if len(sys.argv) < 2:
  232.         print '''\
  233.     No action specified.
  234.     Detailed inquiry help
  235.     eg. : python fcd_test.py --help'''
  236.         sys.exit()

  237.     if sys.argv[1].startswith('--'):
  238.         option = sys.argv[1][2:]
  239.         if option == 'version':
  240.             print 'Version 1.0'
  241.         elif option == 'help':
  242.             print '''\
  243.     这个程序主要处理fcd的自动升级;参数是shell升级脚本。见help!
  244.     参数必须和升级程序在同一目录,或者指定shell升级脚本的绝对路径!
  245.     Options include:
  246.       --version : Prints the version number
  247.       --help : Display this help
  248.         argv[1] : upgrade sh file
  249.         eg. : python fcd_test.py upgrade.sh or python fcd_test.py /tmp/upgrade.sh'''
  250.         else:
  251.             print '''\
  252.     Unknown option.
  253.     Detailed inquiry help
  254.     eg. : python fcd_test.py --help'''
  255.         sys.exit()

  256. def main():
  257.     """主函数"""
  258.     Usage()

  259.     if os.path.exists(sys.argv[1]):
  260.         upgrade_sh = "sh"+ " " + sys.argv[1]
  261.     else:
  262.         print '请确认文件是否存在'
  263.         sys.exit(1)

  264.     global INTERFACE
  265.     INTERFACE = nic()

  266.     mylog_init()

  267.     logging.info(' Interface : %s',INTERFACE)
  268.     if Suspend_parsing():
  269.         if IsOpen(ip,port):
  270.             Suspend_cluster()
  271.             logging.info(' 开始监控网卡流量')
  272.             netM()
  273.             retcode = subprocess.call(upgrade_sh,shell=True)
  274.             if retcode != 0:
  275.                 logging.error(" Execute the script errors. return %d", -retcode)
  276.                 Restore_cluster()
  277.             else:
  278.                 logging.info(" Execute the script successfully. return %d", retcode)
  279.                 Restore_cluster()
  280.                 if Restore_parsing():
  281.                     logging.info(' 本机IP已经恢复解析')
  282.                 else:
  283.                     logging.warning(' 请先检查本机IP是否恢复解析')
  284.         else:
  285.             logging.info(' 本机器无集群设置')
  286.             netM()
  287.             retcode = subprocess.call(upgrade_sh,shell=True)
  288.             if retcode != 0:
  289.                 logging.error(" Execute the script errors. return %d", -retcode)
  290.             else:
  291.                 logging.info(" Execute the script successfully. return %d", retcode)
  292.                 if Restore_parsing():
  293.                     logging.info(' 本机IP已经恢复解析')
  294.                 else:
  295.                     logging.warning(' 请先检查本机IP是否恢复解析')
  296.     else:
  297.         logging.warning(' 请先检查本机IP是否暂停解析')

  298. if __name__ == '__main__':
  299.     main()

阅读(1637) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~