# 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 smtplib import os,sys,time,fcntl,struct import ConfigParser import commands import traceback import socket import shutil import sys import re try: from email.mime.multipart import MIMEMultipart except: from email.MIMEMultipart import MIMEMultipart try: from email.mime.text import MIMEText except: from email.MIMEText import MIMEText try: from hashlib import md5 except: from md5 import md5 CONFIG_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 rst def 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 IP def 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 1 class SendMail(object): def __init__ (self): self.smtpserver = 'smtp.163.com' self.fro = '[email protected]' self.c_code = 'UTF-8' self.port = 25 self.auth = '[email protected]' 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 : [email protected], [email protected],[email protected] \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 = '[email protected],[email protected],[email protected]' send.sendmail('[email protected]',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()