Beispiel #1
0
def setup_path():
    """
    Lookup config file path
    """
    if HOLLANDCFG.lookup("holland.path"):
        os.putenv("PATH", HOLLANDCFG.lookup("holland.path"))
        os.environ["PATH"] = HOLLANDCFG.lookup("holland.path")
Beispiel #2
0
def setup_path():
    """
    Lookup config file path
    """
    if HOLLANDCFG.lookup('holland.path'):
        os.putenv('PATH', HOLLANDCFG.lookup('holland.path'))
        os.environ['PATH'] = HOLLANDCFG.lookup('holland.path')
Beispiel #3
0
def setup_path():
    """
    Lookup config file path
    """
    if HOLLANDCFG.lookup("holland.path"):
        os.putenv("PATH", HOLLANDCFG.lookup("holland.path"))
        os.environ["PATH"] = HOLLANDCFG.lookup("holland.path")
Beispiel #4
0
    def run(self, cmd, opts, *backups):
        error = 0

        if not backups:
            LOG.info("No backupsets specified - using backupsets from %s",
                     HOLLANDCFG.filename)
            backups = HOLLANDCFG.lookup("holland.backupsets")

        if not backups:
            LOG.warning("Nothing to purge")
            return 0

        if not opts.force:
            LOG.warning(
                "Running in dry-run mode.  Use --execute to do a real purge.")

        for name in backups:
            if "/" not in name:
                backupset = SPOOL.find_backupset(name)
                if not backupset:
                    LOG.error("Failed to find backupset '%s'", name)
                    error = 1
                    continue
                purge_backupset(backupset, opts.force, opts.all)
            else:
                backup = SPOOL.find_backup(name)
                if not backup:
                    LOG.error("Failed to find single backup '%s'", name)
                    error = 1
                    continue
                purge_backup(backup, opts.force)
                if opts.force:
                    SPOOL.find_backupset(backup.backupset).update_symlinks()
        return error
Beispiel #5
0
    def run(self, cmd, opts, *backups):
        error = 0

        if not backups:
            LOG.info("No backupsets specified - using backupsets from %s", HOLLANDCFG.filename)
            backups = HOLLANDCFG.lookup("holland.backupsets")

        if not backups:
            LOG.warning("Nothing to purge")
            return 0

        if not opts.force:
            LOG.warning("Running in dry-run mode.  Use --execute to do a real purge.")

        for name in backups:
            if "/" not in name:
                backupset = SPOOL.find_backupset(name)
                if not backupset:
                    LOG.error("Failed to find backupset '%s'", name)
                    error = 1
                    continue
                purge_backupset(backupset, opts.force, opts.all)
            else:
                backup = SPOOL.find_backup(name)
                if not backup:
                    LOG.error("Failed to find single backup '%s'", name)
                    error = 1
                    continue
                purge_backup(backup, opts.force)
                if opts.force:
                    SPOOL.find_backupset(backup.backupset).update_symlinks()
        return error
Beispiel #6
0
def purge_backupset(backupset, force=False, all_backups=False):
    """Purge a whole backupset either entirely or per the configured
    retention count

    :param backupset: Backupset object to purge
    :param force: Force the purge - this is not a dry-run
    :param all_backupsets: purge all backups regardless of configured
                           retention count
    """
    if all_backups:
        retention_count = 0
    else:
        try:
            config = HOLLANDCFG.backupset(backupset.name)
            config.validate_config(CONFIGSPEC, suppress_warnings=True)
        except (IOError, ConfigError) as exc:
            LOG.error("Failed to load backupset '%s': %s", backupset.name, exc)
            LOG.error("Aborting, because I could not tell how many backups to "
                      "preserve.")
            LOG.error("You can still purge the backupset by using the --all "
                      "option or specifying specific backups to purge")
        else:
            retention_count = config["holland:backup"]["backups-to-keep"]

            LOG.info("Evaluating purge for backupset %s", backupset.name)
            LOG.info("Retaining up to %d backup%s", retention_count,
                     "s"[0:bool(retention_count)])
            backups = []
            size = 0
            backup_list = backupset.list_backups(reverse=True)
            for backup in itertools.islice(backup_list, retention_count, None):
                backups.append(backup)
                config = backup.config["holland:backup"]
                size += int(config["on-disk-size"])

            LOG.info("    %d total backups", len(backup_list))
            for backup in backup_list:
                LOG.info("        * %s", backup.path)
            LOG.info("    %d backups to keep", len(backup_list) - len(backups))
            for backup in backup_list[0:-len(backups)]:
                LOG.info("        + %s", backup.path)
            LOG.info("    %d backups to purge", len(backups))
            for backup in backups:
                LOG.info("        - %s", backup.path)
            LOG.info("    %s total to purge", format_bytes(size))

            if force:
                count = 0
                for backup in backupset.purge(retention_count):
                    count += 1
                    LOG.info("Purged %s", backup.name)
                if count == 0:
                    LOG.info("No backups purged.")
                else:
                    LOG.info("Purged %d backup%s", count, "s"[0:bool(count)])
            else:
                LOG.info("Skipping purge in dry-run mode.")
            backupset.update_symlinks()
Beispiel #7
0
def purge_backupset(backupset, force=False, all_backups=False):
    """Purge a whole backupset either entirely or per the configured
    retention count

    :param backupset: Backupset object to purge
    :param force: Force the purge - this is not a dry-run
    :param all_backupsets: purge all backups regardless of configured
                           retention count
    """
    if all_backups:
        retention_count = 0
    else:
        try:
            config = HOLLANDCFG.backupset(backupset.name)
            config.validate_config(CONFIGSPEC, suppress_warnings=True)
        except (IOError, ConfigError) as exc:
            LOG.error("Failed to load backupset '%s': %s", backupset.name, exc)
            LOG.error("Aborting, because I could not tell how many backups to " "preserve.")
            LOG.error(
                "You can still purge the backupset by using the --all "
                "option or specifying specific backups to purge"
            )
        else:
            retention_count = config["holland:backup"]["backups-to-keep"]

            LOG.info("Evaluating purge for backupset %s", backupset.name)
            LOG.info("Retaining up to %d backup%s", retention_count, "s"[0 : bool(retention_count)])
            backups = []
            size = 0
            backup_list = backupset.list_backups(reverse=True)
            for backup in itertools.islice(backup_list, retention_count, None):
                backups.append(backup)
                config = backup.config["holland:backup"]
                size += int(config["on-disk-size"])

            LOG.info("    %d total backups", len(backup_list))
            for backup in backup_list:
                LOG.info("        * %s", backup.path)
            LOG.info("    %d backups to keep", len(backup_list) - len(backups))
            for backup in backup_list[0 : -len(backups)]:
                LOG.info("        + %s", backup.path)
            LOG.info("    %d backups to purge", len(backups))
            for backup in backups:
                LOG.info("        - %s", backup.path)
            LOG.info("    %s total to purge", format_bytes(size))

            if force:
                count = 0
                for backup in backupset.purge(retention_count):
                    count += 1
                    LOG.info("Purged %s", backup.name)
                if count == 0:
                    LOG.info("No backups purged.")
                else:
                    LOG.info("Purged %d backup%s", count, "s"[0 : bool(count)])
            else:
                LOG.info("Skipping purge in dry-run mode.")
            backupset.update_symlinks()
Beispiel #8
0
def setup_logging(opts):
    """
    Setup log file
    """
    clear_root_handlers()
    if hasattr(opts, "log_level"):
        log_level = opts.log_level or HOLLANDCFG.lookup("logging.level")
    else:
        log_level = HOLLANDCFG.lookup("logging.level")

    if not opts.quiet:
        setup_console_logging(level=log_level)

    if HOLLANDCFG.lookup("logging.filename"):
        try:
            if HOLLANDCFG.lookup("logging.format"):
                setup_file_logging(
                    filename=str(HOLLANDCFG.lookup("logging.filename")),
                    level=log_level,
                    msg_format=HOLLANDCFG.lookup(str("logging.format")),
                )
            else:
                setup_file_logging(
                    filename=str(HOLLANDCFG.lookup("logging.filename")), level=log_level
                )
        except IOError as exc:
            LOG.warning("Skipping file logging: %s", exc)
Beispiel #9
0
def setup_logging(opts):
    """
    Setup log file
    """
    clear_root_handlers()
    if hasattr(opts, "log_level"):
        log_level = opts.log_level or HOLLANDCFG.lookup("logging.level")
    else:
        log_level = HOLLANDCFG.lookup("logging.level")

    if not opts.quiet:
        setup_console_logging(level=log_level)

    if HOLLANDCFG.lookup("logging.filename"):
        try:
            if HOLLANDCFG.lookup("logging.format"):
                setup_file_logging(
                    filename=str(HOLLANDCFG.lookup("logging.filename")),
                    level=log_level,
                    msg_format=HOLLANDCFG.lookup(str("logging.format")),
                )
            else:
                setup_file_logging(filename=str(
                    HOLLANDCFG.lookup("logging.filename")),
                                   level=log_level)
        except IOError as exc:
            LOG.warning("Skipping file logging: %s", exc)
Beispiel #10
0
def bootstrap(opts):
    """
    Called by main() to setup everything
    """
    # Setup the configuration
    setup_config(opts)
    # use umask setting
    setup_umask()
    # Setup logging per config
    setup_logging(opts)
    # setup tmpdir
    if HOLLANDCFG.lookup("holland.tmpdir"):
        os.environ["TMPDIR"] = str(HOLLANDCFG.lookup("holland.tmpdir"))
    # configure our PATH
    setup_path()
    # Setup plugin directories
    setup_plugins()
    # Setup spool
    SPOOL.path = HOLLANDCFG.lookup("holland.backup-directory")
Beispiel #11
0
def bootstrap(opts):
    """
    Called by main() to setup everything
    """
    # Setup the configuration
    setup_config(opts)
    # use umask setting
    setup_umask()
    # Setup logging per config
    setup_logging(opts)
    # setup tmpdir
    if HOLLANDCFG.lookup("holland.tmpdir"):
        os.environ["TMPDIR"] = str(HOLLANDCFG.lookup("holland.tmpdir"))
    # configure our PATH
    setup_path()
    # Setup plugin directories
    setup_plugins()
    # Setup spool
    SPOOL.path = HOLLANDCFG.lookup("holland.backup-directory")
Beispiel #12
0
    def test_globalconfig(self):
        import logging
        cfgentry_tests = {
            'holland.plugin-dirs': ['/usr/share/holland/plugins'],
            'holland.umask': int('0007', 8),
            'holland.path':
            '/bin:/usr/bin:/usr/local/bin:/usr/local/sbin:/usr/local/mysql/bin',
            'logging.level': logging.INFO,
            'logging.filename': '/dev/null'
        }

        for key, value in list(cfgentry_tests.items()):
            self.assertEqual(HOLLANDCFG.lookup(key), value)
Beispiel #13
0
    def test_globalconfig(self):
        import logging
        cfgentry_tests = {
            'holland.plugin-dirs' : ['/usr/share/holland/plugins'],
            'holland.umask' : int('0007', 8),
            'holland.path' : '/bin:/usr/bin:/usr/local/bin:/usr/local/sbin:/usr/local/mysql/bin',

            'logging.level' : logging.INFO,
            'logging.filename' : '/dev/null'
        }

        for key, value in list(cfgentry_tests.items()):
            self.assertEqual(HOLLANDCFG.lookup(key), value)
Beispiel #14
0
    def run(self, cmd, opts, *backupsets):
        if not backupsets:
            backupsets = HOLLANDCFG.lookup("holland.backupsets")
            LOG.debug("No backupsets given. Using %r", backupsets)

        # strip empty items from backupsets list
        backupsets = [name for name in backupsets if name]

        if not backupsets:
            LOG.info("Nothing to backup")
            return 1

        runner = BackupRunner(SPOOL)

        # dry-run implies no-lock
        if opts.dry_run:
            opts.no_lock = True

        # don't purge if doing a dry-run, or when simultaneous backups may be running
        if not opts.no_lock:
            purge_mgr = PurgeManager()

            runner.register_cb("before-backup", purge_mgr)
            runner.register_cb("after-backup", purge_mgr)
            runner.register_cb("failed-backup", purge_backup)

        runner.register_cb("after-backup", report_low_space)

        if not opts.dry_run:
            runner.register_cb("before-backup", call_hooks)
            runner.register_cb("after-backup", call_hooks)
            runner.register_cb("failed-backup", call_hooks)

        error = 1
        LOG.info("--- Starting %s run ---", opts.dry_run and "dry" or "backup")
        for name in backupsets:
            try:
                config = HOLLANDCFG.backupset(name)
                # ensure we have at least an empty holland:backup section
                config.setdefault("holland:backup", {})
            except (SyntaxError, IOError) as exc:
                LOG.error("Could not load backupset '%s': %s", name, exc)
                break

            if not opts.no_lock:
                lock = Lock(config.filename)
                try:
                    lock.acquire()
                    LOG.debug("Set advisory lock on %s", lock.path)
                except LockError:
                    LOG.debug("Unable to acquire advisory lock on %s", lock.path)
                    LOG.error(
                        "Another holland backup process is already "
                        "running backupset '%s'. Aborting.",
                        name,
                    )
                    break

            try:
                try:
                    runner.backup(name, config, opts.dry_run)
                except BackupError as exc:
                    LOG.error("Backup failed: %s", exc.args[0])
                    break
                except ConfigError as exc:
                    break
            finally:
                if not opts.no_lock:
                    if lock.is_locked():
                        lock.release()
                    LOG.info("Released lock %s", lock.path)
        else:
            error = 0
        LOG.info("--- Ending %s run ---", opts.dry_run and "dry" or "backup")
        return error
Beispiel #15
0
def setup_plugins():
    """
    Setup plugins
    """
    for location in HOLLANDCFG.lookup("holland.plugin-dirs"):
        add_plugin_dir(location)
Beispiel #16
0
def setup_umask():
    """
    get file umask
    """
    os.umask(HOLLANDCFG.lookup("holland.umask"))
Beispiel #17
0
    def run(self, cmd, opts, *backupsets):
        if not backupsets:
            backupsets = HOLLANDCFG.lookup('holland.backupsets')

        # strip empty items from backupsets list
        backupsets = [name for name in backupsets if name]

        if not backupsets:
            LOG.info("Nothing to backup")
            return 1

        runner = BackupRunner(SPOOL)

        # dry-run implies no-lock
        if opts.dry_run:
            opts.no_lock = True

        # don't purge if doing a dry-run, or when simultaneous backups may be running
        if not opts.no_lock:
            purge_mgr = PurgeManager()

            runner.register_cb('before-backup', purge_mgr)
            runner.register_cb('after-backup', purge_mgr)
            runner.register_cb('failed-backup', purge_backup)

        runner.register_cb('after-backup', report_low_space)

        if not opts.dry_run:
            runner.register_cb('before-backup', call_hooks)
            runner.register_cb('after-backup', call_hooks)
            runner.register_cb('failed-backup', call_hooks)

        error = 1
        LOG.info("--- Starting %s run ---", opts.dry_run and 'dry' or 'backup')
        for name in backupsets:
            try:
                config = HOLLANDCFG.backupset(name)
                # ensure we have at least an empty holland:backup section
                config.setdefault('holland:backup', {})
            except (SyntaxError, IOError) as exc:
                LOG.error("Could not load backupset '%s': %s", name, exc)
                break

            if not opts.no_lock:
                lock = Lock(config.filename)
                try:
                    lock.acquire()
                    LOG.debug("Set advisory lock on %s", lock.path)
                except LockError:
                    LOG.debug("Unable to acquire advisory lock on %s",
                              lock.path)
                    LOG.error(
                        "Another holland backup process is already "
                        "running backupset '%s'. Aborting.", name)
                    break

            try:
                try:
                    runner.backup(name, config, opts.dry_run)
                except BackupError as exc:
                    LOG.error("Backup failed: %s", exc.args[0])
                    break
                except ConfigError as exc:
                    break
            finally:
                if not opts.no_lock:
                    if lock.is_locked():
                        lock.release()
                    LOG.info("Released lock %s", lock.path)
        else:
            error = 0
        LOG.info("--- Ending %s run ---", opts.dry_run and 'dry' or 'backup')
        return error
Beispiel #18
0
def setup_plugins():
    """
    Setup plugins
    """
    for location in HOLLANDCFG.lookup("holland.plugin-dirs"):
        add_plugin_dir(location)
Beispiel #19
0
def setup_umask():
    """
    get file umask
    """
    os.umask(HOLLANDCFG.lookup("holland.umask"))