Add a recreate action (#1030).
Reviewed-on: borgmatic-collective/borgmatic#1030
This commit is contained in:
commit
59f9d56aae
8 changed files with 955 additions and 0 deletions
53
borgmatic/actions/recreate.py
Normal file
53
borgmatic/actions/recreate.py
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
import logging
|
||||
|
||||
import borgmatic.borg.recreate
|
||||
import borgmatic.config.validate
|
||||
from borgmatic.actions.create import collect_patterns, process_patterns
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def run_recreate(
|
||||
repository,
|
||||
config,
|
||||
local_borg_version,
|
||||
recreate_arguments,
|
||||
global_arguments,
|
||||
local_path,
|
||||
remote_path,
|
||||
):
|
||||
'''
|
||||
Run the "recreate" action for the given repository.
|
||||
'''
|
||||
if recreate_arguments.repository is None or borgmatic.config.validate.repositories_match(
|
||||
repository, recreate_arguments.repository
|
||||
):
|
||||
if recreate_arguments.archive:
|
||||
logger.answer(f'Recreating archive {recreate_arguments.archive}')
|
||||
else:
|
||||
logger.answer('Recreating repository')
|
||||
|
||||
# Collect and process patterns.
|
||||
processed_patterns = process_patterns(
|
||||
collect_patterns(config), borgmatic.config.paths.get_working_directory(config)
|
||||
)
|
||||
|
||||
borgmatic.borg.recreate.recreate_archive(
|
||||
repository['path'],
|
||||
borgmatic.borg.repo_list.resolve_archive_name(
|
||||
repository['path'],
|
||||
recreate_arguments.archive,
|
||||
config,
|
||||
local_borg_version,
|
||||
global_arguments,
|
||||
local_path,
|
||||
remote_path,
|
||||
),
|
||||
config,
|
||||
local_borg_version,
|
||||
recreate_arguments,
|
||||
global_arguments,
|
||||
local_path=local_path,
|
||||
remote_path=remote_path,
|
||||
patterns=processed_patterns,
|
||||
)
|
||||
100
borgmatic/borg/recreate.py
Normal file
100
borgmatic/borg/recreate.py
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
import logging
|
||||
import shlex
|
||||
|
||||
import borgmatic.borg.environment
|
||||
import borgmatic.config.paths
|
||||
import borgmatic.execute
|
||||
from borgmatic.borg import flags
|
||||
from borgmatic.borg.create import make_exclude_flags, make_list_filter_flags, write_patterns_file
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def recreate_archive(
|
||||
repository,
|
||||
archive,
|
||||
config,
|
||||
local_borg_version,
|
||||
recreate_arguments,
|
||||
global_arguments,
|
||||
local_path,
|
||||
remote_path=None,
|
||||
patterns=None,
|
||||
):
|
||||
'''
|
||||
Given a local or remote repository path, an archive name, a configuration dict,
|
||||
the local Borg version string, an argparse.Namespace of recreate arguments,
|
||||
an argparse.Namespace of global arguments, optional local and remote Borg paths.
|
||||
|
||||
Executes the recreate command with the given arguments.
|
||||
'''
|
||||
|
||||
lock_wait = config.get('lock_wait', None)
|
||||
exclude_flags = make_exclude_flags(config)
|
||||
compression = config.get('compression', None)
|
||||
chunker_params = config.get('chunker_params', None)
|
||||
# Available recompress MODES: 'if-different' (default), 'always', 'never'
|
||||
recompress = config.get('recompress', None)
|
||||
|
||||
# Write patterns to a temporary file and use that file with --patterns-from.
|
||||
patterns_file = write_patterns_file(
|
||||
patterns, borgmatic.config.paths.get_working_directory(config)
|
||||
)
|
||||
|
||||
recreate_command = (
|
||||
(local_path, 'recreate')
|
||||
+ (('--remote-path', remote_path) if remote_path else ())
|
||||
+ (('--log-json',) if global_arguments.log_json else ())
|
||||
+ (('--lock-wait', str(lock_wait)) if lock_wait is not None else ())
|
||||
+ (('--info',) if logger.getEffectiveLevel() == logging.INFO else ())
|
||||
+ (('--debug', '--show-rc') if logger.isEnabledFor(logging.DEBUG) else ())
|
||||
+ (('--patterns-from', patterns_file.name) if patterns_file else ())
|
||||
+ (
|
||||
(
|
||||
'--list',
|
||||
'--filter',
|
||||
make_list_filter_flags(local_borg_version, global_arguments.dry_run),
|
||||
)
|
||||
if recreate_arguments.list
|
||||
else ()
|
||||
)
|
||||
# Flag --target works only for a single archive
|
||||
+ (('--target', recreate_arguments.target) if recreate_arguments.target and archive else ())
|
||||
+ (
|
||||
('--comment', shlex.quote(recreate_arguments.comment))
|
||||
if recreate_arguments.comment
|
||||
else ()
|
||||
)
|
||||
+ (('--timestamp', recreate_arguments.timestamp) if recreate_arguments.timestamp else ())
|
||||
+ (('--compression', compression) if compression else ())
|
||||
+ (('--chunker-params', chunker_params) if chunker_params else ())
|
||||
+ (
|
||||
flags.make_match_archives_flags(
|
||||
recreate_arguments.match_archives or archive or config.get('match_archives'),
|
||||
config.get('archive_name_format'),
|
||||
local_borg_version,
|
||||
)
|
||||
if recreate_arguments.match_archives
|
||||
else ()
|
||||
)
|
||||
+ (('--recompress', recompress) if recompress else ())
|
||||
+ exclude_flags
|
||||
+ (
|
||||
flags.make_repository_archive_flags(repository, archive, local_borg_version)
|
||||
if archive
|
||||
else flags.make_repository_flags(repository, local_borg_version)
|
||||
)
|
||||
)
|
||||
|
||||
if global_arguments.dry_run:
|
||||
logger.info('Skipping the archive recreation (dry run)')
|
||||
return
|
||||
|
||||
borgmatic.execute.execute_command(
|
||||
full_command=recreate_command,
|
||||
output_log_level=logging.INFO,
|
||||
environment=borgmatic.borg.environment.make_environment(config),
|
||||
working_directory=borgmatic.config.paths.get_working_directory(config),
|
||||
borg_local_path=local_path,
|
||||
borg_exit_codes=config.get('borg_exit_codes'),
|
||||
)
|
||||
|
|
@ -27,6 +27,7 @@ ACTION_ALIASES = {
|
|||
'break-lock': [],
|
||||
'key': [],
|
||||
'borg': [],
|
||||
'recreate': [],
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1545,6 +1546,52 @@ def make_parsers():
|
|||
)
|
||||
borg_group.add_argument('-h', '--help', action='help', help='Show this help message and exit')
|
||||
|
||||
recreate_parser = action_parsers.add_parser(
|
||||
'recreate',
|
||||
aliases=ACTION_ALIASES['recreate'],
|
||||
help='Recreate an archive in a repository',
|
||||
description='Recreate an archive in a repository',
|
||||
add_help=False,
|
||||
)
|
||||
recreate_group = recreate_parser.add_argument_group('recreate arguments')
|
||||
recreate_group.add_argument(
|
||||
'--repository',
|
||||
help='Path of repository containing archive to recreate, defaults to the configured repository if there is only one, quoted globs supported',
|
||||
)
|
||||
recreate_group.add_argument(
|
||||
'--archive',
|
||||
help='Archive name, hash, or series to recreate',
|
||||
)
|
||||
recreate_group.add_argument(
|
||||
'--list', dest='list', action='store_true', help='Show per-file details'
|
||||
)
|
||||
recreate_group.add_argument(
|
||||
'--target',
|
||||
metavar='TARGET',
|
||||
help='Create a new archive from the specified archive (via --archive), without replacing it',
|
||||
)
|
||||
recreate_group.add_argument(
|
||||
'--comment',
|
||||
metavar='COMMENT',
|
||||
help='Add a comment text to the archive or, if an archive is not provided, to all matching archives',
|
||||
)
|
||||
recreate_group.add_argument(
|
||||
'--timestamp',
|
||||
metavar='TIMESTAMP',
|
||||
help='Manually override the archive creation date/time (UTC)',
|
||||
)
|
||||
recreate_group.add_argument(
|
||||
'-a',
|
||||
'--match-archives',
|
||||
'--glob-archives',
|
||||
dest='match_archives',
|
||||
metavar='PATTERN',
|
||||
help='Only consider archive names, hashes, or series matching this pattern',
|
||||
)
|
||||
recreate_group.add_argument(
|
||||
'-h', '--help', action='help', help='Show this help message and exit'
|
||||
)
|
||||
|
||||
return global_parser, action_parsers, global_plus_action_parser
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import borgmatic.actions.info
|
|||
import borgmatic.actions.list
|
||||
import borgmatic.actions.mount
|
||||
import borgmatic.actions.prune
|
||||
import borgmatic.actions.recreate
|
||||
import borgmatic.actions.repo_create
|
||||
import borgmatic.actions.repo_delete
|
||||
import borgmatic.actions.repo_info
|
||||
|
|
@ -397,6 +398,16 @@ def run_actions(
|
|||
local_path,
|
||||
remote_path,
|
||||
)
|
||||
elif action_name == 'recreate' and action_name not in skip_actions:
|
||||
borgmatic.actions.recreate.run_recreate(
|
||||
repository,
|
||||
config,
|
||||
local_borg_version,
|
||||
action_arguments,
|
||||
global_arguments,
|
||||
local_path,
|
||||
remote_path,
|
||||
)
|
||||
elif action_name == 'prune' and action_name not in skip_actions:
|
||||
borgmatic.actions.prune.run_prune(
|
||||
config_filename,
|
||||
|
|
|
|||
|
|
@ -284,6 +284,23 @@ properties:
|
|||
http://borgbackup.readthedocs.io/en/stable/usage/create.html for
|
||||
details. Defaults to "lz4".
|
||||
example: lz4
|
||||
recompress:
|
||||
type: string
|
||||
enum: ['if-different', 'always', 'never']
|
||||
description: |
|
||||
Mode for recompressing data chunks according to MODE.
|
||||
Possible modes are:
|
||||
- "if-different": Recompress if the current compression
|
||||
is with a different compression algorithm.
|
||||
- "always": Recompress even if the current compression
|
||||
is with the same compression algorithm. Use this to change
|
||||
the compression level.
|
||||
- "never": Do not recompress. Use this option to explicitly
|
||||
prevent recompression.
|
||||
See https://borgbackup.readthedocs.io/en/stable/usage/recreate.html
|
||||
for details.
|
||||
Defaults to "never".
|
||||
example: if-different
|
||||
upload_rate_limit:
|
||||
type: integer
|
||||
description: |
|
||||
|
|
@ -767,6 +784,7 @@ properties:
|
|||
- prune
|
||||
- compact
|
||||
- create
|
||||
- recreate
|
||||
- check
|
||||
- delete
|
||||
- extract
|
||||
|
|
@ -982,6 +1000,7 @@ properties:
|
|||
- prune
|
||||
- compact
|
||||
- create
|
||||
- recreate
|
||||
- check
|
||||
- delete
|
||||
- extract
|
||||
|
|
@ -1046,6 +1065,7 @@ properties:
|
|||
- prune
|
||||
- compact
|
||||
- create
|
||||
- recreate
|
||||
- check
|
||||
- delete
|
||||
- extract
|
||||
|
|
|
|||
39
tests/unit/actions/test_recreate.py
Normal file
39
tests/unit/actions/test_recreate.py
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
from flexmock import flexmock
|
||||
|
||||
from borgmatic.actions import recreate as module
|
||||
|
||||
|
||||
def test_run_recreate_does_not_raise():
|
||||
flexmock(module.logger).answer = lambda message: None
|
||||
flexmock(module.borgmatic.config.validate).should_receive('repositories_match').and_return(True)
|
||||
flexmock(module.borgmatic.borg.recreate).should_receive('recreate_archive')
|
||||
|
||||
recreate_arguments = flexmock(repository=flexmock(), archive=None)
|
||||
|
||||
module.run_recreate(
|
||||
repository={'path': 'repo'},
|
||||
config={},
|
||||
local_borg_version=None,
|
||||
recreate_arguments=recreate_arguments,
|
||||
global_arguments=flexmock(),
|
||||
local_path=None,
|
||||
remote_path=None,
|
||||
)
|
||||
|
||||
|
||||
def test_run_recreate_with_archive_does_not_raise():
|
||||
flexmock(module.logger).answer = lambda message: None
|
||||
flexmock(module.borgmatic.config.validate).should_receive('repositories_match').and_return(True)
|
||||
flexmock(module.borgmatic.borg.recreate).should_receive('recreate_archive')
|
||||
|
||||
recreate_arguments = flexmock(repository=flexmock(), archive='test-archive')
|
||||
|
||||
module.run_recreate(
|
||||
repository={'path': 'repo'},
|
||||
config={},
|
||||
local_borg_version=None,
|
||||
recreate_arguments=recreate_arguments,
|
||||
global_arguments=flexmock(),
|
||||
local_path=None,
|
||||
remote_path=None,
|
||||
)
|
||||
644
tests/unit/borg/test_recreate.py
Normal file
644
tests/unit/borg/test_recreate.py
Normal file
|
|
@ -0,0 +1,644 @@
|
|||
import logging
|
||||
import shlex
|
||||
|
||||
from flexmock import flexmock
|
||||
|
||||
from borgmatic.borg import recreate as module
|
||||
|
||||
from ..test_verbosity import insert_logging_mock
|
||||
|
||||
|
||||
def insert_execute_command_mock(command, working_directory=None, borg_exit_codes=None):
|
||||
flexmock(module.borgmatic.borg.environment).should_receive('make_environment')
|
||||
flexmock(module.borgmatic.execute).should_receive('execute_command').with_args(
|
||||
full_command=command,
|
||||
output_log_level=module.logging.INFO,
|
||||
environment=None,
|
||||
working_directory=working_directory,
|
||||
borg_local_path=command[0],
|
||||
borg_exit_codes=borg_exit_codes,
|
||||
).once()
|
||||
|
||||
|
||||
def mock_dependencies():
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_exclude_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.create).should_receive('write_patterns_file').and_return(None)
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_list_filter_flags').and_return('')
|
||||
flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.flags).should_receive(
|
||||
'make_repository_archive_flags'
|
||||
).and_return(('repo::archive',))
|
||||
|
||||
|
||||
def test_recreate_archive_dry_run_skips_execution():
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_exclude_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.create).should_receive('write_patterns_file').and_return(None)
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_list_filter_flags').and_return('')
|
||||
flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.flags).should_receive(
|
||||
'make_repository_archive_flags'
|
||||
).and_return(('repo::archive',))
|
||||
flexmock(module.borgmatic.execute).should_receive('execute_command').never()
|
||||
|
||||
recreate_arguments = flexmock(
|
||||
repository=flexmock(),
|
||||
list=None,
|
||||
target=None,
|
||||
comment=None,
|
||||
timestamp=None,
|
||||
match_archives=None,
|
||||
)
|
||||
|
||||
result = module.recreate_archive(
|
||||
repository='repo',
|
||||
archive='archive',
|
||||
config={},
|
||||
local_borg_version='1.2.3',
|
||||
recreate_arguments=recreate_arguments,
|
||||
global_arguments=flexmock(log_json=False, dry_run=True),
|
||||
local_path='borg',
|
||||
)
|
||||
|
||||
assert result is None
|
||||
|
||||
|
||||
def test_recreate_calls_borg_with_required_flags():
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_exclude_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.create).should_receive('write_patterns_file').and_return(None)
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_list_filter_flags').and_return('')
|
||||
flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.flags).should_receive(
|
||||
'make_repository_archive_flags'
|
||||
).and_return(('repo::archive',))
|
||||
insert_execute_command_mock(('borg', 'recreate', 'repo::archive'))
|
||||
|
||||
module.recreate_archive(
|
||||
repository='repo',
|
||||
archive='archive',
|
||||
config={},
|
||||
local_borg_version='1.2.3',
|
||||
recreate_arguments=flexmock(
|
||||
list=None,
|
||||
target=None,
|
||||
comment=None,
|
||||
timestamp=None,
|
||||
match_archives=None,
|
||||
),
|
||||
global_arguments=flexmock(dry_run=False, log_json=False),
|
||||
local_path='borg',
|
||||
remote_path=None,
|
||||
patterns=None,
|
||||
)
|
||||
|
||||
|
||||
def test_recreate_with_remote_path():
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_exclude_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.create).should_receive('write_patterns_file').and_return(None)
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_list_filter_flags').and_return('')
|
||||
flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.flags).should_receive(
|
||||
'make_repository_archive_flags'
|
||||
).and_return(('repo::archive',))
|
||||
insert_execute_command_mock(('borg', 'recreate', '--remote-path', 'borg1', 'repo::archive'))
|
||||
|
||||
module.recreate_archive(
|
||||
repository='repo',
|
||||
archive='archive',
|
||||
config={},
|
||||
local_borg_version='1.2.3',
|
||||
recreate_arguments=flexmock(
|
||||
list=None,
|
||||
target=None,
|
||||
comment=None,
|
||||
timestamp=None,
|
||||
match_archives=None,
|
||||
),
|
||||
global_arguments=flexmock(dry_run=False, log_json=False),
|
||||
local_path='borg',
|
||||
remote_path='borg1',
|
||||
patterns=None,
|
||||
)
|
||||
|
||||
|
||||
def test_recreate_with_lock_wait():
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_exclude_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.create).should_receive('write_patterns_file').and_return(None)
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_list_filter_flags').and_return('')
|
||||
flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.flags).should_receive(
|
||||
'make_repository_archive_flags'
|
||||
).and_return(('repo::archive',))
|
||||
insert_execute_command_mock(('borg', 'recreate', '--lock-wait', '5', 'repo::archive'))
|
||||
|
||||
module.recreate_archive(
|
||||
repository='repo',
|
||||
archive='archive',
|
||||
config={'lock_wait': '5'},
|
||||
local_borg_version='1.2.3',
|
||||
recreate_arguments=flexmock(
|
||||
list=None,
|
||||
target=None,
|
||||
comment=None,
|
||||
timestamp=None,
|
||||
match_archives=None,
|
||||
),
|
||||
global_arguments=flexmock(dry_run=False, log_json=False),
|
||||
local_path='borg',
|
||||
patterns=None,
|
||||
)
|
||||
|
||||
|
||||
def test_recreate_with_log_info():
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_exclude_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.create).should_receive('write_patterns_file').and_return(None)
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_list_filter_flags').and_return('')
|
||||
flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.flags).should_receive(
|
||||
'make_repository_archive_flags'
|
||||
).and_return(('repo::archive',))
|
||||
insert_execute_command_mock(('borg', 'recreate', '--info', 'repo::archive'))
|
||||
|
||||
insert_logging_mock(logging.INFO)
|
||||
|
||||
module.recreate_archive(
|
||||
repository='repo',
|
||||
archive='archive',
|
||||
config={},
|
||||
local_borg_version='1.2.3',
|
||||
recreate_arguments=flexmock(
|
||||
list=None,
|
||||
target=None,
|
||||
comment=None,
|
||||
timestamp=None,
|
||||
match_archives=None,
|
||||
),
|
||||
global_arguments=flexmock(dry_run=False, log_json=False),
|
||||
local_path='borg',
|
||||
patterns=None,
|
||||
)
|
||||
|
||||
|
||||
def test_recreate_with_log_debug():
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_exclude_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.create).should_receive('write_patterns_file').and_return(None)
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_list_filter_flags').and_return('')
|
||||
flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.flags).should_receive(
|
||||
'make_repository_archive_flags'
|
||||
).and_return(('repo::archive',))
|
||||
insert_execute_command_mock(('borg', 'recreate', '--debug', '--show-rc', 'repo::archive'))
|
||||
insert_logging_mock(logging.DEBUG)
|
||||
|
||||
module.recreate_archive(
|
||||
repository='repo',
|
||||
archive='archive',
|
||||
config={},
|
||||
local_borg_version='1.2.3',
|
||||
recreate_arguments=flexmock(
|
||||
list=None,
|
||||
target=None,
|
||||
comment=None,
|
||||
timestamp=None,
|
||||
match_archives=None,
|
||||
),
|
||||
global_arguments=flexmock(dry_run=False, log_json=False),
|
||||
local_path='borg',
|
||||
patterns=None,
|
||||
)
|
||||
|
||||
|
||||
def test_recreate_with_log_json():
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_exclude_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.create).should_receive('write_patterns_file').and_return(None)
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_list_filter_flags').and_return('')
|
||||
flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.flags).should_receive(
|
||||
'make_repository_archive_flags'
|
||||
).and_return(('repo::archive',))
|
||||
insert_execute_command_mock(('borg', 'recreate', '--log-json', 'repo::archive'))
|
||||
|
||||
module.recreate_archive(
|
||||
repository='repo',
|
||||
archive='archive',
|
||||
config={},
|
||||
local_borg_version='1.2.3',
|
||||
recreate_arguments=flexmock(
|
||||
list=None,
|
||||
target=None,
|
||||
comment=None,
|
||||
timestamp=None,
|
||||
match_archives=None,
|
||||
),
|
||||
global_arguments=flexmock(dry_run=False, log_json=True),
|
||||
local_path='borg',
|
||||
patterns=None,
|
||||
)
|
||||
|
||||
|
||||
def test_recreate_with_list_filter_flags():
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_exclude_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.create).should_receive('write_patterns_file').and_return(None)
|
||||
flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.flags).should_receive(
|
||||
'make_repository_archive_flags'
|
||||
).and_return(('repo::archive',))
|
||||
flexmock(module).should_receive('make_list_filter_flags').and_return('AME+-')
|
||||
insert_execute_command_mock(
|
||||
('borg', 'recreate', '--list', '--filter', 'AME+-', 'repo::archive')
|
||||
)
|
||||
|
||||
module.recreate_archive(
|
||||
repository='repo',
|
||||
archive='archive',
|
||||
config={},
|
||||
local_borg_version='1.2.3',
|
||||
recreate_arguments=flexmock(
|
||||
list=True,
|
||||
target=None,
|
||||
comment=None,
|
||||
timestamp=None,
|
||||
match_archives=None,
|
||||
),
|
||||
global_arguments=flexmock(dry_run=False, log_json=False),
|
||||
local_path='borg',
|
||||
patterns=None,
|
||||
)
|
||||
|
||||
|
||||
def test_recreate_with_patterns_from_flag():
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_exclude_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_list_filter_flags').and_return('')
|
||||
flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.flags).should_receive(
|
||||
'make_repository_archive_flags'
|
||||
).and_return(('repo::archive',))
|
||||
mock_patterns_file = flexmock(name='patterns_file')
|
||||
flexmock(module).should_receive('write_patterns_file').and_return(mock_patterns_file)
|
||||
insert_execute_command_mock(
|
||||
('borg', 'recreate', '--patterns-from', 'patterns_file', 'repo::archive')
|
||||
)
|
||||
|
||||
module.recreate_archive(
|
||||
repository='repo',
|
||||
archive='archive',
|
||||
config={},
|
||||
local_borg_version='1.2.3',
|
||||
recreate_arguments=flexmock(
|
||||
list=None,
|
||||
target=None,
|
||||
comment=None,
|
||||
timestamp=None,
|
||||
match_archives=None,
|
||||
),
|
||||
global_arguments=flexmock(dry_run=False, log_json=False),
|
||||
local_path='borg',
|
||||
patterns=['pattern1', 'pattern2'],
|
||||
)
|
||||
|
||||
|
||||
def test_recreate_with_exclude_flags():
|
||||
flexmock(module.borgmatic.borg.create).should_receive('write_patterns_file').and_return(None)
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_list_filter_flags').and_return('')
|
||||
flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.flags).should_receive(
|
||||
'make_repository_archive_flags'
|
||||
).and_return(('repo::archive',))
|
||||
flexmock(module).should_receive('make_exclude_flags').and_return(('--exclude', 'pattern'))
|
||||
insert_execute_command_mock(('borg', 'recreate', '--exclude', 'pattern', 'repo::archive'))
|
||||
|
||||
module.recreate_archive(
|
||||
repository='repo',
|
||||
archive='archive',
|
||||
config={'exclude_patterns': ['pattern']},
|
||||
local_borg_version='1.2.3',
|
||||
recreate_arguments=flexmock(
|
||||
list=None,
|
||||
target=None,
|
||||
comment=None,
|
||||
timestamp=None,
|
||||
match_archives=None,
|
||||
),
|
||||
global_arguments=flexmock(dry_run=False, log_json=False),
|
||||
local_path='borg',
|
||||
patterns=None,
|
||||
)
|
||||
|
||||
|
||||
def test_recreate_with_target_flag():
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_exclude_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.create).should_receive('write_patterns_file').and_return(None)
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_list_filter_flags').and_return('')
|
||||
flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.flags).should_receive(
|
||||
'make_repository_archive_flags'
|
||||
).and_return(('repo::archive',))
|
||||
insert_execute_command_mock(('borg', 'recreate', '--target', 'new-archive', 'repo::archive'))
|
||||
|
||||
module.recreate_archive(
|
||||
repository='repo',
|
||||
archive='archive',
|
||||
config={},
|
||||
local_borg_version='1.2.3',
|
||||
recreate_arguments=flexmock(
|
||||
list=None,
|
||||
target='new-archive',
|
||||
comment=None,
|
||||
timestamp=None,
|
||||
match_archives=None,
|
||||
),
|
||||
global_arguments=flexmock(dry_run=False, log_json=False),
|
||||
local_path='borg',
|
||||
patterns=None,
|
||||
)
|
||||
|
||||
|
||||
def test_recreate_with_comment_flag():
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_exclude_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.create).should_receive('write_patterns_file').and_return(None)
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_list_filter_flags').and_return('')
|
||||
flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.flags).should_receive(
|
||||
'make_repository_archive_flags'
|
||||
).and_return(('repo::archive',))
|
||||
insert_execute_command_mock(
|
||||
('borg', 'recreate', '--comment', shlex.quote('This is a test comment'), 'repo::archive')
|
||||
)
|
||||
|
||||
module.recreate_archive(
|
||||
repository='repo',
|
||||
archive='archive',
|
||||
config={},
|
||||
local_borg_version='1.2.3',
|
||||
recreate_arguments=flexmock(
|
||||
list=None,
|
||||
target=None,
|
||||
comment='This is a test comment',
|
||||
timestamp=None,
|
||||
match_archives=None,
|
||||
),
|
||||
global_arguments=flexmock(dry_run=False, log_json=False),
|
||||
local_path='borg',
|
||||
patterns=None,
|
||||
)
|
||||
|
||||
|
||||
def test_recreate_with_timestamp_flag():
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_exclude_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.create).should_receive('write_patterns_file').and_return(None)
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_list_filter_flags').and_return('')
|
||||
flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.flags).should_receive(
|
||||
'make_repository_archive_flags'
|
||||
).and_return(('repo::archive',))
|
||||
insert_execute_command_mock(
|
||||
('borg', 'recreate', '--timestamp', '2023-10-01T12:00:00', 'repo::archive')
|
||||
)
|
||||
|
||||
module.recreate_archive(
|
||||
repository='repo',
|
||||
archive='archive',
|
||||
config={},
|
||||
local_borg_version='1.2.3',
|
||||
recreate_arguments=flexmock(
|
||||
list=None,
|
||||
target=None,
|
||||
comment=None,
|
||||
timestamp='2023-10-01T12:00:00',
|
||||
match_archives=None,
|
||||
),
|
||||
global_arguments=flexmock(dry_run=False, log_json=False),
|
||||
local_path='borg',
|
||||
patterns=None,
|
||||
)
|
||||
|
||||
|
||||
def test_recreate_with_compression_flag():
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_exclude_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.create).should_receive('write_patterns_file').and_return(None)
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_list_filter_flags').and_return('')
|
||||
flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.flags).should_receive(
|
||||
'make_repository_archive_flags'
|
||||
).and_return(('repo::archive',))
|
||||
insert_execute_command_mock(('borg', 'recreate', '--compression', 'lz4', 'repo::archive'))
|
||||
|
||||
module.recreate_archive(
|
||||
repository='repo',
|
||||
archive='archive',
|
||||
config={'compression': 'lz4'},
|
||||
local_borg_version='1.2.3',
|
||||
recreate_arguments=flexmock(
|
||||
list=None,
|
||||
target=None,
|
||||
comment=None,
|
||||
timestamp=None,
|
||||
match_archives=None,
|
||||
),
|
||||
global_arguments=flexmock(dry_run=False, log_json=False),
|
||||
local_path='borg',
|
||||
patterns=None,
|
||||
)
|
||||
|
||||
|
||||
def test_recreate_with_chunker_params_flag():
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_exclude_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.create).should_receive('write_patterns_file').and_return(None)
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_list_filter_flags').and_return('')
|
||||
flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.flags).should_receive(
|
||||
'make_repository_archive_flags'
|
||||
).and_return(('repo::archive',))
|
||||
insert_execute_command_mock(
|
||||
('borg', 'recreate', '--chunker-params', '19,23,21,4095', 'repo::archive')
|
||||
)
|
||||
|
||||
module.recreate_archive(
|
||||
repository='repo',
|
||||
archive='archive',
|
||||
config={'chunker_params': '19,23,21,4095'},
|
||||
local_borg_version='1.2.3',
|
||||
recreate_arguments=flexmock(
|
||||
list=None,
|
||||
target=None,
|
||||
comment=None,
|
||||
timestamp=None,
|
||||
match_archives=None,
|
||||
),
|
||||
global_arguments=flexmock(dry_run=False, log_json=False),
|
||||
local_path='borg',
|
||||
patterns=None,
|
||||
)
|
||||
|
||||
|
||||
def test_recreate_with_recompress_flag():
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_exclude_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.create).should_receive('write_patterns_file').and_return(None)
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_list_filter_flags').and_return('')
|
||||
flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.flags).should_receive(
|
||||
'make_repository_archive_flags'
|
||||
).and_return(('repo::archive',))
|
||||
insert_execute_command_mock(('borg', 'recreate', '--recompress', 'always', 'repo::archive'))
|
||||
|
||||
module.recreate_archive(
|
||||
repository='repo',
|
||||
archive='archive',
|
||||
config={'recompress': 'always'},
|
||||
local_borg_version='1.2.3',
|
||||
recreate_arguments=flexmock(
|
||||
list=None,
|
||||
target=None,
|
||||
comment=None,
|
||||
timestamp=None,
|
||||
match_archives=None,
|
||||
),
|
||||
global_arguments=flexmock(dry_run=False, log_json=False),
|
||||
local_path='borg',
|
||||
patterns=None,
|
||||
)
|
||||
|
||||
|
||||
def test_recreate_with_match_archives_star():
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_exclude_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.create).should_receive('write_patterns_file').and_return(None)
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_list_filter_flags').and_return('')
|
||||
flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.flags).should_receive(
|
||||
'make_repository_archive_flags'
|
||||
).and_return(('repo::archive',))
|
||||
insert_execute_command_mock(('borg', 'recreate', 'repo::archive'))
|
||||
|
||||
module.recreate_archive(
|
||||
repository='repo',
|
||||
archive='archive',
|
||||
config={},
|
||||
local_borg_version='1.2.3',
|
||||
recreate_arguments=flexmock(
|
||||
list=None,
|
||||
target=None,
|
||||
comment=None,
|
||||
timestamp=None,
|
||||
match_archives='*',
|
||||
),
|
||||
global_arguments=flexmock(dry_run=False, log_json=False),
|
||||
local_path='borg',
|
||||
patterns=None,
|
||||
)
|
||||
|
||||
|
||||
def test_recreate_with_match_archives_regex():
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_exclude_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.create).should_receive('write_patterns_file').and_return(None)
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_list_filter_flags').and_return('')
|
||||
flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.flags).should_receive(
|
||||
'make_repository_archive_flags'
|
||||
).and_return(('repo::archive',))
|
||||
insert_execute_command_mock(('borg', 'recreate', 'repo::archive'))
|
||||
|
||||
module.recreate_archive(
|
||||
repository='repo',
|
||||
archive='archive',
|
||||
config={},
|
||||
local_borg_version='1.2.3',
|
||||
recreate_arguments=flexmock(
|
||||
list=None,
|
||||
target=None,
|
||||
comment=None,
|
||||
timestamp=None,
|
||||
match_archives='re:.*',
|
||||
),
|
||||
global_arguments=flexmock(dry_run=False, log_json=False),
|
||||
local_path='borg',
|
||||
patterns=None,
|
||||
)
|
||||
|
||||
|
||||
def test_recreate_with_match_archives_shell():
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_exclude_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.create).should_receive('write_patterns_file').and_return(None)
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_list_filter_flags').and_return('')
|
||||
flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.flags).should_receive(
|
||||
'make_repository_archive_flags'
|
||||
).and_return(('repo::archive',))
|
||||
insert_execute_command_mock(('borg', 'recreate', 'repo::archive'))
|
||||
|
||||
module.recreate_archive(
|
||||
repository='repo',
|
||||
archive='archive',
|
||||
config={},
|
||||
local_borg_version='1.2.3',
|
||||
recreate_arguments=flexmock(
|
||||
list=None,
|
||||
target=None,
|
||||
comment=None,
|
||||
timestamp=None,
|
||||
match_archives='sh:*',
|
||||
),
|
||||
global_arguments=flexmock(dry_run=False, log_json=False),
|
||||
local_path='borg',
|
||||
patterns=None,
|
||||
)
|
||||
|
||||
|
||||
def test_recreate_with_glob_archives_flag():
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_exclude_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.create).should_receive('write_patterns_file').and_return(None)
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_list_filter_flags').and_return('')
|
||||
flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(
|
||||
('--glob-archives', 'foo-*')
|
||||
)
|
||||
flexmock(module.borgmatic.borg.flags).should_receive(
|
||||
'make_repository_archive_flags'
|
||||
).and_return(('repo::archive',))
|
||||
insert_execute_command_mock(('borg', 'recreate', '--glob-archives', 'foo-*', 'repo::archive'))
|
||||
|
||||
module.recreate_archive(
|
||||
repository='repo',
|
||||
archive='archive',
|
||||
config={},
|
||||
local_borg_version='1.2.3',
|
||||
recreate_arguments=flexmock(
|
||||
list=None,
|
||||
target=None,
|
||||
comment=None,
|
||||
timestamp=None,
|
||||
match_archives='foo-*',
|
||||
),
|
||||
global_arguments=flexmock(dry_run=False, log_json=False),
|
||||
local_path='borg',
|
||||
patterns=None,
|
||||
)
|
||||
|
||||
|
||||
def test_recreate_with_match_archives_flag():
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_exclude_flags').and_return(())
|
||||
flexmock(module.borgmatic.borg.create).should_receive('write_patterns_file').and_return(None)
|
||||
flexmock(module.borgmatic.borg.create).should_receive('make_list_filter_flags').and_return('')
|
||||
flexmock(module.borgmatic.borg.flags).should_receive('make_match_archives_flags').and_return(
|
||||
('--match-archives', 'sh:foo-*')
|
||||
)
|
||||
flexmock(module.borgmatic.borg.flags).should_receive(
|
||||
'make_repository_archive_flags'
|
||||
).and_return(('--repo', 'repo', 'archive'))
|
||||
insert_execute_command_mock(
|
||||
('borg', 'recreate', '--match-archives', 'sh:foo-*', '--repo', 'repo', 'archive')
|
||||
)
|
||||
|
||||
module.recreate_archive(
|
||||
repository='repo',
|
||||
archive='archive',
|
||||
config={},
|
||||
local_borg_version='2.0.0b3',
|
||||
recreate_arguments=flexmock(
|
||||
list=None,
|
||||
target=None,
|
||||
comment=None,
|
||||
timestamp=None,
|
||||
match_archives='sh:foo-*',
|
||||
),
|
||||
global_arguments=flexmock(dry_run=False, log_json=False),
|
||||
local_path='borg',
|
||||
patterns=None,
|
||||
)
|
||||
|
|
@ -1039,6 +1039,47 @@ def test_run_actions_with_skip_actions_skips_create():
|
|||
)
|
||||
|
||||
|
||||
def test_run_actions_runs_recreate():
|
||||
flexmock(module).should_receive('add_custom_log_levels')
|
||||
flexmock(module).should_receive('get_skip_actions').and_return([])
|
||||
flexmock(module.command).should_receive('Before_after_hooks').and_return(flexmock())
|
||||
|
||||
flexmock(borgmatic.actions.recreate).should_receive('run_recreate').once()
|
||||
|
||||
tuple(
|
||||
module.run_actions(
|
||||
arguments={'global': flexmock(dry_run=False, log_file='foo'), 'recreate': flexmock()},
|
||||
config_filename=flexmock(),
|
||||
config={'repositories': []},
|
||||
config_paths=[],
|
||||
local_path=flexmock(),
|
||||
remote_path=flexmock(),
|
||||
local_borg_version=flexmock(),
|
||||
repository={'path': 'repo'},
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def test_run_actions_with_skip_actions_skips_recreate():
|
||||
flexmock(module).should_receive('add_custom_log_levels')
|
||||
flexmock(module).should_receive('get_skip_actions').and_return(['recreate'])
|
||||
flexmock(module.command).should_receive('Before_after_hooks').and_return(flexmock())
|
||||
flexmock(borgmatic.actions.recreate).should_receive('run_recreate').never()
|
||||
|
||||
tuple(
|
||||
module.run_actions(
|
||||
arguments={'global': flexmock(dry_run=False, log_file='foo'), 'recreate': flexmock()},
|
||||
config_filename=flexmock(),
|
||||
config={'repositories': [], 'skip_actions': ['recreate']},
|
||||
config_paths=[],
|
||||
local_path=flexmock(),
|
||||
remote_path=flexmock(),
|
||||
local_borg_version=flexmock(),
|
||||
repository={'path': 'repo'},
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def test_run_actions_runs_prune():
|
||||
flexmock(module).should_receive('add_custom_log_levels')
|
||||
flexmock(module).should_receive('get_skip_actions').and_return([])
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue