예제 #1
0
    def backup(self, name, config, dry_run=False):
        """Run a backup for the named backupset using the provided
        configuration

        :param name: name of the backupset
        :param config: dict-like object providing the backupset configuration

        :raises: BackupError if a backup fails
        """
        for i in range(MAX_SPOOL_RETRIES):
            try:
                spool_entry = self.spool.add_backup(name)
                break
            except OSError as exc:
                if exc.errno != errno.EEXIST:
                    raise BackupError("Failed to create spool: %s" % exc)
                LOG.debug("Failed to create spool.  Retrying in %d seconds.", i + 1)
                time.sleep(i + 1)
        else:
            raise BackupError("Failed to create a new backup directory for %s" % name)

        spool_entry.config.merge(config)
        spool_entry.validate_config()

        if dry_run:
            # always purge the spool
            self.register_cb("post-backup", lambda *args, **kwargs: spool_entry.purge())

        plugin = load_plugin(name, spool_entry.config, spool_entry.path, dry_run)

        spool_entry.config["holland:backup"]["start-time"] = time.time()
        spool_entry.flush()
        self.apply_cb("before-backup", spool_entry)
        spool_entry.config["holland:backup"]["failed"] = False

        try:
            estimated_size = self.check_available_space(plugin, spool_entry, dry_run)
            LOG.info(
                "Starting backup[%s] via plugin %s",
                spool_entry.name,
                spool_entry.config["holland:backup"]["plugin"],
            )
            plugin.backup()
        except KeyboardInterrupt:
            LOG.warning("Backup aborted by interrupt")
            spool_entry.config["holland:backup"]["failed"] = True
            raise
        except BaseException as ex:
            LOG.warning(ex)
            spool_entry.config["holland:backup"]["failed"] = True

        spool_entry.config["holland:backup"]["stop-time"] = time.time()
        if not dry_run and not spool_entry.config["holland:backup"]["failed"]:
            final_size = float(directory_size(spool_entry.path))
            LOG.info("Final on-disk backup size %s", format_bytes(final_size))
            if estimated_size > 0:
                LOG.info(
                    "%.2f%% of estimated size %s",
                    (final_size / estimated_size) * 100.0,
                    format_bytes(estimated_size),
                )

            spool_entry.config["holland:backup"]["on-disk-size"] = final_size
            spool_entry.flush()

        start_time = spool_entry.config["holland:backup"]["start-time"]
        stop_time = spool_entry.config["holland:backup"]["stop-time"]

        if spool_entry.config["holland:backup"]["failed"]:
            LOG.error("Backup failed after %s", format_interval(stop_time - start_time))
        else:
            LOG.info("Backup completed in %s", format_interval(stop_time - start_time))

        if dry_run:
            spool_entry.purge()

        if sys.exc_info() != (None, None, None) or spool_entry.config["holland:backup"]["failed"]:
            LOG.debug("sys.exc_info(): %r", sys.exc_info())
            self.apply_cb("failed-backup", spool_entry)
            raise BackupError("Failed backup: %s" % name)
        else:
            self.apply_cb("after-backup", spool_entry)
예제 #2
0
파일: base.py 프로젝트: chder/holland
            final_size = float(directory_size(spool_entry.path))
            LOG.info("Final on-disk backup size %s", format_bytes(final_size))
            if estimated_size > 0:
                LOG.info("%.2f%% of estimated size %s",
                     (final_size / estimated_size)*100.0,
                     format_bytes(estimated_size))

            spool_entry.config['holland:backup']['on-disk-size'] = final_size
            spool_entry.flush()

        start_time = spool_entry.config['holland:backup']['start-time']
        stop_time = spool_entry.config['holland:backup']['stop-time']

        if spool_entry.config['holland:backup']['failed']:
            LOG.error("Backup failed after %s",
                      format_interval(stop_time - start_time))
        else:
            LOG.info("Backup completed in %s",
                     format_interval(stop_time - start_time))


        if dry_run:
            spool_entry.purge()

        if sys.exc_info() != (None, None, None):
            self.apply_cb('failed-backup', spool_entry)
            raise
        else:
            self.apply_cb('after-backup', spool_entry)

    def free_required_space(self, name, required_bytes, dry_run=False):
예제 #3
0
                    backupset_cfg.lookup('holland:backup.plugin'))
        plugin.backup()
    except KeyboardInterrupt:
        exc = BackupError("Interrupted")
    except Exception, exc:
        if not isinstance(exc, BackupError):
            LOGGER.debug("Unexpected exception when running backups.",
                         exc_info=True)
            exc = BackupError(exc)

    backup_job.config['holland:backup']['stop-time'] = time.time()
    backup_interval = (backup_job.config['holland:backup']['stop-time'] -
                       backup_job.config['holland:backup']['start-time'])
    if dry_run:
        LOGGER.info("Dry-run completed in %s",
                    format_interval(backup_interval))
    else:
        LOGGER.info("Backup completed in %s", format_interval(backup_interval))

    if not dry_run and exc is None:
        final_size = directory_size(backup_job.path)
        LOGGER.info(
            "Final on-disk backup size: %s %.2f%% of estimated size %s",
            format_bytes(final_size),
            estimated_size and 100 * (float(final_size) / estimated_size)
            or 0.0, format_bytes(estimated_size))
        backup_job.config['holland:backup']['on-disk-size'] = final_size
        LOGGER.debug("Flushing backup job")
        backup_job.flush()

    if exc is not None:
예제 #4
0
    def backup(self, name, config, dry_run=False):
        """Run a backup for the named backupset using the provided
        configuration

        :param name: name of the backupset
        :param config: dict-like object providing the backupset configuration

        :raises: BackupError if a backup fails
        """
        for i in range(MAX_SPOOL_RETRIES):
            try:
                spool_entry = self.spool.add_backup(name)
                break
            except OSError as exc:
                if exc.errno != errno.EEXIST:
                    raise BackupError("Failed to create spool: %s" % exc)
                LOG.debug("Failed to create spool.  Retrying in %d seconds.", i + 1)
                time.sleep(i + 1)
        else:
            raise BackupError("Failed to create a new backup directory for %s" % name)

        spool_entry.config.merge(config)
        spool_entry.validate_config()

        if dry_run:
            # always purge the spool
            self.register_cb("post-backup", lambda *args, **kwargs: spool_entry.purge())

        plugin = load_plugin(name, spool_entry.config, spool_entry.path, dry_run)

        spool_entry.config["holland:backup"]["start-time"] = time.time()
        spool_entry.flush()
        self.apply_cb("before-backup", spool_entry)
        spool_entry.config["holland:backup"]["failed"] = False

        try:
            estimated_size = self.check_available_space(plugin, spool_entry, dry_run)
            LOG.info(
                "Starting backup[%s] via plugin %s",
                spool_entry.name,
                spool_entry.config["holland:backup"]["plugin"],
            )
            plugin.backup()
        except KeyboardInterrupt:
            LOG.warning("Backup aborted by interrupt")
            spool_entry.config["holland:backup"]["failed"] = True
            raise
        except BaseException as ex:
            LOG.warning(ex)
            spool_entry.config["holland:backup"]["failed"] = True

        spool_entry.config["holland:backup"]["stop-time"] = time.time()
        if not dry_run and not spool_entry.config["holland:backup"]["failed"]:
            final_size = float(directory_size(spool_entry.path))
            LOG.info("Final on-disk backup size %s", format_bytes(final_size))
            if estimated_size > 0:
                LOG.info(
                    "%.2f%% of estimated size %s",
                    (final_size / estimated_size) * 100.0,
                    format_bytes(estimated_size),
                )

            spool_entry.config["holland:backup"]["on-disk-size"] = final_size
            spool_entry.flush()

        start_time = spool_entry.config["holland:backup"]["start-time"]
        stop_time = spool_entry.config["holland:backup"]["stop-time"]

        if spool_entry.config["holland:backup"]["failed"]:
            LOG.error("Backup failed after %s", format_interval(stop_time - start_time))
        else:
            LOG.info("Backup completed in %s", format_interval(stop_time - start_time))

        if dry_run:
            spool_entry.purge()

        if sys.exc_info() != (None, None, None) or spool_entry.config["holland:backup"]["failed"]:
            LOG.debug("sys.exc_info(): %r", sys.exc_info())
            self.apply_cb("failed-backup", spool_entry)
            raise BackupError("Failed backup: %s" % name)
        else:
            self.apply_cb("after-backup", spool_entry)
예제 #5
0
                    backup_job.name,
                    backupset_cfg.lookup('holland:backup.plugin'))
        plugin.backup()
    except KeyboardInterrupt:
        exc = BackupError("Interrupted")
    except Exception, exc:
        if not isinstance(exc, BackupError):
            LOGGER.debug("Unexpected exception when running backups.", exc_info=True)
            exc = BackupError(exc)

    backup_job.config['holland:backup']['stop-time'] = time.time()
    backup_interval = (backup_job.config['holland:backup']['stop-time'] -
                       backup_job.config['holland:backup']['start-time'])
    if dry_run:
        LOGGER.info("Dry-run completed in %s",
                    format_interval(backup_interval))
    else:
        LOGGER.info("Backup completed in %s", 
                    format_interval(backup_interval))

    if not dry_run and exc is None:
        final_size = directory_size(backup_job.path)
        LOGGER.info("Final on-disk backup size: %s %.2f%% of estimated size %s", 
                    format_bytes(final_size), 
                    estimated_size and 100*(float(final_size)/estimated_size) or 0.0,
                    format_bytes(estimated_size))
        backup_job.config['holland:backup']['on-disk-size'] = final_size
        LOGGER.debug("Flushing backup job")
        backup_job.flush()

    if exc is not None:
예제 #6
0
            final_size = directory_size(spool_entry.path)
            LOG.info("Final on-disk backup size %s", format_bytes(final_size))
            if estimated_size > 0:
                LOG.info("%.2f%% of estimated size %s",
                     (float(final_size) / estimated_size)*100.0,
                     format_bytes(estimated_size))

            spool_entry.config['holland:backup']['on-disk-size'] = final_size
            spool_entry.flush()

        start_time = spool_entry.config['holland:backup']['start-time']
        stop_time = spool_entry.config['holland:backup']['stop-time']

        if spool_entry.config['holland:backup']['failed']:
            LOG.error("Backup failed after %s",
                      format_interval(stop_time - start_time))
        else:
            LOG.info("Backup completed in %s",
                     format_interval(stop_time - start_time))


        if dry_run:
            spool_entry.purge()

        if sys.exc_info() != (None, None, None):
            self.apply_cb('failed-backup', spool_entry)
            raise
        else:
            self.apply_cb('after-backup', spool_entry)

    def check_available_space(self, plugin, dry_run=False):
예제 #7
0
파일: backup.py 프로젝트: jschairb/holland
                    break
        finally:
            if not opts.no_lock:
                try:
                    fcntl.flock(config_file, fcntl.LOCK_UN)
                except OSError, exc:
                    LOGGER.debug("Error when releasing backup lock: %s", exc)
                    pass

        if not error_found:
            LOGGER.info("All backupsets run successfully")
        else:
            LOGGER.info("One or more backupsets failed to run successfully")
        LOGGER.info("This backup run of %d backupset%s took %s",
                    len(backupsets), ('','s')[len(backupsets) > 1],
                    format_interval(time.time() - start_time))
        LOGGER.info("-----> Ending backup run <----")
        return error_found


def run_backup(jobname, dry_run=False):
    try:
        backup(jobname, dry_run)
    except KeyboardInterrupt, e:
        LOGGER.info("Interrupt")
    except BackupError, exc:
        LOGGER.error("Backup %r failed: %s", jobname, exc)
    except Exception, exc:
        LOGGER.error("Unexpected exception caught.  This is probably "
                     "a bug.  Please report to the holland "
                     "development team.", exc_info=True)