# vim: tabstop=4 shiftwidth=4 softtabstop=4# Copyright 2010 United States Government as represented by the# Administrator of the National Aeronautics and Space Administration.# Copyright 2011 Justin Santa Barbara# All Rights Reserved.# Copyright (c) 2010 Citrix Systems, Inc.##    Licensed under the Apache License, Version 2.0 (the "License"); you may#    not use this file except in compliance with the License. You may obtain#    a copy of the License at##         http://www.apache.org/licenses/LICENSE-2.0##    Unless required by applicable law or agreed to in writing, software#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the#    License for the specific language governing permissions and limitations#    under the License.import smtplibimport os,sys,time,fcntl,structimport ConfigParserimport commandsimport tracebackimport socketimport shutilimport sysimport retry:    from email.mime.multipart import MIMEMultipartexcept:    from email.MIMEMultipart import MIMEMultiparttry:    from email.mime.text import MIMETextexcept:    from email.MIMEText import MIMETexttry:    from hashlib import md5except:    from md5 import md5CONFIG_PATH = "/etc/rsyncd.conf"def _load_cfg(section = None):    '''    load config section from CONFIG_PATH    '''    global CONFIG_PATH    config = ConfigParser.ConfigParser()    if os.path.isfile(CONFIG_PATH):        config.read(CONFIG_PATH)        sections = config.sections()        if section and section in sections:            return dict(config.items(section))        elif not section:            rst = dict()            for sec in sections:                rst[sec] = dict(config.items(sec))            return rst        else:            return dict()def load_cfg(sections = []):    '''    from cfg format to dict    :params sections The section list in cfg    return a dict with all options    '''    rst = dict()    if not sections:        return _load_cfg()    for sec in sections:        rst[sec] = _load_cfg(sec)    return rstdef logging(item,level,mes):    logpath = '/var/log/kxtools/'    if not os.path.exists(logpath):        os.makedirs(logpath)    fp = open('%s/kxbackup.log'%logpath,'a')    fp.write('%s - %s - %s - %s \n'%(time.ctime(),item,level,mes))    fp.close()"""Access file md5 value"""def MD5(fname):    filemd5 = ""    try:        file = open(fname, "rb")        md5f = md5()        strs = ""        while True:            strs = file.read(8096)            if not strs:                break            md5f.update(strs)        filemd5 = md5f.hexdigest()        file.close()        return filemd5    except:        logging('MySQL Check','ERROR',traceback.format_exc())def get_em_ipaddr(dev):    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)    IP = socket.inet_ntoa(fcntl.ioctl(           s.fileno(),           0x8915,  # SIOCGIFADDR           struct.pack('24s',dev)    )[20:24])    return IPdef ipaddr():    """    Get host name, ip    return(hostname, ip)    """    def _get_ipaddr():        try:            s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)            s.connect(("8.8.8.8", 8000))            return s.getsockname()[0]        except:            logging('MySQL Check','ERROR',traceback.format_exc())        s.close()    return (socket.gethostname(), _get_ipaddr())def tracert(ip):    count = 0    for t in range(10):        sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)        sock.settimeout(10)        try:            sock.connect((ip,873))            count += 1        except socket.error,e:            pass        time.sleep(1)    if count >= 6:        return 0    else:        return 1class  SendMail(object):    def __init__ (self):        self.smtpserver = 'smtp.163.com'        self.fro = 'kxbackup@163.com'        self.c_code = 'UTF-8'        self.port = 25        self.auth = 'kxbackup@163.com'        self.pawd = '11111111@123'    ''' Send Email'''    def sendmail(self,to,subject,content,cc='',files=[]):        msg = MIMEMultipart()        msg['Subject'] = subject        txt = MIMEText(content)        msg.attach(txt)        hd = smtplib.SMTP(self.smtpserver,self.port)        hd.ehlo()        hd.starttls()        hd.ehlo()        if self.auth and self.pawd:            hd.login(self.auth,self.pawd)        for t in to.split(","):            hd.sendmail(self.fro,t, msg.as_string())        if cc:            for t in cc.split(","):                hd.sendmail(self.fro,t, msg.as_string())        hd.close()class CheckMySQL(object):    def __init__(self):        version = 1.0    def checkRsyncConfig(self):        # Rsync configuration check        fp = open('/etc/rsyncd.conf','r').readlines()        for n,s in enumerate(fp):            if n == 0:                if s[0] != '[':                    fp.insert(0,'[global]\n')        f = open('/etc/rsyncd.conf','w')        f.writelines(fp)        f.close()    def checkFile(self):        # Directory traversal, find today compared with yesterday's file        backupPath  = load_cfg()['yttx']['path']        os.chdir(backupPath)        CTIME = time.strftime('%Y%m%d')        files= dict()        # Define the keys        for f in os.listdir(backupPath):            stamp_time, file_kyes = self._get_file_ctime(f)            if (time.time() - stamp_time) <= 86400:                files[file_kyes] = list()        # According to the date of classified documents        for f in os.listdir(backupPath):            stamp_time , file_ctime = self._get_file_ctime(f)            stamp_ctime = time.time()            for tm in files.keys():                #print file_ctime,f                if tm == file_ctime and (stamp_ctime - stamp_time) <= 86400:                    files[tm].append(f)        # Check the file MD5        today_file =dict()        ystday_file = dict()        Ttime = time.strftime("%Y%m%d")        Ytime = time.strftime("%Y%m%d",time.localtime((time.time() - 86400)))        for f  in os.listdir(backupPath):            if Ttime ==f.split('_')[0]:                ip = f.split('_')[1]                today_file[ip]=f            elif Ytime == f.split('_')[0]:                ip = f.split('_')[1]                ystday_file[ip] = f            else:                pass        # Read the latest IP list        backup_list = '/data0/backup_mysql.txt'        if not os.path.exists(backup_list):            utils.COMM("touch %s" %backup_list)        fp = open('/data0/backup_mysql.txt','r').readlines()        ips = [i.strip() for i in fp]        fail_ip = list()        done_ip = list()        # Call Func md5        for ip in ips:            if ip  in today_file:                if not self._checkMD5(backupPath,today_file[ip]):                    fail_ip.append(ip)                else:                    done_ip.append(ip)            else:                fail_ip.append(ip)        # Determine whether is empty,        # If not empty, calls the SendMail class        done_mes = str()        if done_ip:            for ip in done_ip:                done_mes += "host %s MySQL backup is successful \n" %ip        done_info = "\nBackup Successful: \n" + done_mes        ret = str()        if fail_ip:            for ip in fail_ip:                ret += "host %s MySQL backup is failure \n" %ip        mess = "\nPlease check the specific reason for the error \n" + "E-mail : 222@222.222.com, 3333@222.222.com,444@222.2222.com \n" + "Q Q : 11111,2222222,33333 "        back_time = "\nCheck Time: %s \n" %time.ctime()        mes = done_info  + "\nBackup Failure:\n"  + ret + back_time +  mess        send = SendMail()        # Subject        subject = "MySQL Backup %s information" %ipaddr()[1]        cc = '2222@222.222.com,333@222.222.com,444@222.222.com'        send.sendmail('kxbackup@163.com',subject,mes,cc='')    def _checkMD5(self,backupPath,files):        file = backupPath + '/' + files        try:            md5sun = file.split("_")[-1].split('.')[0]        except:            return False        fmd5sun = MD5(file)        if fmd5sun  == md5sun:            return True        else:            return False    def _get_file_ctime(self,f):        # return time stamp, YY-MM-DD        st_ctime = os.stat(f).st_mtime        return st_ctime , time.strftime('%Y%m%d',time.localtime(st_ctime))    def DeleteFile(self):        # Delete file from 8 day ago        reserve = '/data0/reserve/'        if not os.path.exists(reserve):            os.makedirs(reserve)        backuPath  = load_cfg()['yttx']['path']        keep_file = list()        delete_file = list()        os.chdir(backuPath)        ctimes = time.time()        keep_time  = 691200        for f in os.listdir(backuPath):            create_time = os.stat(f).st_ctime            if ctimes - create_time >= keep_time:                try:                    shutil.move(f,reserve)                except:                    shutil.move(f,'/dev/null')                logging('MySQL Check','INFO',"Delete file %s"%f)if __name__ == "__main__":    sc = CheckMySQL()    sc.checkRsyncConfig()    sc.checkFile()    sc.DeleteFile()