From ceeaf254432f596f1f06d1e0e756d8782fc9fbf9 Mon Sep 17 00:00:00 2001 From: Dan Helfman Date: Fri, 28 Jul 2017 22:02:18 -0700 Subject: [PATCH] #17: Added command-line flags for performing a borgmatic run with only pruning, creating, or checking enabled. --- NEWS | 6 ++ README.md | 22 ++++++- borgmatic/commands/borgmatic.py | 60 +++++++++++++++---- .../integration/commands/test_borgmatic.py | 24 ++++++++ setup.py | 2 +- 5 files changed, 99 insertions(+), 15 deletions(-) diff --git a/NEWS b/NEWS index f73b4b8..c5a8162 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,9 @@ +1.1.4 + + * #17: Added command-line flags for performing a borgmatic run with only pruning, creating, or + checking enabled. This supports use cases like running consistency checks from a different cron + job with a different frequency, or running pruning with a different verbosity level. + 1.1.3 * #14: Support for running multiple config files in /etc/borgmatic.d/ from a single borgmatic run. diff --git a/README.md b/README.md index 8ea9a89..c15e826 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ to remove anything you don't need. ### Multiple configuration files A more advanced usage is to create multiple separate configuration files and -place each one in a /etc/borgmatic.d directory. For instance: +place each one in an /etc/borgmatic.d directory. For instance: sudo mkdir /etc/borgmatic.d sudo generate-borgmatic-config --destination /etc/borgmatic.d/app1.yaml @@ -175,6 +175,12 @@ arguments: This will also prune any old backups as per the configured retention policy, and check backups for consistency problems due to things like file damage. +If you'd like to see the available command-line arguments, view the help: + + borgmatic --help + +### Verbosity + By default, the backup will proceed silently except in the case of errors. But if you'd like to to get additional information about the progress of the backup as it proceeds, use the verbosity option: @@ -185,9 +191,19 @@ Or, for even more progress spew: borgmatic --verbosity 2 -If you'd like to see the available command-line arguments, view the help: +### À la carte - borgmatic --help +If you want to run borgmatic with only pruning, creating, or checking enabled, +the following optional flags are available: + + borgmatic --prune + borgmatic --create + borgmatic --check + +You can run with only one of these flags provided, or you can mix and match +any number of them. This supports use cases like running consistency checks +from a different cron job with a different frequency, or running pruning with +a different verbosity level. ## Autopilot diff --git a/borgmatic/commands/borgmatic.py b/borgmatic/commands/borgmatic.py index a26c30c..c5c7a28 100644 --- a/borgmatic/commands/borgmatic.py +++ b/borgmatic/commands/borgmatic.py @@ -18,7 +18,14 @@ def parse_arguments(*arguments): Given command-line arguments with which this script was invoked, parse the arguments and return them as an ArgumentParser instance. ''' - parser = ArgumentParser() + parser = ArgumentParser( + description= + ''' + A simple wrapper script for the Borg backup software that creates and prunes backups. + If none of the --prune, --create, or --check options are given, then borgmatic defaults + to all three: prune, create, and check archives. + ''' + ) parser.add_argument( '-c', '--config', nargs='+', @@ -29,7 +36,25 @@ def parse_arguments(*arguments): parser.add_argument( '--excludes', dest='excludes_filename', - help='Excludes filename, deprecated in favor of exclude_patterns within configuration', + help='Deprecated in favor of exclude_patterns within configuration', + ) + parser.add_argument( + '-p', '--prune', + dest='prune', + action='store_true', + help='Prune archives according to the retention policy', + ) + parser.add_argument( + '-C', '--create', + dest='create', + action='store_true', + help='Create archives (actually perform backups)', + ) + parser.add_argument( + '-k', '--check', + dest='check', + action='store_true', + help='Check archives for consistency', ) parser.add_argument( '-v', '--verbosity', @@ -37,7 +62,17 @@ def parse_arguments(*arguments): help='Display verbose progress (1 for some, 2 for lots)', ) - return parser.parse_args(arguments) + args = parser.parse_args(arguments) + + # If any of the three action flags in the given parse arguments have been explicitly requested, + # leave them as-is. Otherwise, assume defaults: Mutate the given arguments to enable all the + # actions. + if not args.prune and not args.create and not args.check: + args.prune = True + args.create = True + args.check = True + + return args def main(): # pragma: no cover @@ -60,14 +95,17 @@ def main(): # pragma: no cover borg.initialize(storage) for repository in location['repositories']: - borg.prune_archives(args.verbosity, repository, retention, remote_path=remote_path) - borg.create_archive( - args.verbosity, - repository, - location, - storage, - ) - borg.check_archives(args.verbosity, repository, consistency, remote_path=remote_path) + if args.prune: + borg.prune_archives(args.verbosity, repository, retention, remote_path=remote_path) + if args.create: + borg.create_archive( + args.verbosity, + repository, + location, + storage, + ) + if args.check: + borg.check_archives(args.verbosity, repository, consistency, remote_path=remote_path) except (ValueError, OSError, CalledProcessError) as error: print(error, file=sys.stderr) sys.exit(1) diff --git a/borgmatic/tests/integration/commands/test_borgmatic.py b/borgmatic/tests/integration/commands/test_borgmatic.py index 0334341..2b82ecf 100644 --- a/borgmatic/tests/integration/commands/test_borgmatic.py +++ b/borgmatic/tests/integration/commands/test_borgmatic.py @@ -37,6 +37,30 @@ def test_parse_arguments_with_verbosity_flag_overrides_default(): assert parser.verbosity == 1 +def test_parse_arguments_with_no_actions_defaults_to_all_actions_enabled(): + parser = module.parse_arguments() + + assert parser.prune is True + assert parser.create is True + assert parser.check is True + + +def test_parse_arguments_with_prune_action_leaves_other_actions_disabled(): + parser = module.parse_arguments('--prune') + + assert parser.prune is True + assert parser.create is False + assert parser.check is False + + +def test_parse_arguments_with_multiple_actions_leaves_other_action_disabled(): + parser = module.parse_arguments('--create', '--check') + + assert parser.prune is False + assert parser.create is True + assert parser.check is True + + def test_parse_arguments_with_invalid_arguments_exits(): with pytest.raises(SystemExit): module.parse_arguments('--posix-me-harder') diff --git a/setup.py b/setup.py index 7831a3e..d4f587b 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, find_packages -VERSION = '1.1.3' +VERSION = '1.1.4' setup(