示例#1
0
 def _get_capacity_value(self, section, section_name):
     s = self._required_value(section, section_name, 'Capacity')
     m = self.CAPA_RE.match(s)
     if not m:
         raise BackupError('Configuration file section "{}" has bad '
                           'Capacity value "{}": must match /^{}/'.format(
                               section_name, s, self.CAPA_RE.pattern))
     return int(s[:-1]) * self.CAPA_SUFFIX_FACTORS[s[-1].lower()]
示例#2
0
def rmpolicy_by_name(name):
    pol = None
    if name == 'oldest': pol = OldestPolicy()
    elif name == 'thinning': pol = ThinningPolicy()
    elif name == 'never': pol = NeverPolicy()
    else:
        raise BackupError('Invalid removal policy: "{}"'.format(name))
    pol.name = name
    return pol
示例#3
0
    def __init__(self, filename):
        if not os.path.exists(filename):
            raise BackupError(
                'Configuration file {} does not exist'.format(filename))

        parser = configparser.ConfigParser()
        parser['DEFAULT'] = {
            'FullBackupsInterval': 'monthly',
            'IncrBackupsInterval': 'daily',
            'RemovalPolicy': 'thinning',
            'IgnoreChangingFiles': False,
            'LogsBackupCount': 60
        }

        parser.read(filename)

        self.instances = []

        for section_name, section in parser.items():
            if section_name == 'DEFAULT': continue
            if not section_name.lower().startswith('backup '):
                raise BackupError(
                    'Configuration file section name "{}" is '
                    'invalid: must begin with "Backup "'.format(section_name))
            cfg = _ConfigInstance()
            cfg.name = section_name[7:]
            cfg.dest_dir = self._required_value(section, section_name,
                                                'DestinationDir')
            cfg.dar_args = self._get_dar_args(section, section_name)
            cfg.capacity = self._get_capacity_value(section, section_name)
            cfg.full_intvl = schedules.schedule_by_name(
                section['FullBackupsInterval'])
            cfg.incr_intvl = schedules.schedule_by_name(
                section['IncrBackupsInterval'])
            cfg.rmpolicy = rmpolicies.rmpolicy_by_name(
                section['RemovalPolicy'])
            cfg.ignore_changing_files = self._bool_value(
                section, section_name, 'IgnoreChangingFiles')
            cfg.logfilename = section.get('LogfileName')
            cfg.logsbackupcount = int(section.get('LogsBackupCount'))
            self.instances.append(cfg)
示例#4
0
 def _bool_value(self, section, section_name, name):
     value = section[name]
     if isinstance(value, bool): return value
     v = value.lower()
     if v in ('1', 'yes', 'true', 'on'):
         return True
     elif v in ('0', 'no', 'false', 'off'):
         return False
     else:
         raise BackupError('Configuration file section "{}" setting "{}" '
                           'is not a valid boolean value'.format(
                               section_name, name))
示例#5
0
 def __init__(self, name, path):
     self._name = name
     self._basedir = path
     archives = []
     for fn in os.listdir(path):
         archive = self._archive_at_path(fn)
         if archive:
             logging.debug('Found existing archive {}'.format(fn))
             archives.append(archive)
     archives.sort(key=attrgetter('timestamp'))
     if len(archives) > 0 and archives[0].is_incremental:
         raise BackupError('Oldest archive {} is incremental'.format(
             archive.path()))
     self._first = None
     self._last = None
     self._count = 0
     self._total_size = 0
     for arc in archives:
         self._append(arc)
示例#6
0
def run(cfg, force_full, force_incr):
    clean_parts(cfg.dest_dir)
    now = datetime.datetime.now()
    arcset = ArchiveSet(cfg.name, cfg.dest_dir)

    if force_incr:
        if not arcset:
            raise BackupError('Cannot run incremental backup: no archives '
                              'exist yet')
        backup(True, cfg, now, arcset)
    elif force_full or not arcset:
        backup(False, cfg, now, arcset)
    else:
        latest_time = arcset.latest().timestamp
        if cfg.full_intvl(latest_time, now):
            backup(False, cfg, now, arcset)
        elif cfg.incr_intvl(latest_time, now):
            backup(True, cfg, now, arcset)
        else:
            logging.debug('Not time for next backup yet: ' + cfg.name)
示例#7
0
 def __call__(self, arcset, now):
     # Don't just return None, because that causes the cleaner to throw a
     # NoRemovalCandidatesError, which may result in a retry after deleting
     # the current archive.  We don't want that -- we want to give up
     # immediately.
     raise BackupError('No more disk space is available')
示例#8
0
 def _required_value(self, section, section_name, name):
     if name not in section:
         raise BackupError('Configuration file section "{}" is missing '
                           'required setting "{}"'.format(
                               section_name, name))
     return section[name]
示例#9
0
def schedule_by_name(name):
    sched = getattr(Schedules, name, None)
    if sched: return sched
    raise BackupError('Invalid backup schedule: "{}"'.format(name))