docker_images/backups/rsyncvolumes/plan.py

88 lines
2.1 KiB
Python

# -*- 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()