代码更新系统(一):配置文件配置

  • 背景:

平常工作中,经常写更新脚本,一个会拉,一会推,一会使用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('\n') 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('\n')))

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__():前面的函数逻辑上组合在一起

 

 

 

 

你可能感兴趣的:(配置文件)