zoukankan      html  css  js  c++  java
  • 代码更新系统(一):配置文件配置

    • 背景:

    平常工作中,经常写更新脚本,一个会拉,一会推,一会使用ssh隧道。脚本好几个不利于管理。一直以来都想些一套更新系统。系统可以复用,可以自己选择在配置文件里更新方法或者选择在WEB上配置,WEB接受更新和展示更新状态,甚至在WEB实事执行更新操作。为了实现这些功能,一步步来,先实现从配置文件里读取配置并执行更新。以后功能都写好后再整合

    • 更新工具:rsync
    • 代码
      1 #-*- coding: utf-8 -*-
      2 '''
      3 Created on 2013-7-1
      4 
      5 @author: Jin
      6 '''
      7 import os
      8 import sys
      9 import ConfigParser
     10 import logging
     11 import subprocess
     12 
     13 #vars
     14 config_file='./config.ini'
     15 homedir   = './'
     16 logfile   = os.path.basename(sys.argv[0])+'.log'
     17 logpath   = homedir+logfile
     18 
     19 #logconfig
     20 logging.basicConfig(level=logging.DEBUG,
     21                     format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
     22                     datefmt='%Y-%m-%d %H:%M',
     23                     filename=logpath,
     24                     filemode='a')
     25 
     26 console = logging.StreamHandler()
     27 console.setLevel(logging.INFO)
     28 formatter = logging.Formatter('%(asctime)s %(name)-12s %(levelname)-8s %(message)s')
     29 console.setFormatter(formatter)
     30 logging.getLogger('').addHandler(console)
     31 
     32 
     33 def check_file(filename):
     34     if os.path.exists(filename) and os.path.isfile(filename):
     35         return True
     36     else:
     37         return False
     38     
     39 def config_from_file(config_file='./config.ini'):
     40     '''
     41     Get config from config file.return dict date
     42     The dict keys is:'method','action','rsync_bin','ip','user','argv','excludeconf','localdir','pwdfile','module','remotedir'
     43     If pwdfile,module,excludeconf undefine,will use default set:
     44     password file is '/etc/rsync/rsync_default.secrets'
     45     module is 'default'
     46     excludeconf is '/etc/rsync/exclude_files.conf'
     47     '''
     48     
     49     if check_file(config_file):
     50         config=ConfigParser.ConfigParser()
     51         config.read(config_file)
     52         
     53         if config.has_option('rsyncclient','method'):
     54             method=config.get('rsyncclient','method')
     55         else:
     56             method=None           
     57         if config.has_option('rsyncclient','action'):
     58             action=config.get('rsyncclient','action')
     59         else:
     60             action=None
     61         if config.has_option('rsyncclient','rsync_bin'):
     62             rsync_bin=config.get('rsyncclient','rsync_bin')
     63         else:
     64             rsync_bin='rsync'
     65         if config.has_option('rsyncclient','ip'):
     66             ip=config.get('rsyncclient','ip')
     67         else:
     68             ip=None   
     69         if config.has_option('rsyncclient','user'):
     70             user=config.get('rsyncclient','user')
     71         else:
     72             user=None           
     73         if config.has_option('rsyncclient','argv'):
     74             argv=config.get('rsyncclient','argv')
     75         else:
     76             argv=None       
     77         if config.has_option('rsyncclient','localdir'):
     78             localdir=config.get('rsyncclient','localdir')
     79         else:
     80             localdir=None           
     81         if config.has_option('rsyncclient','excludeconf'):
     82             excludeconf=config.get('rsyncclient','excludeconf')
     83         else:
     84             excludeconf='/etc/rsync/exclude_files.conf'
     85                    
     86         #method daemon options  need passwordfile and module         
     87         if config.has_option('rsyncclient','pwdfile'):
     88             pwdfile=config.get('rsyncclient','pwdfile')
     89         else:
     90             pwdfile='/etc/rsync/rsync_default.secrets'
     91         if config.has_option('rsyncclient','module'):
     92             module=config.get('rsyncclient','module')
     93         else:
     94             module='default'
     95         
     96         #method ssh options need remotedir
     97         if config.has_option('rsyncclient','remotedir'):
     98             remotedir=config.get('rsyncclient','remotedir')
     99         else:
    100             remotedir=None
    101           
    102         data = {'method':method,'action':action,'rsync_bin':rsync_bin,'ip':ip,'user':user,'argv':argv,'localdir':localdir,'excludeconf':excludeconf,'pwdfile':pwdfile,'module':module,'remotedir':remotedir}
    103         #logging.debug("data:%s" % data)
    104         return data
    105     
    106     else:
    107         logging.error("%s is not exist" % config_file) 
    108         return None    
    109         
    110 def get_cmd(configdata):
    111     '''
    112     assembling command from config dict
    113     '''
    114     if type(configdata)==type({}):   
    115         if None in configdata.values():
    116             for key in configdata:
    117                 if configdata[key] == None:
    118                     logging.error("%s is undefine!" % key)
    119                     return None
    120         else: 
    121             if configdata['method']=='daemon' and configdata['action']=='push':
    122                 '''push local to rsync daemon server'''
    123                 cmd=configdata['rsync_bin']+' '+configdata['argv']+' '+'--exclude-from='+configdata['excludeconf']+' '+'--password-file='+configdata['pwdfile']+' '+configdata['localdir']+' '+configdata['user']+'@'+configdata['ip']+'::'+configdata['module']
    124                 return cmd
    125             elif configdata['method']=='daemon' and configdata['action']=='pull':
    126                 '''pull from rsync daemon server to local'''
    127                 cmd=configdata['rsync_bin']+' '+configdata['argv']+' '+'--exclude-from='+configdata['excludeconf']+' '+'--password-file='+configdata['pwdfile']+' '+configdata['user']+'@'+configdata['ip']+'::'+configdata['module']+' '+configdata['localdir']
    128                 return cmd
    129             elif configdata['method']=='ssh' and configdata['action']=='push':
    130                 '''push local to remote server use ssh'''
    131                 cmd=configdata['rsync_bin']+' '+configdata['argv']+' '+'-e '+configdata['method']+' '+'--exclude-from='+configdata['excludeconf']+' '+configdata['localdir']+' '+configdata['user']+'@'+configdata['ip']+':'+configdata['remotedir']
    132                 return cmd
    133             elif configdata['method']=='ssh' and configdata['action']=='pull':
    134                 '''pull from to remote server to local use ssh'''
    135                 cmd=configdata['rsync_bin']+' '+configdata['argv']+' '+'-e '+configdata['method']+' '+'--exclude-from='+configdata['excludeconf']+' '+configdata['user']+'@'+configdata['ip']+':'+configdata['remotedir']+' '+configdata['localdir']
    136                 return cmd
    137             else:
    138                 '''undefine'''
    139                 logging.error("method:%s or action:%s error!" % (configdata['method'],configdata['action']))
    140                 return None  
    141             
    142 def check_rsyncclient_runevn(configdata):
    143     '''check excludeconf,is not exists create it,check pwdfile,is not exists warning and exit'''
    144     if not check_file(configdata['excludeconf']):
    145         logging.info("%s is not exists,Now create it!" % configdata['excludeconf'])
    146         with open(configdata['excludeconf'],'wt') as f:
    147             f.write('')
    148         
    149     if configdata['method']=='daemon':
    150         if not check_file(configdata['pwdfile']):
    151             logging.error("%s is not exists!" % configdata['pwdfile'])
    152             return False
    153         else:
    154             return True
    155     elif configdata['method']=='ssh':
    156         return True
    157     else:
    158         return False
    159               
    160 def is_running(processname):
    161     '''Get processname status '''
    162     cmd='/usr/bin/pgrep '+ processname+' > /dev/null 2>&1'
    163     try:
    164         #pstat=subprocess.Popen(cmd,shell=True,stdin=subprocess.PIPE)
    165         pstat=subprocess.Popen(cmd,shell=True)
    166     except StandardError,e:
    167         logging.error("Get run status failed:: %s ,exit run!" % e)
    168         sys.exit(1)
    169     else:
    170         pstat.wait()
    171         if pstat.returncode == 0:
    172             return True
    173         else:
    174             return False
    175         
    176 def run_command(cmd):
    177     '''run command'''
    178     if is_running('rsync'):
    179         logging.warning("rsync is running!")
    180     else:
    181         try:
    182             pstat=subprocess.Popen(cmd,shell=True,stderr=subprocess.PIPE,stdout=subprocess.PIPE)
    183         except StandardError,e: 
    184             logging.error("Run script failed:: %d (%s) ,exit run!" % (e.errno, e.strerror))
    185             sys.exit(1)
    186         else:
    187             pstat.wait()
    188             if pstat.returncode == 0:
    189                 logging.info("Run script Successful,exit code is %s" % pstat.returncode)
    190                 lines=pstat.stdout.readlines()
    191                 dellist=[]
    192                 rsync_dict={}
    193                 for line in lines:
    194                     if 'deleting' in line:
    195                         dellist.append(line.split()[1])
    196                 delcount=len(dellist)
    197                 addlist=[i.rstrip('
    ') for i in lines[delcount+2:-3]]
    198                 addcount=len(addlist)
    199                 speed=' '.join(lines[-2].split()[-2:])
    200                 rsync_dict={}
    201                 rsync_dict['delcount']=delcount
    202                 rsync_dict['dellist']=dellist
    203                 rsync_dict['addcount']=delcount
    204                 rsync_dict['addlist']=addlist
    205                 rsync_dict['speed']=speed
    206                 print rsync_dict
    207                 logging.info("Result,delcount:%d,dellist:%s,addcount:%d,addlist:%s,speed:%s" % (delcount,dellist,addcount,addlist,speed))
    208                     
    209             else:
    210                 logging.error("Run script End,exit code is %s,With reason <%s>" % (pstat.returncode,pstat.stderr.read().rstrip('
    ')))
    211                 
    212 
    213 def __main__():
    214     configdata=config_from_file(config_file)
    215     if configdata:
    216         cmd=get_cmd(configdata)
    217         if cmd:
    218             if check_rsyncclient_runevn(configdata):
    219                 run_command(cmd)
    220             else:
    221                 logging.error("check rsyncclient runenv fail,detail see log!")
    222                 sys.exit(3)
    223         else:
    224             logging.error("command is None,detail see log!")
    225             sys.exit(2)
    226     else:
    227         logging.error("configdata is None,detail see log!")
    228         sys.exit(1)
    229     
    230         
    231 if __name__ == '__main__':
    232     __main__()
    View Code
    • 配置文件格式

    [rsyncclient]
    action = pull
    method = daemon
    localdir = /tmp/testdir/
    user = rsync_store
    ip = 127.0.0.1
    argv = -vzrtopg --delete
    excludeconf=./exclude_files.conf
    remotedir = /tmp/remotedir/
    module = store
    pwdfile = ./rsync_store.passwd

    • 代码简单说明:

    check_file:判断文件存在且进为文件(排除文件存在为目录的情况)

    config_from_file:从ini文件读取配置,吐出一个配置字典

    get_cmd:将配置字典组合成一个command,根据method和

    check_rsyncclient_runevn:根据配置字典检查rsync的运行环境 排除文件和密码文件,这里是我比较纠结的地方,要不要创建空的排除列表文件?

    is_running:检查程序是否运行,其实不严谨,下一个版本看是否能改进

    run_command():运行组合好的命令

     __main__():前面的函数逻辑上组合在一起

  • 相关阅读:
    造轮子 | 怎样设计一个面向协议的 iOS 网络请求库
    win7 激活码 秘钥
    python-pptx
    pycharm
    itop 环境
    Ubuntu上安装MongoDB(译)
    python之fabric(二):执行模式(转)
    python之fabric(一):环境env
    Windows下pip安装包报错:Microsoft Visual C++ 9.0 is required Unable to find vcvarsall.bat
    vagrant系列教程(四):vagrant搭建redis与redis的监控程序redis-stat(转)
  • 原文地址:https://www.cnblogs.com/diege/p/3171147.html
Copyright © 2011-2022 走看看