Skip to content

Commit

Permalink
cleanup multiple archives in one go
Browse files Browse the repository at this point in the history
  • Loading branch information
per2jensen committed Aug 20, 2024
1 parent 245e84d commit 7230230
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 18 deletions.
2 changes: 1 addition & 1 deletion v2/src/dar_backup/__about__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.5.13"
__version__ = "0.5.14"
35 changes: 19 additions & 16 deletions v2/src/dar_backup/cleanup.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def delete_old_backups(backup_dir, age, backup_type, backup_definition=None):
logger.error(f"Error deleting file {file_path}: {e}")


def delete_archives(backup_dir, archive_name):
def delete_archive(backup_dir, archive_name):
"""
Delete all .dar and .par2 files in the backup directory for the given archive name.
Expand Down Expand Up @@ -122,13 +122,13 @@ def main():

global logger

parser = argparse.ArgumentParser(description="Cleanup old backup files.")
parser.add_argument('--backup-definition', '-d', help="Specific backup definition to clean.")
parser.add_argument('--config-file', '-c', type=str, help="Path to 'dar-backup.conf'", default='~/.config/dar-backup/dar-backup.conf')
parser.add_argument('--version', '-v', action='store_true', help="Show version information.")
parser = argparse.ArgumentParser(description="Cleanup old archives according to AGE configuration.")
parser.add_argument('-d', '--backup-definition', help="Specific backup definition to cleanup.")
parser.add_argument('-c', '--config-file', '-c', type=str, help="Path to 'dar-backup.conf'", default='~/.config/dar-backup/dar-backup.conf')
parser.add_argument('-v', '--version', action='store_true', help="Show version information.")
parser.add_argument('--alternate-archive-dir', type=str, help="Cleanup in this directory instead of the default one.")
parser.add_argument('--cleanup-specific-archive', type=str, help="Force delete all .dar and .par2 files in the backup directory for given archive name")
parser.add_argument('--list', action='store_true', help="List available archives.")
parser.add_argument('--cleanup-specific-archive', type=str, help="List of archives to cleanup")
parser.add_argument('-l', '--list', action='store_true', help="List available archives.")
parser.add_argument('--verbose', action='store_true', help="Print various status messages to screen")
args = parser.parse_args()

Expand All @@ -151,13 +151,12 @@ def main():
logger.debug(f"`config_settings`:\n{config_settings}")

current_dir = os.path.normpath(os.path.dirname(__file__))
args.verbose and (print(f"Current directory: {current_dir}"))
args.verbose and (print(f"Config file: {args.config_file}"))
args.verbose and (print(f"Backup dir: {config_settings.backup_dir}"))
args.verbose and (print(f"Logfile location: {config_settings.logfile_location}"))
args.verbose and (print(f"--alternate-archive-dir: {args.alternate_archive_dir}"))
args.verbose and (print(f"--cleanup-specific-archive: {args.cleanup_specific_archive}"))

args.verbose and (print(f"Script directory: {current_dir}"))
args.verbose and (print(f"Config file: {args.config_file}"))
args.verbose and (print(f"Backup dir: {config_settings.backup_dir}"))
args.verbose and (print(f"Logfile location: {config_settings.logfile_location}"))
args.verbose and (print(f"--alternate-archive-dir: {args.alternate_archive_dir}"))
args.verbose and (print(f"--cleanup-specific-archive: {args.cleanup_specific_archive}"))

# run PREREQ scripts
if 'PREREQ' in config_settings.config:
Expand All @@ -178,9 +177,13 @@ def main():
if args.alternate_archive_dir:
config_settings.backup_dir = args.alternate_archive_dir


if args.cleanup_specific_archive:
delete_archives(config_settings.backup_dir, args.cleanup_specific_archive)
sys.exit(0)
print(f"Cleaning up specific archives: {args.cleanup_specific_archive}")
archive_names = args.cleanup_specific_archive.split(',')
for archive_name in archive_names:
print(f"Deleting archive: {archive_name}")
delete_archive(config_settings.backup_dir, archive_name.strip())
elif args.list:
list_backups(config_settings.backup_dir, args.backup_definition)
else:
Expand Down
64 changes: 63 additions & 1 deletion v2/tests/test_cleanup.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,66 @@ def test_cleanup_functionality(setup_environment, env):
assert (os.path.exists(os.path.join(env.test_dir, 'backups', f'example_INCR_{date_10_days_ago}.1.dar'))), f"File {os.path.join(env.test_dir, 'backups', f'example_INCR_{date_10_days_ago}.1.dar')} does not exist"


def test_cleanup_specific_archive(setup_environment, env):
def test_cleanup_specific_archives(setup_environment, env):
"""
Verify that the cleanup script can delete multiple specific archives
"""
test_files = {
f'specific_FULL_{date_100_days_ago}.1.dar': 'dummy',
f'specific_FULL_{date_100_days_ago}.1.dar.vol001.par2': 'dummy',
f'specific_FULL_{date_100_days_ago}.1.dar.par2': 'dummy',
f'specific_FULL_{date_100_days_ago}.2.dar': 'dummy',
f'specific_FULL_{date_100_days_ago}.2.dar.vol666.par2': 'dummy',
f'specific_FULL_{date_100_days_ago}.2.dar.par2': 'dummy',
f'specific_FULL_{date_40_days_ago}.1.dar': 'dummy',
f'specific_FULL_{date_40_days_ago}.1.dar.vol001.par2': 'dummy',
f'specific_FULL_{date_40_days_ago}.1.dar.par2': 'dummy',
f'specific_FULL_{date_40_days_ago}.2.dar': 'dummy',
f'specific_FULL_{date_40_days_ago}.2.dar.vol666.par2': 'dummy',
f'specific_FULL_{date_40_days_ago}.2.dar.par2': 'dummy',
f'specific_FULL_{date_20_days_ago}.1.dar': 'dummy',
f'specific_FULL_{date_20_days_ago}.1.dar.vol001.par2': 'dummy',
f'specific_FULL_{date_20_days_ago}.1.dar.par2': 'dummy',
f'specific_FULL_{date_20_days_ago}.2.dar': 'dummy',
f'specific_FULL_{date_20_days_ago}.2.dar.vol666.par2': 'dummy',
f'specific_FULL_{date_20_days_ago}.2.dar.par2': 'dummy',
}
for filename, content in test_files.items():
with open(os.path.join(env.test_dir, 'backups', filename), 'w') as f:
f.write(content)

command = ['cleanup', '--cleanup-specific-archive', f'specific_FULL_{date_100_days_ago} , specific_FULL_{date_20_days_ago}' , '--config-file', env.config_file, '--verbose']
env.logger.info(command)
result = subprocess.run(command, capture_output=True, text=True)
env.logger.info(result.stdout)
if result.returncode != 0:
env.logger.error(result.stderr)
raise RuntimeError(f"Cleanup script failed with return code {result.returncode}")

assert (not os.path.exists(os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_100_days_ago}.1.dar'))), f"File {os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_100_days_ago}.1.dar')} still exists"
assert (not os.path.exists(os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_100_days_ago}.1.dar.vol001.par2'))), f"File {os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_100_days_ago}.1.dar.vol001.par2')} still exists"
assert (not os.path.exists(os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_100_days_ago}.1.dar.par2'))), f"File {os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_100_days_ago}.1.dar.par2')} still exists"
assert (not os.path.exists(os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_100_days_ago}.2.dar'))), f"File {os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_100_days_ago}.2.dar')} still exists"
assert (not os.path.exists(os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_100_days_ago}.2.dar.vol666.par2'))), f"File {os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_100_days_ago}.2.dar.vol666.par2')} still exists"
assert (not os.path.exists(os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_100_days_ago}.2.dar.par2'))), f"File {os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_100_days_ago}.2.dar.par2')} still exists"

assert (not os.path.exists(os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_20_days_ago}.1.dar'))), f"File {os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_20_days_ago}.1.dar')} still exists"
assert (not os.path.exists(os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_20_days_ago}.1.dar.vol001.par2'))), f"File {os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_20_days_ago}.1.dar.vol001.par2')} still exists"
assert (not os.path.exists(os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_20_days_ago}.1.dar.par2'))), f"File {os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_20_days_ago}.1.dar.par2')} still exists"
assert (not os.path.exists(os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_20_days_ago}.2.dar'))), f"File {os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_20_days_ago}.2.dar')} still exists"
assert (not os.path.exists(os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_20_days_ago}.2.dar.vol666.par2'))), f"File {os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_20_days_ago}.2.dar.vol666.par2')} still exists"
assert (not os.path.exists(os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_20_days_ago}.2.dar.par2'))), f"File {os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_20_days_ago}.2.dar.par2')} still exists"

assert (os.path.exists(os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_40_days_ago}.1.dar'))), f"File {os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_40_days_ago}.1.dar')} still exists"
assert (os.path.exists(os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_40_days_ago}.1.dar.vol001.par2'))), f"File {os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_40_days_ago}.1.dar.vol001.par2')} still exists"
assert (os.path.exists(os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_40_days_ago}.1.dar.par2'))), f"File {os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_40_days_ago}.1.dar.par2')} still exists"
assert (os.path.exists(os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_40_days_ago}.2.dar'))), f"File {os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_40_days_ago}.2.dar')} still exists"
assert (os.path.exists(os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_40_days_ago}.2.dar.vol666.par2'))), f"File {os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_40_days_ago}.2.dar.vol666.par2')} still exists"
assert (os.path.exists(os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_40_days_ago}.2.dar.par2'))), f"File {os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_40_days_ago}.2.dar.par2')} still exists"



def test_cleanup_multiple_specific_archive(setup_environment, env):
test_files = {
f'specific_FULL_{date_100_days_ago}.1.dar': 'dummy',
f'specific_FULL_{date_100_days_ago}.1.dar.vol001.par2': 'dummy',
Expand Down Expand Up @@ -110,6 +169,9 @@ def test_cleanup_specific_archive(setup_environment, env):
assert (not os.path.exists(os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_100_days_ago}.2.dar.par2'))), f"File {os.path.join(env.test_dir, 'backups', f'specific_FULL_{date_100_days_ago}.2.dar.par2')} still exists"





def test_cleanup_alternate_dir(setup_environment, env):
alternate_dir = os.path.join(env.test_dir, 'backups-alternate')
if not alternate_dir.startswith('/tmp/unit-test'):
Expand Down

0 comments on commit 7230230

Please sign in to comment.