主要功能是自动发现被监控目录的上传文件。并通过socket传送给各个选定的父节点,然后父节点在同步到子节点IDC
#!/usr/bin/env python #encoding=utf8 ''' @attention: This file is the main file @license: GNU GPL v3 @author: Wayne @contact: wangzhenyu@gyyx.cn @note: 2015/06/18 lastest stable version 0.1 release ''' import hashlib,sys,os,datetime,fcntl,re,socket,time,commands,threading,random from pyinotify import WatchManager, Notifier,ProcessEvent,IN_DELETE, IN_CREATE,IN_MODIFY,IN_CLOSE_WRITE from init_db import MyDB def port_scan(): print "start port scan.................." db2= MyDB(user = '***', passwd = '****', db = '******', socket = '/tmp/mysql.socket') if db2.connect(): print "db2 connected" else: print "can not connect to db server!" return False ser_list=db2.select('select node_ip from ser_info') print ser_list for ser in ser_list: sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: sk.connect((ser[0],6969)) db2.modify("update ser_info set isalive=0 where node_ip='%s'" % ser[0]) print "set %s is available" % ser[0] sk.close() except Exception: db2.modify("update ser_info set isalive=1 where node_ip='%s'" % ser[0]) print "set %s is unavailable" % ser[0] return db2 def settopnode(db): sql_uni="select node_ip from ser_info left join idc_info on (ser_info.idc_id=idc_info.idc_id and ser_info.isalive=0) where idc_info.line_id=1" sql_tel="select node_ip from ser_info left join idc_info on (ser_info.idc_id=idc_info.idc_id and ser_info.isalive=0) where idc_info.line_id=0" print "searching server list............." uni_list=db.select(sql_uni) tel_list=db.select(sql_tel) if len(uni_list)==0: top_uni_node='error' else: top_uni_node=random.choice(uni_list)[0] if len(tel_list)==0: top_tel_node='error' else: top_tel_node=random.choice(tel_list)[0] return top_uni_node,top_tel_node class ThreadSock(threading.Thread): def __init__(self,ip,fname,gdir,md5_sum): threading.Thread.__init__(self) self.setDaemon(True) self.ip=ip self.fname=fname self.gdir=gdir self.md5_sum=md5_sum self.port=6969 def run(self): sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) sock.connect((self.ip,self.port)) create_sync=rsync_file_cmd(self.fname,self.ip, self.gdir) starttime=time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()) commands.getstatusoutput(create_sync.cmd) sock.send(self.fname+" " +self.fdir+" "+self.md5_sum+" "+'END') class rsync_file_cmd(): def __init__(self,src_file,ip,dst): self.src_file=src_file self.ip=ip self.dst=dst self.cmd='/usr/bin/rsync -az --delete %s %s::htdocs/%s' % (src_file,ip,dst) def save_trans_data(src,eventname,eventpath): db2=port_scan() print "start select topnode......." top_uni_node,top_tel_node=settopnode(db2) print top_uni_node,top_tel_node print src,eventname,eventpath os.chdir(eventpath) md5_sum=get_md5(eventname) gdir=eventpath.split('/')[-1] gid=int(db2.select('select gid from game_info where path="%s"' % eventpath)[0][0]) print "gid is %d" % gid insert_sql="insert into file_info (fname,gid) values ('%s',%s)" % (eventname,gid) db2.modify(insert_sql) print "insert file to db......." db2.close() if top_uni_node !='error': print "start trans file to union nodes......" t1=ThreadSock(top_uni_node,eventname,gdir,md5_sum) t1.start() if top_tel_node !='error': t2=ThreadSock(top_tel_node,eventname,gdir,md5_sum) t2.start() def get_md5(filename): md5_sum=hashlib.md5(filename).hexdigest() return md5_sum class EventHandler(ProcessEvent): """Handle""" def process_IN_CREATE(self,event): if event.dir: if event.pathname.split('/')[-3]=='games': save_trans_data(event.pathname,event.name,event.path) def process_IN_CLOSE_WRITE(self, event): if event.pathname.split('/')[-3]=='games': save_trans_data(event.pathname,event.name,event.path) def FSMonitor(path='/home/htdocs/games/'): wm = WatchManager() mask = IN_CLOSE_WRITE notifier = Notifier(wm,EventHandler()) wm.add_watch(path,mask,rec=True,auto_add=True) while True: try: notifier.process_events() if notifier.check_events(): notifier.read_events() except: notifier.stop() break if __name__=='__main__': try: pid = os.fork() if pid > 0: sys.exit(0) except OSError, e: print >>sys.stderr, 'fork failed: %d (%s)' % (e.errno, e.strerror) sys.exit(1) os.setsid() os.umask(0) FSMonitor()