forked from borgmatic-collective/borgmatic
Compare commits
32 Commits
79e4e089ee
...
5cea1e1b72
| Author | SHA1 | Date | |
|---|---|---|---|
| 5cea1e1b72 | |||
| 5716e61f8f | |||
| 65d1b9235d | |||
| a8362f2618 | |||
| 36265eea7d | |||
| da324ebeb7 | |||
| 59f9d56aae | |||
|
|
dbf2e78f62 | ||
|
|
2716d9d0b0 | ||
| 0182dbd914 | |||
|
|
8b3a682edf | ||
|
|
7020f0530a | ||
|
|
26fd41da92 | ||
| 088da19012 | |||
| 486bec698d | |||
| 7a766c717e | |||
| 520fb78a00 | |||
|
|
acc2814f11 | ||
| 996b037946 | |||
|
|
9356924418 | ||
|
|
203e84b91f | ||
|
|
ea5a2d8a46 | ||
|
|
a8726c408a | ||
|
|
3542673446 | ||
|
|
b60cf2449a | ||
|
|
e7f14bca87 | ||
|
|
fa3b140590 | ||
|
|
a1d2f7f221 | ||
|
|
a750d58a2d | ||
| 2045706faa | |||
|
|
4e2805918d | ||
|
|
6adb0fd44c |
4
NEWS
4
NEWS
@@ -1,6 +1,10 @@
|
||||
2.0.0.dev0
|
||||
* #262: Add a "default_actions" option that supports disabling default actions when borgmatic is
|
||||
run without any command-line arguments.
|
||||
* #345: Add a "key import" action to import a repository key from backup.
|
||||
* #422: Add home directory expansion to file-based and KeePassXC credential hooks.
|
||||
* #610: Add a "recreate" action for recreating archives, for instance for retroactively excluding
|
||||
particular files from existing archives.
|
||||
* #790, #821: Deprecate all "before_*", "after_*" and "on_error" command hooks in favor of more
|
||||
flexible "commands:". See the documentation for more information:
|
||||
https://torsion.org/borgmatic/docs/how-to/add-preparation-and-cleanup-steps-to-backups/
|
||||
|
||||
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': [],
|
||||
}
|
||||
|
||||
|
||||
@@ -1521,6 +1522,52 @@ def make_parsers():
|
||||
'-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'
|
||||
)
|
||||
|
||||
borg_parser = action_parsers.add_parser(
|
||||
'borg',
|
||||
aliases=ACTION_ALIASES['borg'],
|
||||
|
||||
@@ -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,
|
||||
@@ -943,6 +954,19 @@ def exit_with_help_link(): # pragma: no cover
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def check_and_show_help_on_no_args(configs):
|
||||
'''
|
||||
Check if the borgmatic command is run without any arguments. If the configuration option
|
||||
"default_actions" is set to False, show the help message. Otherwise, trigger the default backup
|
||||
behavior.
|
||||
'''
|
||||
if len(sys.argv) == 1: # No arguments provided
|
||||
default_actions = any(config.get('default_actions', True) for config in configs.values())
|
||||
if not default_actions:
|
||||
parse_arguments('--help')
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
def main(extra_summary_logs=[]): # pragma: no cover
|
||||
configure_signals()
|
||||
configure_delayed_logging()
|
||||
@@ -978,6 +1002,10 @@ def main(extra_summary_logs=[]): # pragma: no cover
|
||||
global_arguments.overrides,
|
||||
resolve_env=global_arguments.resolve_env and not validate,
|
||||
)
|
||||
|
||||
# Use the helper function to check and show help on no arguments, passing the preloaded configs
|
||||
check_and_show_help_on_no_args(configs)
|
||||
|
||||
configuration_parse_errors = (
|
||||
(max(log.levelno for log in parse_logs) >= logging.CRITICAL) if parse_logs else False
|
||||
)
|
||||
|
||||
@@ -284,6 +284,22 @@ 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 +783,7 @@ properties:
|
||||
- prune
|
||||
- compact
|
||||
- create
|
||||
- recreate
|
||||
- check
|
||||
- delete
|
||||
- extract
|
||||
@@ -982,6 +999,7 @@ properties:
|
||||
- prune
|
||||
- compact
|
||||
- create
|
||||
- recreate
|
||||
- check
|
||||
- delete
|
||||
- extract
|
||||
@@ -1046,6 +1064,7 @@ properties:
|
||||
- prune
|
||||
- compact
|
||||
- create
|
||||
- recreate
|
||||
- check
|
||||
- delete
|
||||
- extract
|
||||
@@ -2666,3 +2685,11 @@ properties:
|
||||
example: /usr/local/bin/keepassxc-cli
|
||||
description: |
|
||||
Configuration for integration with the KeePassXC password manager.
|
||||
default_actions:
|
||||
type: boolean
|
||||
description: |
|
||||
Whether to apply default actions (e.g., backup) when no arguments
|
||||
are supplied to the borgmatic command. If set to true, borgmatic
|
||||
triggers the default actions (create, prune, compact and check). If
|
||||
set to false, borgmatic displays the help message instead.
|
||||
example: true
|
||||
|
||||
@@ -4,7 +4,7 @@ COPY . /app
|
||||
RUN apk add --no-cache py3-pip py3-ruamel.yaml py3-ruamel.yaml.clib
|
||||
RUN pip install --break-system-packages --no-cache /app && borgmatic config generate && chmod +r /etc/borgmatic/config.yaml
|
||||
RUN borgmatic --help > /command-line.txt \
|
||||
&& for action in repo-create transfer create prune compact check delete extract config "config bootstrap" "config generate" "config validate" export-tar mount umount repo-delete restore repo-list list repo-info info break-lock "key export" "key change-passphrase" borg; do \
|
||||
&& for action in repo-create transfer create prune compact check delete extract config "config bootstrap" "config generate" "config validate" export-tar mount umount repo-delete restore repo-list list repo-info info break-lock "key export" "key import" "key change-passphrase" recreate borg; do \
|
||||
echo -e "\n--------------------------------------------------------------------------------\n" >> /command-line.txt \
|
||||
&& borgmatic $action --help >> /command-line.txt; done
|
||||
RUN /app/docs/fetch-contributors >> /contributors.html
|
||||
|
||||
@@ -296,6 +296,20 @@ skip_actions:
|
||||
- compact
|
||||
```
|
||||
|
||||
### Disabling default actions
|
||||
|
||||
By default, running `borgmatic` without any arguments will perform the default
|
||||
backup actions (create, prune, compact and check). If you want to disable this
|
||||
behavior and require explicit actions to be specified, add the following to
|
||||
your configuration:
|
||||
|
||||
```yaml
|
||||
default_actions: false
|
||||
```
|
||||
|
||||
With this setting, running `borgmatic` without arguments will show the help
|
||||
message instead of performing any actions.
|
||||
|
||||
|
||||
## Autopilot
|
||||
|
||||
|
||||
@@ -148,9 +148,9 @@ feedback](https://torsion.org/borgmatic/#issues) you have on this feature.
|
||||
|
||||
#### Subvolume discovery
|
||||
|
||||
For any read-write subvolume you'd like backed up, add its path to borgmatic's
|
||||
`source_directories` option. Btrfs does not support snapshotting read-only
|
||||
subvolumes.
|
||||
For any read-write subvolume you'd like backed up, add its mount point path to
|
||||
borgmatic's `source_directories` option. Btrfs does not support snapshotting
|
||||
read-only subvolumes.
|
||||
|
||||
<span class="minilink minilink-addedin">New in version 1.9.6</span> Or include
|
||||
the mount point as a root pattern with borgmatic's `patterns` or `patterns_from`
|
||||
@@ -161,27 +161,27 @@ includes the snapshotted files in the paths sent to Borg. borgmatic is also
|
||||
responsible for cleaning up (deleting) these snapshots after a backup completes.
|
||||
|
||||
borgmatic is smart enough to look at the parent (and grandparent, etc.)
|
||||
directories of each of your `source_directories` to discover any subvolumes.
|
||||
For instance, let's say you add `/var/log` and `/var/lib` to your source
|
||||
directories, but `/var` is a subvolume. borgmatic will discover that and
|
||||
snapshot `/var` accordingly. This also works even with nested subvolumes;
|
||||
directories of each of your `source_directories` to discover any subvolumes. For
|
||||
instance, let's say you add `/var/log` and `/var/lib` to your source
|
||||
directories, but `/var` is a subvolume mount point. borgmatic will discover that
|
||||
and snapshot `/var` accordingly. This also works even with nested subvolumes;
|
||||
borgmatic selects the subvolume that's the "closest" parent to your source
|
||||
directories.
|
||||
|
||||
<span class="minilink minilink-addedin">New in version 1.9.6</span> When using
|
||||
[patterns](https://borgbackup.readthedocs.io/en/stable/usage/help.html#borg-help-patterns),
|
||||
the initial portion of a pattern's path that you intend borgmatic to match
|
||||
against a subvolume can't have globs or other non-literal characters in it—or it
|
||||
won't actually match. For instance, a subvolume of `/var` would match a pattern
|
||||
of `+ fm:/var/*/data`, but borgmatic isn't currently smart enough to match
|
||||
`/var` to a pattern like `+ fm:/v*/lib/data`.
|
||||
against a subvolume mount point can't have globs or other non-literal characters
|
||||
in it—or it won't actually match. For instance, a subvolume mount point of
|
||||
`/var` would match a pattern of `+ fm:/var/*/data`, but borgmatic isn't
|
||||
currently smart enough to match `/var` to a pattern like `+ fm:/v*/lib/data`.
|
||||
|
||||
Additionally, borgmatic rewrites the snapshot file paths so that they appear
|
||||
at their original subvolume locations in a Borg archive. For instance, if your
|
||||
subvolume exists at `/var/subvolume`, then the snapshotted files will appear
|
||||
Additionally, borgmatic rewrites the snapshot file paths so that they appear at
|
||||
their original subvolume locations in a Borg archive. For instance, if your
|
||||
subvolume is mounted at `/var/subvolume`, then the snapshotted files will appear
|
||||
in an archive at `/var/subvolume` as well—even if borgmatic has to mount the
|
||||
snapshot somewhere in `/var/subvolume/.borgmatic-snapshot-1234/` to perform
|
||||
the backup.
|
||||
snapshot somewhere in `/var/subvolume/.borgmatic-snapshot-1234/` to perform the
|
||||
backup.
|
||||
|
||||
<span class="minilink minilink-addedin">With Borg version 1.2 and
|
||||
earlier</span>Snapshotted files are instead stored at a path dependent on the
|
||||
|
||||
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([])
|
||||
@@ -2079,3 +2120,56 @@ def test_collect_configuration_run_summary_logs_outputs_merged_json_results():
|
||||
arguments=arguments,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def test_check_and_show_help_on_no_args_shows_help_when_no_args_and_default_actions_false():
|
||||
flexmock(module.sys).should_receive('argv').and_return(['borgmatic'])
|
||||
flexmock(module).should_receive('parse_arguments').with_args('--help').once()
|
||||
flexmock(module.sys).should_receive('exit').with_args(0).once()
|
||||
module.check_and_show_help_on_no_args({'test.yaml': {'default_actions': False}})
|
||||
|
||||
|
||||
def test_check_and_show_help_on_no_args_does_not_show_help_when_no_args_and_default_actions_true():
|
||||
flexmock(module.sys).should_receive('argv').and_return(['borgmatic'])
|
||||
flexmock(module).should_receive('parse_arguments').never()
|
||||
flexmock(module.sys).should_receive('exit').never()
|
||||
module.check_and_show_help_on_no_args({'test.yaml': {'default_actions': True}})
|
||||
|
||||
|
||||
def test_check_and_show_help_on_no_args_does_not_show_help_when_args_provided():
|
||||
flexmock(module.sys).should_receive('argv').and_return(['borgmatic', '--create'])
|
||||
flexmock(module).should_receive('parse_arguments').never()
|
||||
flexmock(module.sys).should_receive('exit').never()
|
||||
module.check_and_show_help_on_no_args({'test.yaml': {'default_actions': False}})
|
||||
|
||||
|
||||
def test_check_and_show_help_on_no_args_with_no_default_actions_in_all_configs():
|
||||
flexmock(module.sys).should_receive('argv').and_return(['borgmatic'])
|
||||
|
||||
# Both configs have default_actions set to False, so help should be shown
|
||||
configs = {
|
||||
'config1.yaml': {'default_actions': False},
|
||||
'config2.yaml': {'default_actions': False},
|
||||
}
|
||||
|
||||
# Expect help to be shown
|
||||
flexmock(module).should_receive('parse_arguments').with_args('--help').once()
|
||||
flexmock(module.sys).should_receive('exit').with_args(0).once()
|
||||
|
||||
module.check_and_show_help_on_no_args(configs)
|
||||
|
||||
|
||||
def test_check_and_show_help_on_no_args_with_conflicting_configs():
|
||||
flexmock(module.sys).should_receive('argv').and_return(['borgmatic'])
|
||||
|
||||
# Simulate two config files with conflicting 'default_actions' values
|
||||
configs = {
|
||||
'config1.yaml': {'default_actions': True},
|
||||
'config2.yaml': {'default_actions': False},
|
||||
}
|
||||
|
||||
# Expect help not to be shown because at least one config enables default actions
|
||||
flexmock(module).should_receive('parse_arguments').never()
|
||||
flexmock(module.sys).should_receive('exit').never()
|
||||
|
||||
module.check_and_show_help_on_no_args(configs)
|
||||
|
||||
Reference in New Issue
Block a user