When using the "numeric_owner" option, tailor the flags passed to Borg depending on the Borg version (#394).

This commit is contained in:
Dan Helfman 2022-02-10 09:51:13 -08:00
parent 00a57fd947
commit 7e7209322a
4 changed files with 20 additions and 18 deletions

4
NEWS
View file

@ -2,8 +2,8 @@
* #394: Compact repository segments and free space with new "borgmatic compact" action. Borg 1.2+ * #394: Compact repository segments and free space with new "borgmatic compact" action. Borg 1.2+
only. Also run "compact" by default when no actions are specified, as "prune" in Borg 1.2 no only. Also run "compact" by default when no actions are specified, as "prune" in Borg 1.2 no
longer frees up space unless "compact" is run. longer frees up space unless "compact" is run.
* #394: When using the "atime" or "bsd_flags" options, tailor the flags passed to Borg depending on * #394: When using the "atime", "bsd_flags", or "numeric_owner" options, tailor the flags passed
the Borg version. to Borg depending on the Borg version.
* #480, #482: Fix traceback when a YAML validation error occurs. * #480, #482: Fix traceback when a YAML validation error occurs.
1.5.22 1.5.22

View file

@ -237,6 +237,11 @@ def create_archive(
else: else:
noflags_flags = ('--nobsdflags',) if location_config.get('bsd_flags') is False else () noflags_flags = ('--nobsdflags',) if location_config.get('bsd_flags') is False else ()
if feature.available(feature.Feature.NUMERIC_IDS, local_borg_version):
numeric_ids_flags = ('--numeric-ids',) if location_config.get('numeric_owner') else ()
else:
numeric_ids_flags = ('--numeric-owner',) if location_config.get('numeric_owner') else ()
full_command = ( full_command = (
tuple(local_path.split(' ')) tuple(local_path.split(' '))
+ ('create',) + ('create',)
@ -251,7 +256,7 @@ def create_archive(
if location_config.get('one_file_system') or stream_processes if location_config.get('one_file_system') or stream_processes
else () else ()
) )
+ (('--numeric-owner',) if location_config.get('numeric_owner') else ()) + numeric_ids_flags
+ atime_flags + atime_flags
+ (('--noctime',) if location_config.get('ctime') is False else ()) + (('--noctime',) if location_config.get('ctime') is False else ())
+ (('--nobirthtime',) if location_config.get('birthtime') is False else ()) + (('--nobirthtime',) if location_config.get('birthtime') is False else ())

View file

@ -7,12 +7,14 @@ class Feature(Enum):
COMPACT = 1 COMPACT = 1
ATIME = 2 ATIME = 2
NOFLAGS = 3 NOFLAGS = 3
NUMERIC_IDS = 4
FEATURE_TO_MINIMUM_BORG_VERSION = { FEATURE_TO_MINIMUM_BORG_VERSION = {
Feature.COMPACT: parse_version('1.2.0a2'), # borg compact Feature.COMPACT: parse_version('1.2.0a2'), # borg compact
Feature.ATIME: parse_version('1.2.0a7'), # borg create --atime Feature.ATIME: parse_version('1.2.0a7'), # borg create --atime
Feature.NOFLAGS: parse_version('1.2.0a8'), # borg create --noflags Feature.NOFLAGS: parse_version('1.2.0a8'), # borg create --noflags
Feature.NUMERIC_IDS: parse_version('1.2.0b3'), # borg create/extract/mount --numeric-ids
} }

View file

@ -699,18 +699,23 @@ def test_create_archive_with_one_file_system_calls_borg_with_one_file_system_par
) )
def test_create_archive_with_numeric_owner_calls_borg_with_numeric_owner_parameter(): @pytest.mark.parametrize(
'feature_available,option_flag', ((True, '--numeric-ids'), (False, '--numeric-owner'),),
)
def test_create_archive_with_numeric_owner_calls_borg_with_numeric_ids_parameter(
feature_available, option_flag
):
flexmock(module).should_receive('borgmatic_source_directories').and_return([]) flexmock(module).should_receive('borgmatic_source_directories').and_return([])
flexmock(module).should_receive('deduplicate_directories').and_return(('foo', 'bar')) flexmock(module).should_receive('deduplicate_directories').and_return(('foo', 'bar'))
flexmock(module).should_receive('map_directories_to_devices').and_return({}) flexmock(module).should_receive('map_directories_to_devices').and_return({})
flexmock(module).should_receive('_expand_directories').and_return(()) flexmock(module).should_receive('_expand_directories').and_return(())
flexmock(module).should_receive('_expand_home_directories').and_return(()) flexmock(module).should_receive('_expand_home_directories').and_return(())
flexmock(module).should_receive('_write_pattern_file').and_return(None) flexmock(module).should_receive('_write_pattern_file').and_return(None)
flexmock(module.feature).should_receive('available').and_return(True) flexmock(module.feature).should_receive('available').and_return(feature_available)
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(()) flexmock(module).should_receive('_make_exclude_flags').and_return(())
flexmock(module).should_receive('execute_command').with_args( flexmock(module).should_receive('execute_command').with_args(
('borg', 'create', '--numeric-owner') + ARCHIVE_WITH_PATHS, ('borg', 'create') + ((option_flag,) if option_flag else ()) + ARCHIVE_WITH_PATHS,
output_log_level=logging.INFO, output_log_level=logging.INFO,
output_file=None, output_file=None,
borg_local_path='borg', borg_local_path='borg',
@ -817,12 +822,7 @@ def test_create_archive_with_atime_option_calls_borg_with_corresponding_paramete
flexmock(module).should_receive('_expand_directories').and_return(()) flexmock(module).should_receive('_expand_directories').and_return(())
flexmock(module).should_receive('_expand_home_directories').and_return(()) flexmock(module).should_receive('_expand_home_directories').and_return(())
flexmock(module).should_receive('_write_pattern_file').and_return(None) flexmock(module).should_receive('_write_pattern_file').and_return(None)
flexmock(module.feature).should_receive('available').with_args( flexmock(module.feature).should_receive('available').and_return(feature_available)
module.feature.Feature.ATIME, '1.2.3'
).and_return(feature_available)
flexmock(module.feature).should_receive('available').with_args(
module.feature.Feature.NOFLAGS, '1.2.3'
).and_return(True)
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(()) flexmock(module).should_receive('_make_exclude_flags').and_return(())
flexmock(module).should_receive('execute_command').with_args( flexmock(module).should_receive('execute_command').with_args(
@ -864,12 +864,7 @@ def test_create_archive_with_bsd_flags_option_calls_borg_with_corresponding_para
flexmock(module).should_receive('_expand_directories').and_return(()) flexmock(module).should_receive('_expand_directories').and_return(())
flexmock(module).should_receive('_expand_home_directories').and_return(()) flexmock(module).should_receive('_expand_home_directories').and_return(())
flexmock(module).should_receive('_write_pattern_file').and_return(None) flexmock(module).should_receive('_write_pattern_file').and_return(None)
flexmock(module.feature).should_receive('available').with_args( flexmock(module.feature).should_receive('available').and_return(feature_available)
module.feature.Feature.ATIME, '1.2.3'
).and_return(True)
flexmock(module.feature).should_receive('available').with_args(
module.feature.Feature.NOFLAGS, '1.2.3'
).and_return(feature_available)
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(()) flexmock(module).should_receive('_make_exclude_flags').and_return(())
flexmock(module).should_receive('execute_command').with_args( flexmock(module).should_receive('execute_command').with_args(