47: Support for Borg --dry-run option via borgmatic command-line.
This commit is contained in:
parent
bf2f39623e
commit
62526038d6
6 changed files with 81 additions and 11 deletions
3
NEWS
3
NEWS
|
@ -1,5 +1,6 @@
|
|||
1.1.14.dev0
|
||||
* #49: Rename incorrect --pattern-from option to correct --patterns-from.
|
||||
* #49: Fix for typo in --patterns-from option.
|
||||
* #47: Support for Borg --dry-run option via borgmatic command-line.
|
||||
|
||||
1.1.13
|
||||
* #54: Fix for incorrect consistency check flags passed to Borg when all three checks ("repository",
|
||||
|
|
|
@ -85,11 +85,11 @@ def _make_exclude_flags(location_config, exclude_filename=None):
|
|||
|
||||
|
||||
def create_archive(
|
||||
verbosity, repository, location_config, storage_config, local_path='borg', remote_path=None,
|
||||
verbosity, dry_run, repository, location_config, storage_config, local_path='borg', remote_path=None,
|
||||
):
|
||||
'''
|
||||
Given a vebosity flag, a local or remote repository path, a location config dict, and a storage
|
||||
config dict, create a Borg archive.
|
||||
Given vebosity/dry-run flags, a local or remote repository path, a location config dict, and a
|
||||
storage config dict, create a Borg archive.
|
||||
'''
|
||||
sources = tuple(
|
||||
itertools.chain.from_iterable(
|
||||
|
@ -122,6 +122,7 @@ def create_archive(
|
|||
VERBOSITY_SOME: ('--info', '--stats',),
|
||||
VERBOSITY_LOTS: ('--debug', '--list', '--stats'),
|
||||
}.get(verbosity, ())
|
||||
dry_run_flags = ('--dry-run',) if dry_run else ()
|
||||
default_archive_name_format = '{hostname}-{now:%Y-%m-%dT%H:%M:%S.%f}'
|
||||
archive_name_format = storage_config.get('archive_name_format', default_archive_name_format)
|
||||
|
||||
|
@ -133,7 +134,7 @@ def create_archive(
|
|||
),
|
||||
) + sources + pattern_flags + exclude_flags + compression_flags + remote_rate_limit_flags + \
|
||||
one_file_system_flags + files_cache_flags + remote_path_flags + umask_flags + \
|
||||
verbosity_flags
|
||||
verbosity_flags + dry_run_flags
|
||||
|
||||
logger.debug(' '.join(full_command))
|
||||
subprocess.check_call(full_command)
|
||||
|
|
|
@ -32,16 +32,17 @@ def _make_prune_flags(retention_config):
|
|||
)
|
||||
|
||||
|
||||
def prune_archives(verbosity, repository, retention_config, local_path='borg', remote_path=None):
|
||||
def prune_archives(verbosity, dry_run, repository, retention_config, local_path='borg', remote_path=None):
|
||||
'''
|
||||
Given a verbosity flag, a local or remote repository path, a retention config dict, prune Borg
|
||||
archives according the the retention policy specified in that configuration.
|
||||
Given verbosity/dry-run flags, a local or remote repository path, a retention config dict, prune
|
||||
Borg archives according the the retention policy specified in that configuration.
|
||||
'''
|
||||
remote_path_flags = ('--remote-path', remote_path) if remote_path else ()
|
||||
verbosity_flags = {
|
||||
VERBOSITY_SOME: ('--info', '--stats',),
|
||||
VERBOSITY_LOTS: ('--debug', '--stats', '--list'),
|
||||
}.get(verbosity, ())
|
||||
dry_run_flags = ('--dry-run',) if dry_run else ()
|
||||
|
||||
full_command = (
|
||||
local_path, 'prune',
|
||||
|
@ -50,7 +51,7 @@ def prune_archives(verbosity, repository, retention_config, local_path='borg', r
|
|||
element
|
||||
for pair in _make_prune_flags(retention_config)
|
||||
for element in pair
|
||||
) + remote_path_flags + verbosity_flags
|
||||
) + remote_path_flags + verbosity_flags + dry_run_flags
|
||||
|
||||
logger.debug(' '.join(full_command))
|
||||
subprocess.check_call(full_command)
|
||||
|
|
|
@ -61,6 +61,12 @@ def parse_arguments(*arguments):
|
|||
action='store_true',
|
||||
help='Check archives for consistency',
|
||||
)
|
||||
parser.add_argument(
|
||||
'-n', '--dry-run',
|
||||
dest='dry_run',
|
||||
action='store_true',
|
||||
help='Go through the motions, but do not actually write any changes to the repository',
|
||||
)
|
||||
parser.add_argument(
|
||||
'-v', '--verbosity',
|
||||
type=int,
|
||||
|
@ -100,19 +106,22 @@ def run_configuration(config_filename, args): # pragma: no cover
|
|||
|
||||
for unexpanded_repository in location['repositories']:
|
||||
repository = os.path.expanduser(unexpanded_repository)
|
||||
dry_run_label = ' (dry run; not making any changes)' if args.dry_run else ''
|
||||
if args.prune:
|
||||
logger.info('{}: Pruning archives'.format(repository))
|
||||
logger.info('{}: Pruning archives{}'.format(repository, dry_run_label))
|
||||
prune.prune_archives(
|
||||
args.verbosity,
|
||||
args.dry_run,
|
||||
repository,
|
||||
retention,
|
||||
local_path=local_path,
|
||||
remote_path=remote_path,
|
||||
)
|
||||
if args.create:
|
||||
logger.info('{}: Creating archive'.format(repository))
|
||||
logger.info('{}: Creating archive{}'.format(repository, dry_run_label))
|
||||
create.create_archive(
|
||||
args.verbosity,
|
||||
args.dry_run,
|
||||
repository,
|
||||
location,
|
||||
storage,
|
||||
|
|
|
@ -190,6 +190,7 @@ def test_create_archive_calls_borg_with_parameters():
|
|||
|
||||
module.create_archive(
|
||||
verbosity=None,
|
||||
dry_run=False,
|
||||
repository='repo',
|
||||
location_config={
|
||||
'source_directories': ['foo', 'bar'],
|
||||
|
@ -210,6 +211,7 @@ def test_create_archive_with_patterns_calls_borg_with_patterns():
|
|||
|
||||
module.create_archive(
|
||||
verbosity=None,
|
||||
dry_run=False,
|
||||
repository='repo',
|
||||
location_config={
|
||||
'source_directories': ['foo', 'bar'],
|
||||
|
@ -230,6 +232,7 @@ def test_create_archive_with_exclude_patterns_calls_borg_with_excludes():
|
|||
|
||||
module.create_archive(
|
||||
verbosity=None,
|
||||
dry_run=False,
|
||||
repository='repo',
|
||||
location_config={
|
||||
'source_directories': ['foo', 'bar'],
|
||||
|
@ -250,6 +253,7 @@ def test_create_archive_with_verbosity_some_calls_borg_with_info_parameter():
|
|||
|
||||
module.create_archive(
|
||||
verbosity=VERBOSITY_SOME,
|
||||
dry_run=False,
|
||||
repository='repo',
|
||||
location_config={
|
||||
'source_directories': ['foo', 'bar'],
|
||||
|
@ -269,6 +273,28 @@ def test_create_archive_with_verbosity_lots_calls_borg_with_debug_parameter():
|
|||
|
||||
module.create_archive(
|
||||
verbosity=VERBOSITY_LOTS,
|
||||
dry_run=False,
|
||||
repository='repo',
|
||||
location_config={
|
||||
'source_directories': ['foo', 'bar'],
|
||||
'repositories': ['repo'],
|
||||
'exclude_patterns': None,
|
||||
},
|
||||
storage_config={},
|
||||
)
|
||||
|
||||
|
||||
def test_create_archive_with_dry_run_calls_borg_with_dry_run_parameter():
|
||||
flexmock(module).should_receive('_expand_directory').and_return(['foo']).and_return(['bar'])
|
||||
flexmock(module).should_receive('_write_pattern_file').and_return(None)
|
||||
flexmock(module).should_receive('_make_pattern_flags').and_return(())
|
||||
flexmock(module).should_receive('_make_pattern_flags').and_return(())
|
||||
flexmock(module).should_receive('_make_exclude_flags').and_return(())
|
||||
insert_subprocess_mock(CREATE_COMMAND + ('--dry-run',))
|
||||
|
||||
module.create_archive(
|
||||
verbosity=None,
|
||||
dry_run=True,
|
||||
repository='repo',
|
||||
location_config={
|
||||
'source_directories': ['foo', 'bar'],
|
||||
|
@ -288,6 +314,7 @@ def test_create_archive_with_compression_calls_borg_with_compression_parameters(
|
|||
|
||||
module.create_archive(
|
||||
verbosity=None,
|
||||
dry_run=False,
|
||||
repository='repo',
|
||||
location_config={
|
||||
'source_directories': ['foo', 'bar'],
|
||||
|
@ -307,6 +334,7 @@ def test_create_archive_with_remote_rate_limit_calls_borg_with_remote_ratelimit_
|
|||
|
||||
module.create_archive(
|
||||
verbosity=None,
|
||||
dry_run=False,
|
||||
repository='repo',
|
||||
location_config={
|
||||
'source_directories': ['foo', 'bar'],
|
||||
|
@ -326,6 +354,7 @@ def test_create_archive_with_one_file_system_calls_borg_with_one_file_system_par
|
|||
|
||||
module.create_archive(
|
||||
verbosity=None,
|
||||
dry_run=False,
|
||||
repository='repo',
|
||||
location_config={
|
||||
'source_directories': ['foo', 'bar'],
|
||||
|
@ -346,6 +375,7 @@ def test_create_archive_with_files_cache_calls_borg_with_files_cache_parameters(
|
|||
|
||||
module.create_archive(
|
||||
verbosity=None,
|
||||
dry_run=False,
|
||||
repository='repo',
|
||||
location_config={
|
||||
'source_directories': ['foo', 'bar'],
|
||||
|
@ -366,6 +396,7 @@ def test_create_archive_with_local_path_calls_borg_via_local_path():
|
|||
|
||||
module.create_archive(
|
||||
verbosity=None,
|
||||
dry_run=False,
|
||||
repository='repo',
|
||||
location_config={
|
||||
'source_directories': ['foo', 'bar'],
|
||||
|
@ -386,6 +417,7 @@ def test_create_archive_with_remote_path_calls_borg_with_remote_path_parameters(
|
|||
|
||||
module.create_archive(
|
||||
verbosity=None,
|
||||
dry_run=False,
|
||||
repository='repo',
|
||||
location_config={
|
||||
'source_directories': ['foo', 'bar'],
|
||||
|
@ -406,6 +438,7 @@ def test_create_archive_with_umask_calls_borg_with_umask_parameters():
|
|||
|
||||
module.create_archive(
|
||||
verbosity=None,
|
||||
dry_run=False,
|
||||
repository='repo',
|
||||
location_config={
|
||||
'source_directories': ['foo', 'bar'],
|
||||
|
@ -426,6 +459,7 @@ def test_create_archive_with_source_directories_glob_expands():
|
|||
|
||||
module.create_archive(
|
||||
verbosity=None,
|
||||
dry_run=False,
|
||||
repository='repo',
|
||||
location_config={
|
||||
'source_directories': ['foo*'],
|
||||
|
@ -446,6 +480,7 @@ def test_create_archive_with_non_matching_source_directories_glob_passes_through
|
|||
|
||||
module.create_archive(
|
||||
verbosity=None,
|
||||
dry_run=False,
|
||||
repository='repo',
|
||||
location_config={
|
||||
'source_directories': ['foo*'],
|
||||
|
@ -465,6 +500,7 @@ def test_create_archive_with_glob_calls_borg_with_expanded_directories():
|
|||
|
||||
module.create_archive(
|
||||
verbosity=None,
|
||||
dry_run=False,
|
||||
repository='repo',
|
||||
location_config={
|
||||
'source_directories': ['foo*'],
|
||||
|
@ -484,6 +520,7 @@ def test_create_archive_with_archive_name_format_calls_borg_with_archive_name():
|
|||
|
||||
module.create_archive(
|
||||
verbosity=None,
|
||||
dry_run=False,
|
||||
repository='repo',
|
||||
location_config={
|
||||
'source_directories': ['foo', 'bar'],
|
||||
|
@ -505,6 +542,7 @@ def test_create_archive_with_archive_name_format_accepts_borg_placeholders():
|
|||
|
||||
module.create_archive(
|
||||
verbosity=None,
|
||||
dry_run=False,
|
||||
repository='repo',
|
||||
location_config={
|
||||
'source_directories': ['foo', 'bar'],
|
||||
|
|
|
@ -64,6 +64,7 @@ def test_prune_archives_calls_borg_with_parameters():
|
|||
|
||||
module.prune_archives(
|
||||
verbosity=None,
|
||||
dry_run=False,
|
||||
repository='repo',
|
||||
retention_config=retention_config,
|
||||
)
|
||||
|
@ -79,6 +80,7 @@ def test_prune_archives_with_verbosity_some_calls_borg_with_info_parameter():
|
|||
module.prune_archives(
|
||||
repository='repo',
|
||||
verbosity=VERBOSITY_SOME,
|
||||
dry_run=False,
|
||||
retention_config=retention_config,
|
||||
)
|
||||
|
||||
|
@ -93,6 +95,22 @@ def test_prune_archives_with_verbosity_lots_calls_borg_with_debug_parameter():
|
|||
module.prune_archives(
|
||||
repository='repo',
|
||||
verbosity=VERBOSITY_LOTS,
|
||||
dry_run=False,
|
||||
retention_config=retention_config,
|
||||
)
|
||||
|
||||
|
||||
def test_prune_archives_with_dry_run_calls_borg_with_dry_run_parameter():
|
||||
retention_config = flexmock()
|
||||
flexmock(module).should_receive('_make_prune_flags').with_args(retention_config).and_return(
|
||||
BASE_PRUNE_FLAGS,
|
||||
)
|
||||
insert_subprocess_mock(PRUNE_COMMAND + ('--dry-run',))
|
||||
|
||||
module.prune_archives(
|
||||
repository='repo',
|
||||
verbosity=None,
|
||||
dry_run=True,
|
||||
retention_config=retention_config,
|
||||
)
|
||||
|
||||
|
@ -106,6 +124,7 @@ def test_prune_archives_with_local_path_calls_borg_via_local_path():
|
|||
|
||||
module.prune_archives(
|
||||
verbosity=None,
|
||||
dry_run=False,
|
||||
repository='repo',
|
||||
retention_config=retention_config,
|
||||
local_path='borg1',
|
||||
|
@ -121,6 +140,7 @@ def test_prune_archives_with_remote_path_calls_borg_with_remote_path_parameters(
|
|||
|
||||
module.prune_archives(
|
||||
verbosity=None,
|
||||
dry_run=False,
|
||||
repository='repo',
|
||||
retention_config=retention_config,
|
||||
remote_path='borg1',
|
||||
|
|
Loading…
Reference in a new issue