# -*- coding: utf-8 -*- from zipfile import ZipFile, ZIP_DEFLATED from datetime import datetime from os import walk, unlink, environ from os.path import join as osjoin from os.path import isfile from glob import glob from remote import sync # Backup plan for Docker volumes # :::::::::::::::::::::::::::::: # # Keep : # # - all saves the last week # - one save per week the last month # - one save per month during 6 months # Volumes Backup # ============== DEST = environ.get('DEST') dt = datetime.now() zipname = '{0}.zip'.format(dt.strftime('%Y-%m-%d_%Hh%Mm%Ss')) zippath = DEST + zipname # Zip files EXCLUDE_WORDS = environ.get('EXCLUDE_WORDS', False) if EXCLUDE_WORDS: EXCLUDE_WORDS = EXCLUDE_WORDS.split(',') def zipdir(path, ziph): # ziph is zipfile handle for root, dirs, files in walk(path): for file in files: pfile = osjoin(root, file) is_excluded = EXCLUDE_WORDS and any(map(lambda w: w in pfile, EXCLUDE_WORDS)) if (isfile(pfile) and not is_excluded): ziph.write(pfile) print('Compression started') f = ZipFile(zippath, 'w', ZIP_DEFLATED, allowZip64=True) zipdir('%s/volumes' % DEST, f) f.close() print('Compression ended') # Filter all obsolete save files # ============================== PLAN = environ.get('PLAN', u'180,15,2') PLAN = map(int, PLAN.split(u',')) def notkeep(fname): fname = fname.split('/')[-1] ds = fname.split('_') if len(ds) <= 1: return False ds = ds[0] d = datetime.strptime(ds, '%Y-%m-%d') delta = dt - d if delta.days > PLAN[0]: return True elif delta.days > PLAN[1]: if d.day != 1: return True elif delta.days > PLAN[2]: if (d.weekday() != 0) and (d.day != 1): return True else: return False # Filters zip files and keeps only legitimate ones # ================================================ files = glob('%s/*.zip' % DEST) backups_to_remove = filter(notkeep, files) if len(backups_to_remove) > 0: print('Save files outdated, will be deleted : \n\n* ' + '\n* '.join(backups_to_remove)) for b in backups_to_remove: unlink(b) sync()