예제 #1
0
    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)
예제 #2
0
 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("")
예제 #3
0
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)
예제 #4
0
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.