def _decorator( self, *args, **kwargs): if not self.config_file: raise CentrifugeFatalError('Configuration file required for this command') self.config = BackupConfig(self.config_file) self.config.check_services(self.supported_services()) func(self,*args, **kwargs)
def list_backups(self,*args,**kwargs): """ List the configured backups that we know about. """ print("Configured Backups") for config in self.config.iterconfig(): print(config[0]) print("="*len(config[0])) print(BackupConfig.prettyprint(config[1])) print("")
class Centrifuge(object): DATA_DIR = "/var/lib/centrifuge" DEFAULT_SERVICES = [(service,pkg_resources.resource_string(__name__,"data/services/{0}".format(service))) for service in pkg_resources.resource_listdir(__name__,"data/services") ] ADDL_SERVICE_DIRS = [ os.path.expanduser("~/.centrifuge/services"), "/etc/centrifuge/services" ] USER_SPEC_DIR = os.path.expanduser("~/.centrifuge") STATEFILE = "{0}/state".format(DATA_DIR) TIMEDELTAS = { 'daily': datetime.timedelta(days=1), 'weekly': datetime.timedelta(days=7), 'monthly': datetime.timedelta(days=30) } def config_required(func): def _decorator( self, *args, **kwargs): if not self.config_file: raise CentrifugeFatalError('Configuration file required for this command') self.config = BackupConfig(self.config_file) self.config.check_services(self.supported_services()) func(self,*args, **kwargs) return _decorator @classmethod def _userpath(cls,path): return "{0}/{1}".format(cls.USER_SPEC_DIR,path) def supported_services(self,printout=False): if printout: print("Supported Services:") for srv in self.services.itervalues(): print(" - {0}\n".format(srv.name)) return [srv.name for srv in self.services.itervalues()] def __init__(self): self._setup_datadir() @config_required def run_backups(self,*args,**kwargs): cm_args = kwargs['args'] success = [] for backup in cm_args.backup_name: log.info("Running backup '{0}'".format(backup)) success.append(self.run_backup(backup)) if not success[-1]: log.info("'{0}' was not completely successful".format(backup)) return all(success) def run_backup(self,backup_name): try: backup_config = self.config[backup_name] except KeyError as e: log.warn("No configured backup with name '{0}'".format(backup_name)) else: try: backup_state = self.state[backup_name] except KeyError: self.state[backup_name] = state.State(backup_name) backup_state = self.state[backup_name] bservice = self.services[ backup_config['service'] ] ok_daily = self.try_backup(bservice,backup_config,backup_state,"daily") ok_weekly = self.try_backup(bservice,backup_config,backup_state,"weekly") ok_monthly = self.try_backup(bservice,backup_config,backup_state,"monthly") with open(self.STATEFILE,'w') as statef: yaml.dump(self.state,statef) return all((ok_monthly,ok_daily,ok_weekly)) def try_backup(self,bservice, bconfig,bstate,interval): """ Attempt to perform a backup at interval. Fail if you shouldn't """ latest_key = "last_{0}".format(interval) try: latest_created = bstate[latest_key].date_created except KeyError: latest_created = datetime.date(year=1900,month=1,day=1) if (datetime.date.today() - latest_created) >= self.TIMEDELTAS[interval]: if len(bstate[interval]) > bconfig[interval]: okay = bservice.trim(interval,bstate) elif len(bstate[interval]) == bconfig[interval]: okay = bservice.rotate(interval,bstate,bconfig['files']) else: okay = bservice.add(interval,bstate,bconfig['files']) else: okay = True log.info("Skipping '{0}' interval. It's only been {1}".format( interval, datetime.date.today() - latest_created)) return okay def _setup_datadir(self): """ Setup the /var/lib/centrifuge data directory and load our state file. """ log.debug("Setting up data directory '{0}'".format(self.DATA_DIR)) if not os.path.exists(self.DATA_DIR): try: os.makedirs(self.DATA_DIR) except OSError,e: raise CentrifugeFatalError("Unable to create data directory: {0}".format(e[1])) self.state = state.State.ParseFile(self.STATEFILE)
from config import BackupConfig import asyncio import logging from distutils.dir_util import copy_tree, remove_tree from datetime import date import os from time import time from distutils.errors import DistutilsFileError from multiprocessing import Process from lib import getRemovablesByDate, getDateObjectFromString path = os.getcwd() settings = BackupConfig() today = time() def backup(): newPath = f"{settings.output}/backup_{today.__str__()}" copy_tree(settings.input, newPath) print(f"Backupping from {settings.input} to {newPath}") def clean(): print("Cleaning up backup folder") removables = getRemovablesByDate(settings.output) for removable in removables: p = f"{settings.output}\{removable['path']}" remove_tree(p) print("Clean up done.") #TODO: Test for missing config options and bad filepaths.