tar-back is a backup utility to tar and gzip target filesystems.
It supports a custom retention, filter exclusions, and backup
directory.
I use tar-back in combination with cron to perform regular backups of all localhost filesystems into /archive/fs. I then have a central long term storage server that collects the /archive partition from every host.
tar-back:
#!/usr/bin/env python DESCRIPTION = """A backup utility to tar and gzip target filesystems. Custom retention, filter exclusions and backup directory. """ from os import path from sys import exit from shutil import move from optparse import OptionParser import tarfile def filter_exclusions( tarinfo ): """Accept tarinfo, return tarinfo or None""" if o.filters: for filtr in o.filters: if filtr in tarinfo.name: return None return tarinfo def exclude_exclusions( filename ): """Accept filename, return True or False""" """support for python 2.6 or lower""" if o.filters: for filtr in o.filters: if filtr in filename: return True return False def file_rotate( target, retention = 3 ): """file rotation routine""" for i in range( retention-2, 0, -1 ): # count backwards old_name = "%s.%s" % ( target, i ) new_name = "%s.%s" % ( target, i + 1 ) try: move( old_name, new_name ) except IOError: pass move( target, target + '.1' ) if __name__ == '__main__': p = OptionParser() # create an option parser object p.set_description( DESCRIPTION ) p.add_option( '-t', '--targets', help='list of target filesystems to backup (coma delimited)', default=None, dest='targets', metavar='"/home"', ) p.add_option( '-b', '--backup-dir', help='path to backup directory', dest='backdir', metavar='"PATH"', ) p.add_option( '-f', '--filters', help='list of filter patterns to exclude (coma delimited)', default=None, dest='filters', metavar='".mp3"', ) p.add_option( '-r', '--retention', help='backups to retain [default: 3]', default=3, type='int', dest='retention', metavar='amount', ) o, args = p.parse_args() # parse options and args extension = '.tar.gz' if not o.targets: exit( "missing filesystem target, run --help" ) if not o.backdir: exit( "missing backup directory, run --help" ) if not path.isdir( o.backdir ): exit( "backup-dir %s does not exist" % o.backdir ) if o.filters: o.filters = o.filters.split(',') o.targets = o.targets.split(',') for target in o.targets: slug = target.replace( '/', '-' ).lstrip( '-' ) # change / to - if slug == '': slug = 'r' # / slug is empty (root) tarpath = path.join( o.backdir, slug + extension ) if path.isfile( tarpath ): file_rotate( tarpath, o.retention ) tar = tarfile.open( tarpath, 'w:gz' ) try: tar.add( target, filter=filter_exclusions ) except TypeError: tar.add( target, exclude=exclude_exclusions ) tar.close()