Rename several configuration options to match Borg 2 (#557).

This commit is contained in:
Dan Helfman 2022-08-17 21:14:58 -07:00
parent 3b6ed06686
commit f47c98c4a5
10 changed files with 52 additions and 24 deletions

9
NEWS
View file

@ -4,6 +4,15 @@
repository info). If you install Borg 2, you'll need to manually "borg transfer" or "borgmatic repository info). If you install Borg 2, you'll need to manually "borg transfer" or "borgmatic
transfer" your existing Borg 1 repositories before use. See the Borg 2.0 changelog for more transfer" your existing Borg 1 repositories before use. See the Borg 2.0 changelog for more
information about Borg 2: https://www.borgbackup.org/releases/borg-2.0.html information about Borg 2: https://www.borgbackup.org/releases/borg-2.0.html
* #557: Rename several configuration options to match Borg 2: "remote_rate_limit" is now
"upload_rate_limit", "numeric_owner" is "numeric_ids", and "bsd_flags" is "flags". borgmatic
still works with the old options.
* #557: Remote repository paths without the "ssh://" syntax are deprecated but still supported for
now. However, remote repository paths containing "~" will no longer work.
* #557: Omitting the "--archive" flag on the "list" action is deprecated when using Borg 2. Use
the new "rlist" action instead. And when using the "--archive" or "--find" flags on the "list"
action with Borg 2, several flags are no longer supported: "--prefix", "--glob-archives",
"--sort-by", "--first", and "--last".
* #565: Fix handling of "repository" and "data" consistency checks to prevent invalid Borg flags. * #565: Fix handling of "repository" and "data" consistency checks to prevent invalid Borg flags.
* #566: Modify "mount" and "extract" actions to require the "--repository" flag when multiple * #566: Modify "mount" and "extract" actions to require the "--repository" flag when multiple
repositories are configured. repositories are configured.

View file

@ -233,7 +233,7 @@ def create_archive(
checkpoint_interval = storage_config.get('checkpoint_interval', None) checkpoint_interval = storage_config.get('checkpoint_interval', None)
chunker_params = storage_config.get('chunker_params', None) chunker_params = storage_config.get('chunker_params', None)
compression = storage_config.get('compression', None) compression = storage_config.get('compression', None)
remote_rate_limit = storage_config.get('remote_rate_limit', None) upload_rate_limit = storage_config.get('upload_rate_limit', None)
umask = storage_config.get('umask', None) umask = storage_config.get('umask', None)
lock_wait = storage_config.get('lock_wait', None) lock_wait = storage_config.get('lock_wait', None)
files_cache = location_config.get('files_cache') files_cache = location_config.get('files_cache')
@ -246,22 +246,22 @@ def create_archive(
atime_flags = ('--noatime',) if location_config.get('atime') is False else () atime_flags = ('--noatime',) if location_config.get('atime') is False else ()
if feature.available(feature.Feature.NOFLAGS, local_borg_version): if feature.available(feature.Feature.NOFLAGS, local_borg_version):
noflags_flags = ('--noflags',) if location_config.get('bsd_flags') is False else () noflags_flags = ('--noflags',) if location_config.get('flags') is False else ()
else: else:
noflags_flags = ('--nobsdflags',) if location_config.get('bsd_flags') is False else () noflags_flags = ('--nobsdflags',) if location_config.get('flags') is False else ()
if feature.available(feature.Feature.NUMERIC_IDS, local_borg_version): if feature.available(feature.Feature.NUMERIC_IDS, local_borg_version):
numeric_ids_flags = ('--numeric-ids',) if location_config.get('numeric_owner') else () numeric_ids_flags = ('--numeric-ids',) if location_config.get('numeric_ids') else ()
else: else:
numeric_ids_flags = ('--numeric-owner',) if location_config.get('numeric_owner') else () numeric_ids_flags = ('--numeric-owner',) if location_config.get('numeric_ids') else ()
if feature.available(feature.Feature.UPLOAD_RATELIMIT, local_borg_version): if feature.available(feature.Feature.UPLOAD_RATELIMIT, local_borg_version):
upload_ratelimit_flags = ( upload_ratelimit_flags = (
('--upload-ratelimit', str(remote_rate_limit)) if remote_rate_limit else () ('--upload-ratelimit', str(upload_rate_limit)) if upload_rate_limit else ()
) )
else: else:
upload_ratelimit_flags = ( upload_ratelimit_flags = (
('--remote-ratelimit', str(remote_rate_limit)) if remote_rate_limit else () ('--remote-ratelimit', str(upload_rate_limit)) if upload_rate_limit else ()
) )
ensure_files_readable(location_config.get('patterns_from'), location_config.get('exclude_from')) ensure_files_readable(location_config.get('patterns_from'), location_config.get('exclude_from'))

View file

@ -83,9 +83,9 @@ def extract_archive(
raise ValueError('progress and extract_to_stdout cannot both be set') raise ValueError('progress and extract_to_stdout cannot both be set')
if feature.available(feature.Feature.NUMERIC_IDS, local_borg_version): if feature.available(feature.Feature.NUMERIC_IDS, local_borg_version):
numeric_ids_flags = ('--numeric-ids',) if location_config.get('numeric_owner') else () numeric_ids_flags = ('--numeric-ids',) if location_config.get('numeric_ids') else ()
else: else:
numeric_ids_flags = ('--numeric-owner',) if location_config.get('numeric_owner') else () numeric_ids_flags = ('--numeric-owner',) if location_config.get('numeric_ids') else ()
full_command = ( full_command = (
(local_path, 'extract') (local_path, 'extract')

View file

@ -314,8 +314,8 @@ def make_parsers():
create_parser = subparsers.add_parser( create_parser = subparsers.add_parser(
'create', 'create',
aliases=SUBPARSER_ALIASES['create'], aliases=SUBPARSER_ALIASES['create'],
help='Create archives (actually perform backups)', help='Create an archive (actually perform a backup)',
description='Create archives (actually perform backups)', description='Create an archive (actually perform a backup)',
add_help=False, add_help=False,
) )
create_group = create_parser.add_argument_group('create arguments') create_group = create_parser.add_argument_group('create arguments')

View file

@ -283,7 +283,7 @@ def generate_sample_configuration(
if source_filename: if source_filename:
source_config = load.load_configuration(source_filename) source_config = load.load_configuration(source_filename)
normalize.normalize(source_config) normalize.normalize(source_filename, source_config)
destination_config = merge_source_configuration_into_destination( destination_config = merge_source_configuration_into_destination(
_schema_to_sample_configuration(schema), source_config _schema_to_sample_configuration(schema), source_config

View file

@ -36,12 +36,24 @@ def normalize(config_filename, config):
if isinstance(checks, list) and len(checks) and isinstance(checks[0], str): if isinstance(checks, list) and len(checks) and isinstance(checks[0], str):
config['consistency']['checks'] = [{'name': check_type} for check_type in checks] config['consistency']['checks'] = [{'name': check_type} for check_type in checks]
# Rename various configuration options.
numeric_owner = config.get('location', {}).pop('numeric_owner', None)
if numeric_owner is not None:
config['location']['numeric_ids'] = numeric_owner
bsd_flags = config.get('location', {}).pop('bsd_flags', None)
if bsd_flags is not None:
config['location']['flags'] = bsd_flags
remote_rate_limit = config.get('storage', {}).pop('remote_rate_limit', None)
if remote_rate_limit is not None:
config['storage']['upload_rate_limit'] = remote_rate_limit
# Upgrade remote repositories to ssh:// syntax, required in Borg 2. # Upgrade remote repositories to ssh:// syntax, required in Borg 2.
repositories = config.get('location', {}).get('repositories') repositories = config.get('location', {}).get('repositories')
if repositories: if repositories:
config['location']['repositories'] = [] config['location']['repositories'] = []
for repository in repositories: for repository in repositories:
# TODO: Instead of logging directly here, return logs and bubble them up to be displayed *after* logging is initialized.
if '~' in repository: if '~' in repository:
logs.append( logs.append(
logging.makeLogRecord( logging.makeLogRecord(

View file

@ -58,7 +58,7 @@ properties:
database hook is used, the setting here is ignored and database hook is used, the setting here is ignored and
one_file_system is considered true. one_file_system is considered true.
example: true example: true
numeric_owner: numeric_ids:
type: boolean type: boolean
description: | description: |
Only store/extract numeric user and group identifiers. Only store/extract numeric user and group identifiers.
@ -90,10 +90,10 @@ properties:
used, the setting here is ignored and read_special is used, the setting here is ignored and read_special is
considered true. considered true.
example: false example: false
bsd_flags: flags:
type: boolean type: boolean
description: | description: |
Record bsdflags (e.g. NODUMP, IMMUTABLE) in archive. Record filesystem flags (e.g. NODUMP, IMMUTABLE) in archive.
Defaults to true. Defaults to true.
example: true example: true
files_cache: files_cache:
@ -255,7 +255,7 @@ properties:
http://borgbackup.readthedocs.io/en/stable/usage/create.html http://borgbackup.readthedocs.io/en/stable/usage/create.html
for details. Defaults to "lz4". for details. Defaults to "lz4".
example: lz4 example: lz4
remote_rate_limit: upload_rate_limit:
type: integer type: integer
description: | description: |
Remote network upload rate limit in kiBytes/second. Defaults Remote network upload rate limit in kiBytes/second. Defaults

View file

@ -794,7 +794,7 @@ def test_create_archive_with_compression_calls_borg_with_compression_parameters(
@pytest.mark.parametrize( @pytest.mark.parametrize(
'feature_available,option_flag', ((True, '--upload-ratelimit'), (False, '--remote-ratelimit')), 'feature_available,option_flag', ((True, '--upload-ratelimit'), (False, '--remote-ratelimit')),
) )
def test_create_archive_with_remote_rate_limit_calls_borg_with_upload_ratelimit_parameters( def test_create_archive_with_upload_rate_limit_calls_borg_with_upload_ratelimit_parameters(
feature_available, option_flag feature_available, option_flag
): ):
flexmock(module).should_receive('borgmatic_source_directories').and_return([]) flexmock(module).should_receive('borgmatic_source_directories').and_return([])
@ -829,7 +829,7 @@ def test_create_archive_with_remote_rate_limit_calls_borg_with_upload_ratelimit_
'repositories': ['repo'], 'repositories': ['repo'],
'exclude_patterns': None, 'exclude_patterns': None,
}, },
storage_config={'remote_rate_limit': 100}, storage_config={'upload_rate_limit': 100},
local_borg_version='1.2.3', local_borg_version='1.2.3',
) )
@ -917,7 +917,7 @@ def test_create_archive_with_one_file_system_calls_borg_with_one_file_system_par
@pytest.mark.parametrize( @pytest.mark.parametrize(
'feature_available,option_flag', ((True, '--numeric-ids'), (False, '--numeric-owner')), 'feature_available,option_flag', ((True, '--numeric-ids'), (False, '--numeric-owner')),
) )
def test_create_archive_with_numeric_owner_calls_borg_with_numeric_ids_parameter( def test_create_archive_with_numeric_ids_calls_borg_with_numeric_ids_parameter(
feature_available, option_flag feature_available, option_flag
): ):
flexmock(module).should_receive('borgmatic_source_directories').and_return([]) flexmock(module).should_receive('borgmatic_source_directories').and_return([])
@ -950,7 +950,7 @@ def test_create_archive_with_numeric_owner_calls_borg_with_numeric_ids_parameter
location_config={ location_config={
'source_directories': ['foo', 'bar'], 'source_directories': ['foo', 'bar'],
'repositories': ['repo'], 'repositories': ['repo'],
'numeric_owner': True, 'numeric_ids': True,
'exclude_patterns': None, 'exclude_patterns': None,
}, },
storage_config={}, storage_config={},
@ -1102,7 +1102,7 @@ def test_create_archive_with_atime_option_calls_borg_with_corresponding_paramete
(False, False, '--nobsdflags'), (False, False, '--nobsdflags'),
), ),
) )
def test_create_archive_with_bsd_flags_option_calls_borg_with_corresponding_parameter( def test_create_archive_with_flags_option_calls_borg_with_corresponding_parameter(
option_value, feature_available, option_flag option_value, feature_available, option_flag
): ):
flexmock(module).should_receive('borgmatic_source_directories').and_return([]) flexmock(module).should_receive('borgmatic_source_directories').and_return([])
@ -1135,7 +1135,7 @@ def test_create_archive_with_bsd_flags_option_calls_borg_with_corresponding_para
location_config={ location_config={
'source_directories': ['foo', 'bar'], 'source_directories': ['foo', 'bar'],
'repositories': ['repo'], 'repositories': ['repo'],
'bsd_flags': option_value, 'flags': option_value,
'exclude_patterns': None, 'exclude_patterns': None,
}, },
storage_config={}, storage_config={},

View file

@ -174,7 +174,7 @@ def test_extract_archive_calls_borg_with_numeric_ids_parameter(feature_available
repository='repo', repository='repo',
archive='archive', archive='archive',
paths=None, paths=None,
location_config={'numeric_owner': True}, location_config={'numeric_ids': True},
storage_config={}, storage_config={},
local_borg_version='1.2.3', local_borg_version='1.2.3',
) )

View file

@ -51,6 +51,13 @@ from borgmatic.config import normalize as module
{'consistency': {'checks': [{'name': 'archives'}]}}, {'consistency': {'checks': [{'name': 'archives'}]}},
False, False,
), ),
({'location': {'numeric_owner': False}}, {'location': {'numeric_ids': False}}, False,),
({'location': {'bsd_flags': False}}, {'location': {'flags': False}}, False,),
(
{'storage': {'remote_rate_limit': False}},
{'storage': {'upload_rate_limit': False}},
False,
),
( (
{'location': {'repositories': ['foo@bar:/repo']}}, {'location': {'repositories': ['foo@bar:/repo']}},
{'location': {'repositories': ['ssh://foo@bar/repo']}}, {'location': {'repositories': ['ssh://foo@bar/repo']}},