Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
#!/usr/bin/python
#Author: Jelle Bekker
#Base for this script was created by: Andrew McDonald andrew@mcdee.com.au http://mcdee.com.au
# Example: config file
#[client]
#host = localhost
#user = root
#password = root-pass
#For parameter usage, use the -h parameter
from datetime import datetime
import argparse
import os
import subprocess
import sys
import tarfile
import time
def is_dir(path):
"""Checks if a path is an actual directory"""
if not os.path.isdir(path):
msg = "{0} is not a directory".format(path)
raise argparse.ArgumentTypeError(msg)
else:
return path
def is_file(path):
"""Checks if a path is a valid file"""
if not os.path.isfile(path):
msg = "{0} is not a valid file".format(path)
raise argparse.ArgumentTypeError(msg)
else:
return path
def get_args():
parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument('--cnf', action='store', type=is_file, required=True, help=
("Path to a config file with the following contents:\n"
"\n"
"[client]\n"
"user = [root]\n"
"password = [root-pass]\n"
"host = [localhost]\n")
)
parser.add_argument('--backup-directory', type=is_dir, required=True, help='Target directory for the backup')
parser.add_argument('--compress', action='store_true', help='Compress the backup files')
parser.add_argument('--age', type=int, help='Delete backup files older than the specified amount of days')
return parser.parse_args()
def set_permissions(path, permissions=0640):
return os.chmod(path, permissions)
def mysql_dblist(cnf):
ignore_db = ['information_schema', 'performance_schema', 'test']
cmd = ['mysql', '--defaults-extra-file='+cnf, '-se', 'show databases']
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
if p.returncode >0:
print "MySQL Error:"
print stderr
sys.exit(1)
dblist = stdout.strip().split('\n')
for item in ignore_db:
try:
dblist.remove(item)
except ValueError:
continue
if len(dblist) == 0:
print "Doesn't appear to be any user databases found"
return dblist
def mysql_backup(dblist, cnf, dir, compress):
for db in dblist:
bdate = datetime.now().strftime('%Y%m%d%H%M')
bfile = db+'_'+bdate+'.sql'
fullpath = os.path.join(dir, bfile)
dumpfile = open(fullpath, 'w')
set_permissions(fullpath)
if db == 'mysql':
cmd = ['mysqldump', '--defaults-extra-file='+cnf, '--events', db]
else:
cmd = ['mysqldump', '--defaults-extra-file='+cnf, db]
p = subprocess.Popen(cmd, stdout=dumpfile)
retcode = p.wait()
dumpfile.close()
if retcode > 0:
print 'Error:', db, 'backup error'
if compress:
backup_compress(fullpath, bfile)
def backup_compress(path, bfile):
try:
tar = tarfile.open(path+'.tar.gz', 'w:gz')
tar.add(path, arcname=bfile)
tar.close()
set_permissions(path+'.tar.gz')
except Exception as e:
print 'Error compressing {0} ({1}): {2}'.format(path, e.errno, e.strerror)
os.remove(path)
def cleanup_files(path, age):
if age is not None:
now = time.time()
for bf in os.listdir(path):
f = os.path.join(path, bf)
if os.stat(f).st_mtime < now - age * 86400 and os.path.isfile(f):
try:
os.remove(f)
except IOError as e:
print "I/O error({0}): {1}".format(e.errno, e.strerror)
def main():
args = get_args()
db_list = mysql_dblist(args.cnf)
mysql_backup(db_list, args.cnf, args.backup_directory, args.compress)
cleanup_files(args.backup_directory, args.age)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment