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")
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')
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
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
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()
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()
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)
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)
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")
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)
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)
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
def setup_plugins(): """ Setup plugins """ for location in HOLLANDCFG.lookup("holland.plugin-dirs"): add_plugin_dir(location)
def setup_umask(): """ get file umask """ os.umask(HOLLANDCFG.lookup("holland.umask"))
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