线上服务器既有Windows又有Linux的,代码的分发更新要规划下了。使用rsync来分发代码,同时考虑到不同系统平台,用法有些不同。将rsync命令进行了下封装,执行脚本即可。方便开发人员使用。
1. rsync服务端配置
# yum install rsync # vim /etc/rsyncd.conf uid = nobody gid = nobody use chroot = no strict modes = no max connections = 5 charset=utf8 secrets file = /etc/rsyncd.secrets reverse lookup = no transfer logging = yes log format = %t [%p] %o %a %m %P %f %B %M %l (%u) [%C] log file = /var/log/rsyncd.log pid file = /var/run/rsyncd.pid hosts allow = 10.0.100.162 hosts deny = * [www_ttlsa_com] path=/data/webroot/www.ttlsa.com comment = WSGW read only = no ignore errors exclude = .svn/ dont compress = *.gz *.tgz *.zip *.z *.bz2 *.tbz # vim /etc/rc.local rsync --daemon
2. 客户端
这里只说下Windows下的rsync用法,其实和Linux下相同,Windows上要安装cwRsync,同时将Python2.7也安装上,因为后面的Python脚本需要使用到Python环境。
# vim rsyncclient.py #coding:utf-8 import sys import os import getopt import itertools import subprocess import thread import Queue import platform if platform.system()=='Windows': _bin_path=r'D:"Program Files (x86)"cwRsync_5.3.0_Freersync.exe' else: _bin_path='rsync' _default_user='rsyncuser' _default_arg='-vzrtopg --progress --delete' _thread_num=10 _help_d={'-s':'(必选) 本地目录/文件。例如 E:\tmp', '-h':'(必选) 目的ip。支持", -"批量操作符,例如192.168.1,3-5.100', '-m':'(必选) rsync模块名', '-u':'(可选) rsync用户名。默认:%s'%(_default_user), '-p':'(可选) 密码文件路径。例如 E:\passwd\userpasswd.txt'} _help='rn'.join(['%s %s'%(k,v) for (k,v) in _help_d.iteritems()]) _help='全部参数:rn'+_help _help+='''rnrn样例: windows: rsynclient.py -h 192.168.1.2 -s E:\data\xuhh -m xuhh linux: python26 rsynclient.py -h 192.168.1.2 -s /data/xuhh -m xuhh [注意] E:\data\xuhh目录后面加上\与不加\有区别。如E:\data\xuhh\只同步xuhh目录下的内容不包含xuhh目录;E:\data\xuhh同步xuhh整个目录.''' _help+='rnrn' def check_num(func): def t(arg): arg=arg.replace(' ','') res=[x for x in [',','-'] if arg.startswith(x) or arg.endswith(x)] if res: raise NUMARG_ERROR('ip格式错误!') err_arg=[',-','-,','--',',,'] res=[x for x in err_arg if x in arg] if res: raise NUMARG_ERROR('ip格式错误!') return func(arg) return t class NUMARG_ERROR(Exception): def __init__(self,value): self.value=value def __str__(self): return self.value+'rnrn'+_help class ARG_ERROR(Exception): def __init__(self,value): self.value=value def __str__(self): return self.value+'rnrn'+_help def catch_exception(func): def t(*args,**kwargs): try: return func(*args,**kwargs) except NUMARG_ERROR,e: return e.__str__() except ARG_ERROR,e: return e.__str__() except getopt.GetoptError,e: return '-%s %srnrn%s'%(e[1],_help_d['-'+e[1]],_help) except: import cStringIO import traceback err_fp = cStringIO.StringIO() traceback.print_exc(file=err_fp) err_msg = err_fp.getvalue() err_msg='rn'.join(err_msg.split( 'n')) #self.response.out.write(err_msg) return err_msg return t @check_num def extend_num(arg): res=[] if ',' in arg: s=arg.split(',') for x in s: if '-' in x: y=[ str(xx).decode('utf-8') for xx in range(int(x.split('-')[0].strip()),int(x.split('-')[1].strip())+1)] res.extend(y) else: res.append(x.strip()) elif '-' in arg: x=arg y=[ str(xx).decode('utf-8') for xx in range(int(x.split('-')[0].strip()),int(x.split('-')[1].strip())+1)] res.extend(y) else: res.append(arg.strip()) res=dict.fromkeys(res).keys() res.sort() return res def to_rsync_path(path): if platform.system()=='Windows': rsync__path=os.path.abspath(path) rsync__path=rsync__path.replace('\','/') rsync__path=rsync__path.replace(':','') rsync__path='/cygdrive/'+rsync__path if path.endswith('\'): rsync__path+='/' return rsync__path else: return path @catch_exception def run(*argv): opts,args=getopt.getopt(argv,'h:m:s:u:p:') kwargs=dict(opts) #检查参数是否足够 if not kwargs.has_key('-h') or not kwargs.has_key('-s') or not kwargs.has_key('-m'): raise ARG_ERROR('参数不足!') print '--help' if kwargs.has_key('-u') and not kwargs.has_key('-p'): raise ARG_ERROR('密码参数-p没有指定!') #使用默认用户认证 if kwargs.has_key('-p') and not kwargs.has_key('-u'): kwargs['-u']=_default_user #将路径转换为rsync能识别的格式 kwargs['-s']=to_rsync_path(kwargs['-s']) if kwargs.has_key('-p'): kwargs['-p']=to_rsync_path(kwargs['-p']) #扩展ip ips=[] try: ip_seq1,ip_seq2,ip_seq3,ip_seq4=kwargs['-h'].split('.') for num1,num2,num3,num4 in itertools.product(extend_num(ip_seq1),extend_num(ip_seq2),extend_num(ip_seq3),extend_num(ip_seq4)): ips.append('%s.%s.%s.%s'%(num1,num2,num3,num4)) except: raise NUMARG_ERROR('ip格式错误!') #启动线程 queue=Queue.Queue() for x in range(_thread_num): thread.start_new_thread(_work_thread,(queue,)) for ip in ips: if kwargs.has_key('-u'): cmd='%s %s "%s" %s@%s::%s --password-file=%s'%(_bin_path,_default_arg,kwargs['-s'],kwargs['-u'],ip,kwargs['-m'],kwargs['-p']) else: cmd='%s %s "%s" %s::%s'%(_bin_path,_default_arg,kwargs['-s'],ip,kwargs['-m']) queue.put([ip,cmd]) queue.join() def _work_thread(queue): while True: ip,cmd=queue.get() output=subprocess.Popen(cmd.encode('cp936'),shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.read() output= '**********%s**********rn%srn%s'%(ip,cmd,output) if platform.system()=='Windows': output=output.decode('utf-8').encode('cp936') print output queue.task_done() if __name__=='__main__': argv=sys.argv[1:] if argv: res=run(*argv) if res: if platform.system()=='Windows': res=res.decode('utf-8').encode('cp936') print res else: if platform.system()=='Windows': _help=_help.decode('utf-8').encode('cp936') print _help
IP支持192.168.1,3-5.100,111-122这种写法。
3. 用法
转载请注明:爱开源 » Windows 下 rsync 代码分发