forked from borgmatic-collective/borgmatic
Compare commits
No commits in common. "feat/ntfy-self-hosted-auth" and "master" have entirely different histories.
feat/ntfy-
...
master
19
NEWS
19
NEWS
|
@ -1,25 +1,8 @@
|
||||||
1.6.5
|
1.6.3.dev0
|
||||||
* #553: Fix logging to include the full traceback when Borg experiences an internal error, not just
|
|
||||||
the first few lines.
|
|
||||||
* #554: Fix all monitoring hooks to warn if the server returns an HTTP 4xx error. This can happen
|
|
||||||
with Healthchecks, for instance, when using an invalid ping URL.
|
|
||||||
* #555: Fix environment variable plumbing so options like "encryption_passphrase" and
|
|
||||||
"encryption_passcommand" in one configuration file aren't used for other configuration files.
|
|
||||||
|
|
||||||
1.6.4
|
|
||||||
* #546, #382: Keep your repository passphrases and database passwords outside of borgmatic's
|
|
||||||
configuration file with environment variable interpolation. See the documentation for more
|
|
||||||
information: https://torsion.org/borgmatic/docs/how-to/provide-your-passwords/
|
|
||||||
|
|
||||||
1.6.3
|
|
||||||
* #541: Add "borgmatic list --find" flag for searching for files across multiple archives, useful
|
* #541: Add "borgmatic list --find" flag for searching for files across multiple archives, useful
|
||||||
for hunting down that file you accidentally deleted so you can extract it. See the documentation
|
for hunting down that file you accidentally deleted so you can extract it. See the documentation
|
||||||
for more information:
|
for more information:
|
||||||
https://torsion.org/borgmatic/docs/how-to/inspect-your-backups/#searching-for-a-file
|
https://torsion.org/borgmatic/docs/how-to/inspect-your-backups/#searching-for-a-file
|
||||||
* #543: Add a monitoring hook for sending push notifications via ntfy. See the documentation for
|
|
||||||
more information: https://torsion.org/borgmatic/docs/how-to/monitor-your-backups/#ntfy-hook
|
|
||||||
* Fix Bash completion script to no longer alter your shell's settings (complain about unset
|
|
||||||
variables or error on pipe failures).
|
|
||||||
* Deprecate "borgmatic list --successful" flag, as listing only non-checkpoint (successful)
|
* Deprecate "borgmatic list --successful" flag, as listing only non-checkpoint (successful)
|
||||||
archives is now the default in newer versions of Borg.
|
archives is now the default in newer versions of Borg.
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,6 @@ borgmatic is powered by [Borg Backup](https://www.borgbackup.org/).
|
||||||
<a href="https://cronitor.io/"><img src="docs/static/cronitor.png" alt="Cronitor" height="60px" style="margin-bottom:20px;"></a>
|
<a href="https://cronitor.io/"><img src="docs/static/cronitor.png" alt="Cronitor" height="60px" style="margin-bottom:20px;"></a>
|
||||||
<a href="https://cronhub.io/"><img src="docs/static/cronhub.png" alt="Cronhub" height="60px" style="margin-bottom:20px;"></a>
|
<a href="https://cronhub.io/"><img src="docs/static/cronhub.png" alt="Cronhub" height="60px" style="margin-bottom:20px;"></a>
|
||||||
<a href="https://www.pagerduty.com/"><img src="docs/static/pagerduty.png" alt="PagerDuty" height="60px" style="margin-bottom:20px;"></a>
|
<a href="https://www.pagerduty.com/"><img src="docs/static/pagerduty.png" alt="PagerDuty" height="60px" style="margin-bottom:20px;"></a>
|
||||||
<a href="https://ntfy.sh/"><img src="docs/static/ntfy.png" alt="ntfy" height="60px" style="margin-bottom:20px;"></a>
|
|
||||||
<a href="https://www.borgbase.com/?utm_source=borgmatic"><img src="docs/static/borgbase.png" alt="BorgBase" height="60px" style="margin-bottom:20px;"></a>
|
<a href="https://www.borgbase.com/?utm_source=borgmatic"><img src="docs/static/borgbase.png" alt="BorgBase" height="60px" style="margin-bottom:20px;"></a>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from borgmatic.borg import environment
|
|
||||||
from borgmatic.borg.flags import make_flags
|
from borgmatic.borg.flags import make_flags
|
||||||
from borgmatic.execute import execute_command
|
from borgmatic.execute import execute_command
|
||||||
|
|
||||||
|
@ -52,8 +51,5 @@ def run_arbitrary_borg(
|
||||||
)
|
)
|
||||||
|
|
||||||
return execute_command(
|
return execute_command(
|
||||||
full_command,
|
full_command, output_log_level=logging.WARNING, borg_local_path=local_path,
|
||||||
output_log_level=logging.WARNING,
|
|
||||||
borg_local_path=local_path,
|
|
||||||
extra_environment=environment.make_environment(storage_config),
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -5,7 +5,7 @@ import logging
|
||||||
import os
|
import os
|
||||||
import pathlib
|
import pathlib
|
||||||
|
|
||||||
from borgmatic.borg import environment, extract, info, state
|
from borgmatic.borg import extract, info, state
|
||||||
from borgmatic.execute import DO_NOT_CAPTURE, execute_command
|
from borgmatic.execute import DO_NOT_CAPTURE, execute_command
|
||||||
|
|
||||||
DEFAULT_CHECKS = (
|
DEFAULT_CHECKS = (
|
||||||
|
@ -304,22 +304,16 @@ def check_archives(
|
||||||
+ (repository,)
|
+ (repository,)
|
||||||
)
|
)
|
||||||
|
|
||||||
borg_environment = environment.make_environment(storage_config)
|
|
||||||
|
|
||||||
# The Borg repair option triggers an interactive prompt, which won't work when output is
|
# The Borg repair option triggers an interactive prompt, which won't work when output is
|
||||||
# captured. And progress messes with the terminal directly.
|
# captured. And progress messes with the terminal directly.
|
||||||
if repair or progress:
|
if repair or progress:
|
||||||
execute_command(
|
execute_command(full_command, output_file=DO_NOT_CAPTURE)
|
||||||
full_command, output_file=DO_NOT_CAPTURE, extra_environment=borg_environment
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
execute_command(full_command, extra_environment=borg_environment)
|
execute_command(full_command)
|
||||||
|
|
||||||
for check in checks:
|
for check in checks:
|
||||||
write_check_time(make_check_time_path(location_config, borg_repository_id, check))
|
write_check_time(make_check_time_path(location_config, borg_repository_id, check))
|
||||||
|
|
||||||
if 'extract' in checks:
|
if 'extract' in checks:
|
||||||
extract.extract_last_archive_dry_run(
|
extract.extract_last_archive_dry_run(repository, lock_wait, local_path, remote_path)
|
||||||
storage_config, repository, lock_wait, local_path, remote_path
|
|
||||||
)
|
|
||||||
write_check_time(make_check_time_path(location_config, borg_repository_id, 'extract'))
|
write_check_time(make_check_time_path(location_config, borg_repository_id, 'extract'))
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from borgmatic.borg import environment
|
|
||||||
from borgmatic.execute import execute_command
|
from borgmatic.execute import execute_command
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
@ -39,9 +38,4 @@ def compact_segments(
|
||||||
)
|
)
|
||||||
|
|
||||||
if not dry_run:
|
if not dry_run:
|
||||||
execute_command(
|
execute_command(full_command, output_log_level=logging.INFO, borg_local_path=local_path)
|
||||||
full_command,
|
|
||||||
output_log_level=logging.INFO,
|
|
||||||
borg_local_path=local_path,
|
|
||||||
extra_environment=environment.make_environment(storage_config),
|
|
||||||
)
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import os
|
||||||
import pathlib
|
import pathlib
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
from borgmatic.borg import environment, feature, state
|
from borgmatic.borg import feature, state
|
||||||
from borgmatic.execute import DO_NOT_CAPTURE, execute_command, execute_command_with_processes
|
from borgmatic.execute import DO_NOT_CAPTURE, execute_command, execute_command_with_processes
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
@ -317,8 +317,6 @@ def create_archive(
|
||||||
# the terminal directly.
|
# the terminal directly.
|
||||||
output_file = DO_NOT_CAPTURE if progress else None
|
output_file = DO_NOT_CAPTURE if progress else None
|
||||||
|
|
||||||
borg_environment = environment.make_environment(storage_config)
|
|
||||||
|
|
||||||
if stream_processes:
|
if stream_processes:
|
||||||
return execute_command_with_processes(
|
return execute_command_with_processes(
|
||||||
full_command,
|
full_command,
|
||||||
|
@ -327,7 +325,6 @@ def create_archive(
|
||||||
output_file,
|
output_file,
|
||||||
borg_local_path=local_path,
|
borg_local_path=local_path,
|
||||||
working_directory=working_directory,
|
working_directory=working_directory,
|
||||||
extra_environment=borg_environment,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return execute_command(
|
return execute_command(
|
||||||
|
@ -336,5 +333,4 @@ def create_archive(
|
||||||
output_file,
|
output_file,
|
||||||
borg_local_path=local_path,
|
borg_local_path=local_path,
|
||||||
working_directory=working_directory,
|
working_directory=working_directory,
|
||||||
extra_environment=borg_environment,
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import os
|
||||||
|
|
||||||
OPTION_TO_ENVIRONMENT_VARIABLE = {
|
OPTION_TO_ENVIRONMENT_VARIABLE = {
|
||||||
'borg_base_directory': 'BORG_BASE_DIR',
|
'borg_base_directory': 'BORG_BASE_DIR',
|
||||||
'borg_config_directory': 'BORG_CONFIG_DIR',
|
'borg_config_directory': 'BORG_CONFIG_DIR',
|
||||||
|
@ -16,24 +18,21 @@ DEFAULT_BOOL_OPTION_TO_ENVIRONMENT_VARIABLE = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def make_environment(storage_config):
|
def initialize(storage_config):
|
||||||
'''
|
|
||||||
Given a borgmatic storage configuration dict, return its options converted to a Borg environment
|
|
||||||
variable dict.
|
|
||||||
'''
|
|
||||||
environment = {}
|
|
||||||
|
|
||||||
for option_name, environment_variable_name in OPTION_TO_ENVIRONMENT_VARIABLE.items():
|
for option_name, environment_variable_name in OPTION_TO_ENVIRONMENT_VARIABLE.items():
|
||||||
value = storage_config.get(option_name)
|
|
||||||
|
# Options from borgmatic configuration take precedence over already set BORG_* environment
|
||||||
|
# variables.
|
||||||
|
value = storage_config.get(option_name) or os.environ.get(environment_variable_name)
|
||||||
|
|
||||||
if value:
|
if value:
|
||||||
environment[environment_variable_name] = value
|
os.environ[environment_variable_name] = value
|
||||||
|
else:
|
||||||
|
os.environ.pop(environment_variable_name, None)
|
||||||
|
|
||||||
for (
|
for (
|
||||||
option_name,
|
option_name,
|
||||||
environment_variable_name,
|
environment_variable_name,
|
||||||
) in DEFAULT_BOOL_OPTION_TO_ENVIRONMENT_VARIABLE.items():
|
) in DEFAULT_BOOL_OPTION_TO_ENVIRONMENT_VARIABLE.items():
|
||||||
value = storage_config.get(option_name, False)
|
value = storage_config.get(option_name, False)
|
||||||
environment[environment_variable_name] = 'yes' if value else 'no'
|
os.environ[environment_variable_name] = 'yes' if value else 'no'
|
||||||
|
|
||||||
return environment
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from borgmatic.borg import environment
|
|
||||||
from borgmatic.execute import DO_NOT_CAPTURE, execute_command
|
from borgmatic.execute import DO_NOT_CAPTURE, execute_command
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
@ -62,5 +61,4 @@ def export_tar_archive(
|
||||||
output_file=DO_NOT_CAPTURE if destination_path == '-' else None,
|
output_file=DO_NOT_CAPTURE if destination_path == '-' else None,
|
||||||
output_log_level=output_log_level,
|
output_log_level=output_log_level,
|
||||||
borg_local_path=local_path,
|
borg_local_path=local_path,
|
||||||
extra_environment=environment.make_environment(storage_config),
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -2,15 +2,13 @@ import logging
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
from borgmatic.borg import environment, feature
|
from borgmatic.borg import feature
|
||||||
from borgmatic.execute import DO_NOT_CAPTURE, execute_command
|
from borgmatic.execute import DO_NOT_CAPTURE, execute_command
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def extract_last_archive_dry_run(
|
def extract_last_archive_dry_run(repository, lock_wait=None, local_path='borg', remote_path=None):
|
||||||
storage_config, repository, lock_wait=None, local_path='borg', remote_path=None
|
|
||||||
):
|
|
||||||
'''
|
'''
|
||||||
Perform an extraction dry-run of the most recent archive. If there are no archives, skip the
|
Perform an extraction dry-run of the most recent archive. If there are no archives, skip the
|
||||||
dry-run.
|
dry-run.
|
||||||
|
@ -31,13 +29,8 @@ def extract_last_archive_dry_run(
|
||||||
+ (repository,)
|
+ (repository,)
|
||||||
)
|
)
|
||||||
|
|
||||||
borg_environment = environment.make_environment(storage_config)
|
|
||||||
|
|
||||||
list_output = execute_command(
|
list_output = execute_command(
|
||||||
full_list_command,
|
full_list_command, output_log_level=None, borg_local_path=local_path
|
||||||
output_log_level=None,
|
|
||||||
borg_local_path=local_path,
|
|
||||||
extra_environment=borg_environment,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -59,9 +52,7 @@ def extract_last_archive_dry_run(
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
execute_command(
|
execute_command(full_extract_command, working_directory=None)
|
||||||
full_extract_command, working_directory=None, extra_environment=borg_environment
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def extract_archive(
|
def extract_archive(
|
||||||
|
@ -115,16 +106,11 @@ def extract_archive(
|
||||||
+ (tuple(paths) if paths else ())
|
+ (tuple(paths) if paths else ())
|
||||||
)
|
)
|
||||||
|
|
||||||
borg_environment = environment.make_environment(storage_config)
|
|
||||||
|
|
||||||
# The progress output isn't compatible with captured and logged output, as progress messes with
|
# The progress output isn't compatible with captured and logged output, as progress messes with
|
||||||
# the terminal directly.
|
# the terminal directly.
|
||||||
if progress:
|
if progress:
|
||||||
return execute_command(
|
return execute_command(
|
||||||
full_command,
|
full_command, output_file=DO_NOT_CAPTURE, working_directory=destination_path
|
||||||
output_file=DO_NOT_CAPTURE,
|
|
||||||
working_directory=destination_path,
|
|
||||||
extra_environment=borg_environment,
|
|
||||||
)
|
)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -134,11 +120,8 @@ def extract_archive(
|
||||||
output_file=subprocess.PIPE,
|
output_file=subprocess.PIPE,
|
||||||
working_directory=destination_path,
|
working_directory=destination_path,
|
||||||
run_to_completion=False,
|
run_to_completion=False,
|
||||||
extra_environment=borg_environment,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Don't give Borg local path, so as to error on warnings, as Borg only gives a warning if the
|
# Don't give Borg local path, so as to error on warnings, as Borg only gives a warning if the
|
||||||
# restore paths don't exist in the archive!
|
# restore paths don't exist in the archive!
|
||||||
execute_command(
|
execute_command(full_command, working_directory=destination_path)
|
||||||
full_command, working_directory=destination_path, extra_environment=borg_environment
|
|
||||||
)
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from borgmatic.borg import environment
|
|
||||||
from borgmatic.borg.flags import make_flags, make_flags_from_arguments
|
from borgmatic.borg.flags import make_flags, make_flags_from_arguments
|
||||||
from borgmatic.execute import execute_command
|
from borgmatic.execute import execute_command
|
||||||
|
|
||||||
|
@ -43,5 +42,4 @@ def display_archives_info(
|
||||||
full_command,
|
full_command,
|
||||||
output_log_level=None if info_arguments.json else logging.WARNING,
|
output_log_level=None if info_arguments.json else logging.WARNING,
|
||||||
borg_local_path=local_path,
|
borg_local_path=local_path,
|
||||||
extra_environment=environment.make_environment(storage_config),
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -2,7 +2,7 @@ import argparse
|
||||||
import logging
|
import logging
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
from borgmatic.borg import environment, info
|
from borgmatic.borg import info
|
||||||
from borgmatic.execute import DO_NOT_CAPTURE, execute_command
|
from borgmatic.execute import DO_NOT_CAPTURE, execute_command
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
@ -54,9 +54,4 @@ def initialize_repository(
|
||||||
)
|
)
|
||||||
|
|
||||||
# Do not capture output here, so as to support interactive prompts.
|
# Do not capture output here, so as to support interactive prompts.
|
||||||
execute_command(
|
execute_command(init_command, output_file=DO_NOT_CAPTURE, borg_local_path=local_path)
|
||||||
init_command,
|
|
||||||
output_file=DO_NOT_CAPTURE,
|
|
||||||
borg_local_path=local_path,
|
|
||||||
extra_environment=environment.make_environment(storage_config),
|
|
||||||
)
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ import copy
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from borgmatic.borg import environment
|
|
||||||
from borgmatic.borg.flags import make_flags, make_flags_from_arguments
|
from borgmatic.borg.flags import make_flags, make_flags_from_arguments
|
||||||
from borgmatic.execute import execute_command
|
from borgmatic.execute import execute_command
|
||||||
|
|
||||||
|
@ -32,12 +31,7 @@ def resolve_archive_name(repository, archive, storage_config, local_path='borg',
|
||||||
+ ('--short', repository)
|
+ ('--short', repository)
|
||||||
)
|
)
|
||||||
|
|
||||||
output = execute_command(
|
output = execute_command(full_command, output_log_level=None, borg_local_path=local_path)
|
||||||
full_command,
|
|
||||||
output_log_level=None,
|
|
||||||
borg_local_path=local_path,
|
|
||||||
extra_environment=environment.make_environment(storage_config),
|
|
||||||
)
|
|
||||||
try:
|
try:
|
||||||
latest_archive = output.strip().splitlines()[-1]
|
latest_archive = output.strip().splitlines()[-1]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
|
@ -117,8 +111,6 @@ def list_archives(repository, storage_config, list_arguments, local_path='borg',
|
||||||
archive. Or, if list_arguments.find_paths are given, list the files by searching across multiple
|
archive. Or, if list_arguments.find_paths are given, list the files by searching across multiple
|
||||||
archives.
|
archives.
|
||||||
'''
|
'''
|
||||||
borg_environment = environment.make_environment(storage_config)
|
|
||||||
|
|
||||||
# If there are any paths to find (and there's not a single archive already selected), start by
|
# If there are any paths to find (and there's not a single archive already selected), start by
|
||||||
# getting a list of archives to search.
|
# getting a list of archives to search.
|
||||||
if list_arguments.find_paths and not list_arguments.archive:
|
if list_arguments.find_paths and not list_arguments.archive:
|
||||||
|
@ -135,7 +127,6 @@ def list_archives(repository, storage_config, list_arguments, local_path='borg',
|
||||||
),
|
),
|
||||||
output_log_level=None,
|
output_log_level=None,
|
||||||
borg_local_path=local_path,
|
borg_local_path=local_path,
|
||||||
extra_environment=borg_environment,
|
|
||||||
)
|
)
|
||||||
.strip('\n')
|
.strip('\n')
|
||||||
.split('\n')
|
.split('\n')
|
||||||
|
@ -163,7 +154,6 @@ def list_archives(repository, storage_config, list_arguments, local_path='borg',
|
||||||
main_command,
|
main_command,
|
||||||
output_log_level=None if list_arguments.json else logging.WARNING,
|
output_log_level=None if list_arguments.json else logging.WARNING,
|
||||||
borg_local_path=local_path,
|
borg_local_path=local_path,
|
||||||
extra_environment=borg_environment,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if list_arguments.json:
|
if list_arguments.json:
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from borgmatic.borg import environment
|
|
||||||
from borgmatic.execute import DO_NOT_CAPTURE, execute_command
|
from borgmatic.execute import DO_NOT_CAPTURE, execute_command
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
@ -39,16 +38,9 @@ def mount_archive(
|
||||||
+ (tuple(paths) if paths else ())
|
+ (tuple(paths) if paths else ())
|
||||||
)
|
)
|
||||||
|
|
||||||
borg_environment = environment.make_environment(storage_config)
|
|
||||||
|
|
||||||
# Don't capture the output when foreground mode is used so that ctrl-C can work properly.
|
# Don't capture the output when foreground mode is used so that ctrl-C can work properly.
|
||||||
if foreground:
|
if foreground:
|
||||||
execute_command(
|
execute_command(full_command, output_file=DO_NOT_CAPTURE, borg_local_path=local_path)
|
||||||
full_command,
|
|
||||||
output_file=DO_NOT_CAPTURE,
|
|
||||||
borg_local_path=local_path,
|
|
||||||
extra_environment=borg_environment,
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
execute_command(full_command, borg_local_path=local_path, extra_environment=borg_environment)
|
execute_command(full_command, borg_local_path=local_path)
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from borgmatic.borg import environment
|
|
||||||
from borgmatic.execute import execute_command
|
from borgmatic.execute import execute_command
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
@ -73,9 +72,4 @@ def prune_archives(
|
||||||
else:
|
else:
|
||||||
output_log_level = logging.INFO
|
output_log_level = logging.INFO
|
||||||
|
|
||||||
execute_command(
|
execute_command(full_command, output_log_level=output_log_level, borg_local_path=local_path)
|
||||||
full_command,
|
|
||||||
output_log_level=output_log_level,
|
|
||||||
borg_local_path=local_path,
|
|
||||||
extra_environment=environment.make_environment(storage_config),
|
|
||||||
)
|
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from borgmatic.borg import environment
|
|
||||||
from borgmatic.execute import execute_command
|
from borgmatic.execute import execute_command
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def local_borg_version(storage_config, local_path='borg'):
|
def local_borg_version(local_path='borg'):
|
||||||
'''
|
'''
|
||||||
Given a storage configuration dict and a local Borg binary path, return a version string for it.
|
Given a local Borg binary path, return a version string for it.
|
||||||
|
|
||||||
Raise OSError or CalledProcessError if there is a problem running Borg.
|
Raise OSError or CalledProcessError if there is a problem running Borg.
|
||||||
Raise ValueError if the version cannot be parsed.
|
Raise ValueError if the version cannot be parsed.
|
||||||
|
@ -18,12 +17,7 @@ def local_borg_version(storage_config, local_path='borg'):
|
||||||
+ (('--info',) if logger.getEffectiveLevel() == logging.INFO else ())
|
+ (('--info',) if logger.getEffectiveLevel() == logging.INFO else ())
|
||||||
+ (('--debug', '--show-rc') if logger.isEnabledFor(logging.DEBUG) else ())
|
+ (('--debug', '--show-rc') if logger.isEnabledFor(logging.DEBUG) else ())
|
||||||
)
|
)
|
||||||
output = execute_command(
|
output = execute_command(full_command, output_log_level=None, borg_local_path=local_path)
|
||||||
full_command,
|
|
||||||
output_log_level=None,
|
|
||||||
borg_local_path=local_path,
|
|
||||||
extra_environment=environment.make_environment(storage_config),
|
|
||||||
)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return output.split(' ')[1].strip()
|
return output.split(' ')[1].strip()
|
||||||
|
|
|
@ -188,12 +188,6 @@ def make_parsers():
|
||||||
action='extend',
|
action='extend',
|
||||||
help='One or more configuration file options to override with specified values',
|
help='One or more configuration file options to override with specified values',
|
||||||
)
|
)
|
||||||
global_group.add_argument(
|
|
||||||
'--no-environment-interpolation',
|
|
||||||
dest='resolve_env',
|
|
||||||
action='store_false',
|
|
||||||
help='Do not resolve environment variables in configuration file',
|
|
||||||
)
|
|
||||||
global_group.add_argument(
|
global_group.add_argument(
|
||||||
'--bash-completion',
|
'--bash-completion',
|
||||||
default=False,
|
default=False,
|
||||||
|
|
|
@ -16,6 +16,7 @@ from borgmatic.borg import borg as borg_borg
|
||||||
from borgmatic.borg import check as borg_check
|
from borgmatic.borg import check as borg_check
|
||||||
from borgmatic.borg import compact as borg_compact
|
from borgmatic.borg import compact as borg_compact
|
||||||
from borgmatic.borg import create as borg_create
|
from borgmatic.borg import create as borg_create
|
||||||
|
from borgmatic.borg import environment as borg_environment
|
||||||
from borgmatic.borg import export_tar as borg_export_tar
|
from borgmatic.borg import export_tar as borg_export_tar
|
||||||
from borgmatic.borg import extract as borg_extract
|
from borgmatic.borg import extract as borg_extract
|
||||||
from borgmatic.borg import feature as borg_feature
|
from borgmatic.borg import feature as borg_feature
|
||||||
|
@ -59,13 +60,14 @@ def run_configuration(config_filename, config, arguments):
|
||||||
remote_path = location.get('remote_path')
|
remote_path = location.get('remote_path')
|
||||||
retries = storage.get('retries', 0)
|
retries = storage.get('retries', 0)
|
||||||
retry_wait = storage.get('retry_wait', 0)
|
retry_wait = storage.get('retry_wait', 0)
|
||||||
|
borg_environment.initialize(storage)
|
||||||
encountered_error = None
|
encountered_error = None
|
||||||
error_repository = ''
|
error_repository = ''
|
||||||
using_primary_action = {'prune', 'compact', 'create', 'check'}.intersection(arguments)
|
using_primary_action = {'prune', 'compact', 'create', 'check'}.intersection(arguments)
|
||||||
monitoring_log_level = verbosity_to_log_level(global_arguments.monitoring_verbosity)
|
monitoring_log_level = verbosity_to_log_level(global_arguments.monitoring_verbosity)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
local_borg_version = borg_version.local_borg_version(storage, local_path)
|
local_borg_version = borg_version.local_borg_version(local_path)
|
||||||
except (OSError, CalledProcessError, ValueError) as error:
|
except (OSError, CalledProcessError, ValueError) as error:
|
||||||
yield from log_error_records(
|
yield from log_error_records(
|
||||||
'{}: Error getting local Borg version'.format(config_filename), error
|
'{}: Error getting local Borg version'.format(config_filename), error
|
||||||
|
@ -648,7 +650,7 @@ def run_actions(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def load_configurations(config_filenames, overrides=None, resolve_env=True):
|
def load_configurations(config_filenames, overrides=None):
|
||||||
'''
|
'''
|
||||||
Given a sequence of configuration filenames, load and validate each configuration file. Return
|
Given a sequence of configuration filenames, load and validate each configuration file. Return
|
||||||
the results as a tuple of: dict of configuration filename to corresponding parsed configuration,
|
the results as a tuple of: dict of configuration filename to corresponding parsed configuration,
|
||||||
|
@ -662,7 +664,7 @@ def load_configurations(config_filenames, overrides=None, resolve_env=True):
|
||||||
for config_filename in config_filenames:
|
for config_filename in config_filenames:
|
||||||
try:
|
try:
|
||||||
configs[config_filename] = validate.parse_configuration(
|
configs[config_filename] = validate.parse_configuration(
|
||||||
config_filename, validate.schema_filename(), overrides, resolve_env
|
config_filename, validate.schema_filename(), overrides
|
||||||
)
|
)
|
||||||
except PermissionError:
|
except PermissionError:
|
||||||
logs.extend(
|
logs.extend(
|
||||||
|
@ -833,7 +835,7 @@ def collect_configuration_run_summary_logs(configs, arguments):
|
||||||
logger.info('Unmounting mount point {}'.format(arguments['umount'].mount_point))
|
logger.info('Unmounting mount point {}'.format(arguments['umount'].mount_point))
|
||||||
try:
|
try:
|
||||||
borg_umount.unmount_archive(
|
borg_umount.unmount_archive(
|
||||||
mount_point=arguments['umount'].mount_point, local_path=get_local_path(configs),
|
mount_point=arguments['umount'].mount_point, local_path=get_local_path(configs)
|
||||||
)
|
)
|
||||||
except (CalledProcessError, OSError) as error:
|
except (CalledProcessError, OSError) as error:
|
||||||
yield from log_error_records('Error unmounting mount point', error)
|
yield from log_error_records('Error unmounting mount point', error)
|
||||||
|
@ -890,9 +892,7 @@ def main(): # pragma: no cover
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
config_filenames = tuple(collect.collect_config_filenames(global_arguments.config_paths))
|
config_filenames = tuple(collect.collect_config_filenames(global_arguments.config_paths))
|
||||||
configs, parse_logs = load_configurations(
|
configs, parse_logs = load_configurations(config_filenames, global_arguments.overrides)
|
||||||
config_filenames, global_arguments.overrides, global_arguments.resolve_env
|
|
||||||
)
|
|
||||||
|
|
||||||
any_json_flags = any(
|
any_json_flags = any(
|
||||||
getattr(sub_arguments, 'json', False) for sub_arguments in arguments.values()
|
getattr(sub_arguments, 'json', False) for sub_arguments in arguments.values()
|
||||||
|
|
|
@ -30,6 +30,7 @@ def bash_completion():
|
||||||
# Avert your eyes.
|
# Avert your eyes.
|
||||||
return '\n'.join(
|
return '\n'.join(
|
||||||
(
|
(
|
||||||
|
'set -uo pipefail',
|
||||||
'check_version() {',
|
'check_version() {',
|
||||||
' local this_script="$(cat "$BASH_SOURCE" 2> /dev/null)"',
|
' local this_script="$(cat "$BASH_SOURCE" 2> /dev/null)"',
|
||||||
' local installed_script="$(borgmatic --bash-completion 2> /dev/null)"',
|
' local installed_script="$(borgmatic --bash-completion 2> /dev/null)"',
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
import os
|
|
||||||
import re
|
|
||||||
|
|
||||||
_VARIABLE_PATTERN = re.compile(
|
|
||||||
r'(?P<escape>\\)?(?P<variable>\$\{(?P<name>[A-Za-z0-9_]+)((:?-)(?P<default>[^}]+))?\})'
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def _resolve_string(matcher):
|
|
||||||
'''
|
|
||||||
Get the value from environment given a matcher containing a name and an optional default value.
|
|
||||||
If the variable is not defined in environment and no default value is provided, an Error is raised.
|
|
||||||
'''
|
|
||||||
if matcher.group('escape') is not None:
|
|
||||||
# in case of escaped envvar, unescape it
|
|
||||||
return matcher.group('variable')
|
|
||||||
# resolve the env var
|
|
||||||
name, default = matcher.group('name'), matcher.group('default')
|
|
||||||
out = os.getenv(name, default=default)
|
|
||||||
if out is None:
|
|
||||||
raise ValueError('Cannot find variable ${name} in environment'.format(name=name))
|
|
||||||
return out
|
|
||||||
|
|
||||||
|
|
||||||
def resolve_env_variables(item):
|
|
||||||
'''
|
|
||||||
Resolves variables like or ${FOO} from given configuration with values from process environment
|
|
||||||
Supported formats:
|
|
||||||
- ${FOO} will return FOO env variable
|
|
||||||
- ${FOO-bar} or ${FOO:-bar} will return FOO env variable if it exists, else "bar"
|
|
||||||
|
|
||||||
If any variable is missing in environment and no default value is provided, an Error is raised.
|
|
||||||
'''
|
|
||||||
if isinstance(item, str):
|
|
||||||
return _VARIABLE_PATTERN.sub(_resolve_string, item)
|
|
||||||
if isinstance(item, list):
|
|
||||||
for i, subitem in enumerate(item):
|
|
||||||
item[i] = resolve_env_variables(subitem)
|
|
||||||
if isinstance(item, dict):
|
|
||||||
for key, value in item.items():
|
|
||||||
item[key] = resolve_env_variables(value)
|
|
||||||
return item
|
|
|
@ -900,119 +900,6 @@ properties:
|
||||||
https://docs.mongodb.com/database-tools/mongodump/ and
|
https://docs.mongodb.com/database-tools/mongodump/ and
|
||||||
https://docs.mongodb.com/database-tools/mongorestore/ for
|
https://docs.mongodb.com/database-tools/mongorestore/ for
|
||||||
details.
|
details.
|
||||||
ntfy:
|
|
||||||
type: object
|
|
||||||
required: ['topic']
|
|
||||||
additionalProperties: false
|
|
||||||
properties:
|
|
||||||
topic:
|
|
||||||
type: string
|
|
||||||
description: |
|
|
||||||
The topic to publish to.
|
|
||||||
(https://ntfy.sh/docs/publish/)
|
|
||||||
example: topic
|
|
||||||
server:
|
|
||||||
type: string
|
|
||||||
description: |
|
|
||||||
The address of your self-hosted ntfy.sh instance.
|
|
||||||
example: https://ntfy.your-domain.com
|
|
||||||
username:
|
|
||||||
type: string
|
|
||||||
description: |
|
|
||||||
The username for your self-hosted ntfy.sh instance
|
|
||||||
(ignored for the upstream-hosted instance)
|
|
||||||
example: borgmatic
|
|
||||||
password:
|
|
||||||
type: string
|
|
||||||
description: |
|
|
||||||
The password for your self-hosted ntfy.sh instance.
|
|
||||||
(ignored for the upstream-hosted instance)
|
|
||||||
example: superSecretP@ssw0rd
|
|
||||||
start:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
title:
|
|
||||||
type: string
|
|
||||||
description: |
|
|
||||||
The title of the message
|
|
||||||
example: Ping!
|
|
||||||
message:
|
|
||||||
type: string
|
|
||||||
description: |
|
|
||||||
The message body to publish.
|
|
||||||
example: Your backups have failed.
|
|
||||||
priority:
|
|
||||||
type: string
|
|
||||||
description: |
|
|
||||||
The priority to set.
|
|
||||||
example: urgent
|
|
||||||
tags:
|
|
||||||
type: string
|
|
||||||
description: |
|
|
||||||
Tags to attach to the message.
|
|
||||||
example: incoming_envelope
|
|
||||||
finish:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
title:
|
|
||||||
type: string
|
|
||||||
description: |
|
|
||||||
The title of the message.
|
|
||||||
example: Ping!
|
|
||||||
message:
|
|
||||||
type: string
|
|
||||||
description: |
|
|
||||||
The message body to publish.
|
|
||||||
example: Your backups have failed.
|
|
||||||
priority:
|
|
||||||
type: string
|
|
||||||
description: |
|
|
||||||
The priority to set.
|
|
||||||
example: urgent
|
|
||||||
tags:
|
|
||||||
type: string
|
|
||||||
description: |
|
|
||||||
Tags to attach to the message.
|
|
||||||
example: incoming_envelope
|
|
||||||
fail:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
title:
|
|
||||||
type: string
|
|
||||||
description: |
|
|
||||||
The title of the message.
|
|
||||||
example: Ping!
|
|
||||||
message:
|
|
||||||
type: string
|
|
||||||
description: |
|
|
||||||
The message body to publish.
|
|
||||||
example: Your backups have failed.
|
|
||||||
priority:
|
|
||||||
type: string
|
|
||||||
description: |
|
|
||||||
The priority to set.
|
|
||||||
example: urgent
|
|
||||||
tags:
|
|
||||||
type: string
|
|
||||||
description: |
|
|
||||||
Tags to attach to the message.
|
|
||||||
example: incoming_envelope
|
|
||||||
states:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- start
|
|
||||||
- finish
|
|
||||||
- fail
|
|
||||||
uniqueItems: true
|
|
||||||
description: |
|
|
||||||
List of one or more monitoring states to ping for:
|
|
||||||
"start", "finish", and/or "fail". Defaults to
|
|
||||||
pinging for failure only.
|
|
||||||
example:
|
|
||||||
- start
|
|
||||||
- finish
|
|
||||||
healthchecks:
|
healthchecks:
|
||||||
type: object
|
type: object
|
||||||
required: ['ping_url']
|
required: ['ping_url']
|
||||||
|
|
|
@ -4,7 +4,7 @@ import jsonschema
|
||||||
import pkg_resources
|
import pkg_resources
|
||||||
import ruamel.yaml
|
import ruamel.yaml
|
||||||
|
|
||||||
from borgmatic.config import environment, load, normalize, override
|
from borgmatic.config import load, normalize, override
|
||||||
|
|
||||||
|
|
||||||
def schema_filename():
|
def schema_filename():
|
||||||
|
@ -79,7 +79,7 @@ def apply_logical_validation(config_filename, parsed_configuration):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def parse_configuration(config_filename, schema_filename, overrides=None, resolve_env=True):
|
def parse_configuration(config_filename, schema_filename, overrides=None):
|
||||||
'''
|
'''
|
||||||
Given the path to a config filename in YAML format, the path to a schema filename in a YAML
|
Given the path to a config filename in YAML format, the path to a schema filename in a YAML
|
||||||
rendition of JSON Schema format, a sequence of configuration file override strings in the form
|
rendition of JSON Schema format, a sequence of configuration file override strings in the form
|
||||||
|
@ -98,10 +98,8 @@ def parse_configuration(config_filename, schema_filename, overrides=None, resolv
|
||||||
except (ruamel.yaml.error.YAMLError, RecursionError) as error:
|
except (ruamel.yaml.error.YAMLError, RecursionError) as error:
|
||||||
raise Validation_error(config_filename, (str(error),))
|
raise Validation_error(config_filename, (str(error),))
|
||||||
|
|
||||||
normalize.normalize(config)
|
|
||||||
override.apply_overrides(config, overrides)
|
override.apply_overrides(config, overrides)
|
||||||
if resolve_env:
|
normalize.normalize(config)
|
||||||
environment.resolve_env_variables(config)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
validator = jsonschema.Draft7Validator(schema)
|
validator = jsonschema.Draft7Validator(schema)
|
||||||
|
|
|
@ -87,19 +87,18 @@ def log_outputs(processes, exclude_stdouts, output_log_level, borg_local_path):
|
||||||
# Add the process's output to output_buffers to ensure it'll get read.
|
# Add the process's output to output_buffers to ensure it'll get read.
|
||||||
output_buffers.append(other_process.stdout)
|
output_buffers.append(other_process.stdout)
|
||||||
|
|
||||||
while True:
|
line = ready_buffer.readline().rstrip().decode()
|
||||||
line = ready_buffer.readline().rstrip().decode()
|
if not line or not ready_process:
|
||||||
if not line or not ready_process:
|
continue
|
||||||
break
|
|
||||||
|
|
||||||
# Keep the last few lines of output in case the process errors, and we need the output for
|
# Keep the last few lines of output in case the process errors, and we need the output for
|
||||||
# the exception below.
|
# the exception below.
|
||||||
last_lines = buffer_last_lines[ready_buffer]
|
last_lines = buffer_last_lines[ready_buffer]
|
||||||
last_lines.append(line)
|
last_lines.append(line)
|
||||||
if len(last_lines) > ERROR_OUTPUT_MAX_LINE_COUNT:
|
if len(last_lines) > ERROR_OUTPUT_MAX_LINE_COUNT:
|
||||||
last_lines.pop(0)
|
last_lines.pop(0)
|
||||||
|
|
||||||
logger.log(output_log_level, line)
|
logger.log(output_log_level, line)
|
||||||
|
|
||||||
still_running = False
|
still_running = False
|
||||||
|
|
||||||
|
@ -133,6 +132,21 @@ def log_outputs(processes, exclude_stdouts, output_log_level, borg_local_path):
|
||||||
if not still_running:
|
if not still_running:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
# Consume any remaining output that we missed (if any).
|
||||||
|
for process in processes:
|
||||||
|
output_buffer = output_buffer_for_process(process, exclude_stdouts)
|
||||||
|
|
||||||
|
if not output_buffer:
|
||||||
|
continue
|
||||||
|
|
||||||
|
while True: # pragma: no cover
|
||||||
|
remaining_output = output_buffer.readline().rstrip().decode()
|
||||||
|
|
||||||
|
if not remaining_output:
|
||||||
|
break
|
||||||
|
|
||||||
|
logger.log(output_log_level, remaining_output)
|
||||||
|
|
||||||
|
|
||||||
def log_command(full_command, input_file, output_file):
|
def log_command(full_command, input_file, output_file):
|
||||||
'''
|
'''
|
||||||
|
|
|
@ -43,9 +43,7 @@ def ping_monitor(hook_config, config_filename, state, monitoring_log_level, dry_
|
||||||
if not dry_run:
|
if not dry_run:
|
||||||
logging.getLogger('urllib3').setLevel(logging.ERROR)
|
logging.getLogger('urllib3').setLevel(logging.ERROR)
|
||||||
try:
|
try:
|
||||||
response = requests.get(ping_url)
|
requests.get(ping_url)
|
||||||
if not response.ok:
|
|
||||||
response.raise_for_status()
|
|
||||||
except requests.exceptions.RequestException as error:
|
except requests.exceptions.RequestException as error:
|
||||||
logger.warning(f'{config_filename}: Cronhub error: {error}')
|
logger.warning(f'{config_filename}: Cronhub error: {error}')
|
||||||
|
|
||||||
|
|
|
@ -38,9 +38,7 @@ def ping_monitor(hook_config, config_filename, state, monitoring_log_level, dry_
|
||||||
if not dry_run:
|
if not dry_run:
|
||||||
logging.getLogger('urllib3').setLevel(logging.ERROR)
|
logging.getLogger('urllib3').setLevel(logging.ERROR)
|
||||||
try:
|
try:
|
||||||
response = requests.get(ping_url)
|
requests.get(ping_url)
|
||||||
if not response.ok:
|
|
||||||
response.raise_for_status()
|
|
||||||
except requests.exceptions.RequestException as error:
|
except requests.exceptions.RequestException as error:
|
||||||
logger.warning(f'{config_filename}: Cronitor error: {error}')
|
logger.warning(f'{config_filename}: Cronitor error: {error}')
|
||||||
|
|
||||||
|
|
|
@ -1,27 +1,17 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from borgmatic.hooks import (
|
from borgmatic.hooks import cronhub, cronitor, healthchecks, mongodb, mysql, pagerduty, postgresql
|
||||||
cronhub,
|
|
||||||
cronitor,
|
|
||||||
healthchecks,
|
|
||||||
mongodb,
|
|
||||||
mysql,
|
|
||||||
ntfy,
|
|
||||||
pagerduty,
|
|
||||||
postgresql,
|
|
||||||
)
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
HOOK_NAME_TO_MODULE = {
|
HOOK_NAME_TO_MODULE = {
|
||||||
'cronhub': cronhub,
|
|
||||||
'cronitor': cronitor,
|
|
||||||
'healthchecks': healthchecks,
|
'healthchecks': healthchecks,
|
||||||
'mongodb_databases': mongodb,
|
'cronitor': cronitor,
|
||||||
'mysql_databases': mysql,
|
'cronhub': cronhub,
|
||||||
'ntfy': ntfy,
|
|
||||||
'pagerduty': pagerduty,
|
'pagerduty': pagerduty,
|
||||||
'postgresql_databases': postgresql,
|
'postgresql_databases': postgresql,
|
||||||
|
'mysql_databases': mysql,
|
||||||
|
'mongodb_databases': mongodb,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -125,9 +125,7 @@ def ping_monitor(hook_config, config_filename, state, monitoring_log_level, dry_
|
||||||
if not dry_run:
|
if not dry_run:
|
||||||
logging.getLogger('urllib3').setLevel(logging.ERROR)
|
logging.getLogger('urllib3').setLevel(logging.ERROR)
|
||||||
try:
|
try:
|
||||||
response = requests.post(ping_url, data=payload.encode('utf-8'))
|
requests.post(ping_url, data=payload.encode('utf-8'))
|
||||||
if not response.ok:
|
|
||||||
response.raise_for_status()
|
|
||||||
except requests.exceptions.RequestException as error:
|
except requests.exceptions.RequestException as error:
|
||||||
logger.warning(f'{config_filename}: Healthchecks error: {error}')
|
logger.warning(f'{config_filename}: Healthchecks error: {error}')
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
|
||||||
MONITOR_HOOK_NAMES = ('healthchecks', 'cronitor', 'cronhub', 'pagerduty', 'ntfy')
|
MONITOR_HOOK_NAMES = ('healthchecks', 'cronitor', 'cronhub', 'pagerduty')
|
||||||
|
|
||||||
|
|
||||||
class State(Enum):
|
class State(Enum):
|
||||||
|
|
|
@ -1,84 +0,0 @@
|
||||||
import logging
|
|
||||||
|
|
||||||
import requests
|
|
||||||
|
|
||||||
from borgmatic.hooks import monitor
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
MONITOR_STATE_TO_NTFY = {
|
|
||||||
monitor.State.START: None,
|
|
||||||
monitor.State.FINISH: None,
|
|
||||||
monitor.State.FAIL: None,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def initialize_monitor(
|
|
||||||
ping_url, config_filename, monitoring_log_level, dry_run
|
|
||||||
): # pragma: no cover
|
|
||||||
'''
|
|
||||||
No initialization is necessary for this monitor.
|
|
||||||
'''
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def ping_monitor(hook_config, config_filename, state, monitoring_log_level, dry_run):
|
|
||||||
'''
|
|
||||||
Ping the configured Ntfy topic. Use the given configuration filename in any log entries.
|
|
||||||
If this is a dry run, then don't actually ping anything.
|
|
||||||
'''
|
|
||||||
|
|
||||||
run_states = hook_config.get('states', ['fail'])
|
|
||||||
|
|
||||||
if state.name.lower() in run_states:
|
|
||||||
dry_run_label = ' (dry run; not actually pinging)' if dry_run else ''
|
|
||||||
|
|
||||||
state_config = hook_config.get(
|
|
||||||
state.name.lower(),
|
|
||||||
{
|
|
||||||
'title': f'A Borgmatic {state.name} event happened',
|
|
||||||
'message': f'A Borgmatic {state.name} event happened',
|
|
||||||
'priority': 'default',
|
|
||||||
'tags': 'borgmatic',
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
base_url = hook_config.get('server', 'https://ntfy.sh')
|
|
||||||
topic = hook_config.get('topic')
|
|
||||||
|
|
||||||
logger.info(f'{config_filename}: Pinging ntfy topic {topic}{dry_run_label}')
|
|
||||||
logger.debug(f'{config_filename}: Using Ntfy ping URL {base_url}/{topic}')
|
|
||||||
|
|
||||||
headers = {
|
|
||||||
'X-Title': state_config.get('title'),
|
|
||||||
'X-Message': state_config.get('message'),
|
|
||||||
'X-Priority': state_config.get('priority'),
|
|
||||||
'X-Tags': state_config.get('tags'),
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
base_url != 'https://ntfy.sh'
|
|
||||||
and hook_config.get('username') is not None
|
|
||||||
and hook_config.get('password') is not None
|
|
||||||
):
|
|
||||||
headers.update(
|
|
||||||
{'Authorization': f'{hook_config.get("username")}:{hook_config.get("password")}'}
|
|
||||||
)
|
|
||||||
|
|
||||||
if not dry_run:
|
|
||||||
logging.getLogger('urllib3').setLevel(logging.ERROR)
|
|
||||||
try:
|
|
||||||
response = requests.post(f'{base_url}/{topic}', headers=headers)
|
|
||||||
if not response.ok:
|
|
||||||
response.raise_for_status()
|
|
||||||
except requests.exceptions.RequestException as error:
|
|
||||||
logger.warning(f'{config_filename}: Ntfy error: {error}')
|
|
||||||
|
|
||||||
|
|
||||||
def destroy_monitor(
|
|
||||||
ping_url_or_uuid, config_filename, monitoring_log_level, dry_run
|
|
||||||
): # pragma: no cover
|
|
||||||
'''
|
|
||||||
No destruction is necessary for this monitor.
|
|
||||||
'''
|
|
||||||
pass
|
|
|
@ -69,9 +69,7 @@ def ping_monitor(hook_config, config_filename, state, monitoring_log_level, dry_
|
||||||
|
|
||||||
logging.getLogger('urllib3').setLevel(logging.ERROR)
|
logging.getLogger('urllib3').setLevel(logging.ERROR)
|
||||||
try:
|
try:
|
||||||
response = requests.post(EVENTS_API_URL, data=payload.encode('utf-8'))
|
requests.post(EVENTS_API_URL, data=payload.encode('utf-8'))
|
||||||
if not response.ok:
|
|
||||||
response.raise_for_status()
|
|
||||||
except requests.exceptions.RequestException as error:
|
except requests.exceptions.RequestException as error:
|
||||||
logger.warning(f'{config_filename}: PagerDuty error: {error}')
|
logger.warning(f'{config_filename}: PagerDuty error: {error}')
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
FROM alpine:3.16.0 as borgmatic
|
FROM python:3.8-alpine3.13 as borgmatic
|
||||||
|
|
||||||
COPY . /app
|
COPY . /app
|
||||||
RUN apk add --no-cache py3-pip py3-ruamel.yaml py3-ruamel.yaml.clib
|
RUN apk add --no-cache py3-ruamel.yaml py3-ruamel.yaml.clib
|
||||||
RUN pip install --no-cache /app && generate-borgmatic-config && chmod +r /etc/borgmatic/config.yaml
|
RUN pip install --no-cache /app && generate-borgmatic-config && chmod +r /etc/borgmatic/config.yaml
|
||||||
RUN borgmatic --help > /command-line.txt \
|
RUN borgmatic --help > /command-line.txt \
|
||||||
&& for action in init prune compact create check extract export-tar mount umount restore list info borg; do \
|
&& for action in init prune compact create check extract export-tar mount umount restore list info borg; do \
|
||||||
echo -e "\n--------------------------------------------------------------------------------\n" >> /command-line.txt \
|
echo -e "\n--------------------------------------------------------------------------------\n" >> /command-line.txt \
|
||||||
&& borgmatic "$action" --help >> /command-line.txt; done
|
&& borgmatic "$action" --help >> /command-line.txt; done
|
||||||
|
|
||||||
FROM node:18.4.0-alpine as html
|
FROM node:15.2.1-alpine as html
|
||||||
|
|
||||||
ARG ENVIRONMENT=production
|
ARG ENVIRONMENT=production
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ COPY . /source
|
||||||
RUN NODE_ENV=${ENVIRONMENT} npx eleventy --input=/source/docs --output=/output/docs \
|
RUN NODE_ENV=${ENVIRONMENT} npx eleventy --input=/source/docs --output=/output/docs \
|
||||||
&& mv /output/docs/index.html /output/index.html
|
&& mv /output/docs/index.html /output/index.html
|
||||||
|
|
||||||
FROM nginx:1.22.0-alpine
|
FROM nginx:1.19.4-alpine
|
||||||
|
|
||||||
COPY --from=html /output /usr/share/nginx/html
|
COPY --from=html /output /usr/share/nginx/html
|
||||||
COPY --from=borgmatic /etc/borgmatic/config.yaml /usr/share/nginx/html/docs/reference/config.yaml
|
COPY --from=borgmatic /etc/borgmatic/config.yaml /usr/share/nginx/html/docs/reference/config.yaml
|
||||||
|
|
|
@ -3,7 +3,7 @@ title: How to add preparation and cleanup steps to backups
|
||||||
eleventyNavigation:
|
eleventyNavigation:
|
||||||
key: 🧹 Add preparation and cleanup steps
|
key: 🧹 Add preparation and cleanup steps
|
||||||
parent: How-to guides
|
parent: How-to guides
|
||||||
order: 9
|
order: 8
|
||||||
---
|
---
|
||||||
## Preparation and cleanup hooks
|
## Preparation and cleanup hooks
|
||||||
|
|
||||||
|
@ -28,8 +28,7 @@ hooks:
|
||||||
- umount /some/filesystem
|
- umount /some/filesystem
|
||||||
```
|
```
|
||||||
|
|
||||||
<span class="minilink minilink-addedin">New in version 1.6.0</span> The
|
The `before_backup` and `after_backup` hooks each run once per repository in a
|
||||||
`before_backup` and `after_backup` hooks each run once per repository in a
|
|
||||||
configuration file. `before_backup` hooks runs right before the `create`
|
configuration file. `before_backup` hooks runs right before the `create`
|
||||||
action for a particular repository, and `after_backup` hooks run afterwards,
|
action for a particular repository, and `after_backup` hooks run afterwards,
|
||||||
but not if an error occurs in a previous hook or in the backups themselves.
|
but not if an error occurs in a previous hook or in the backups themselves.
|
||||||
|
@ -62,10 +61,6 @@ variables you can use here:
|
||||||
* `repository`: path of the current repository as configured in the current
|
* `repository`: path of the current repository as configured in the current
|
||||||
borgmatic configuration file
|
borgmatic configuration file
|
||||||
|
|
||||||
Note that you can also interpolate in [arbitrary environment
|
|
||||||
variables](https://torsion.org/borgmatic/docs/how-to/provide-your-passwords/).
|
|
||||||
|
|
||||||
|
|
||||||
## Global hooks
|
## Global hooks
|
||||||
|
|
||||||
You can also use `before_everything` and `after_everything` hooks to perform
|
You can also use `before_everything` and `after_everything` hooks to perform
|
||||||
|
|
|
@ -3,7 +3,7 @@ title: How to backup to a removable drive or an intermittent server
|
||||||
eleventyNavigation:
|
eleventyNavigation:
|
||||||
key: 💾 Backup to a removable drive/server
|
key: 💾 Backup to a removable drive/server
|
||||||
parent: How-to guides
|
parent: How-to guides
|
||||||
order: 10
|
order: 9
|
||||||
---
|
---
|
||||||
## Occasional backups
|
## Occasional backups
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ title: How to backup your databases
|
||||||
eleventyNavigation:
|
eleventyNavigation:
|
||||||
key: 🗄️ Backup your databases
|
key: 🗄️ Backup your databases
|
||||||
parent: How-to guides
|
parent: How-to guides
|
||||||
order: 8
|
order: 7
|
||||||
---
|
---
|
||||||
## Database dump hooks
|
## Database dump hooks
|
||||||
|
|
||||||
|
@ -100,14 +100,6 @@ hooks:
|
||||||
- name: all
|
- name: all
|
||||||
```
|
```
|
||||||
|
|
||||||
### External passwords
|
|
||||||
|
|
||||||
If you don't want to keep your database passwords in your borgmatic
|
|
||||||
configuration file, you can instead pass them in via [environment
|
|
||||||
variables](https://torsion.org/borgmatic/docs/how-to/provide-your-passwords/)
|
|
||||||
or command-line [configuration
|
|
||||||
overrides](https://torsion.org/borgmatic/docs/how-to/make-per-application-backups/#configuration-overrides).
|
|
||||||
|
|
||||||
|
|
||||||
### Configuration backups
|
### Configuration backups
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ title: How to deal with very large backups
|
||||||
eleventyNavigation:
|
eleventyNavigation:
|
||||||
key: 📏 Deal with very large backups
|
key: 📏 Deal with very large backups
|
||||||
parent: How-to guides
|
parent: How-to guides
|
||||||
order: 4
|
order: 3
|
||||||
---
|
---
|
||||||
## Biggish data
|
## Biggish data
|
||||||
|
|
||||||
|
@ -74,9 +74,8 @@ See [Borg's check documentation](https://borgbackup.readthedocs.io/en/stable/usa
|
||||||
|
|
||||||
### Check frequency
|
### Check frequency
|
||||||
|
|
||||||
<span class="minilink minilink-addedin">New in version 1.6.2</span> You can
|
As of borgmatic 1.6.2, you can optionally configure checks to run on a
|
||||||
optionally configure checks to run on a periodic basis rather than every time
|
periodic basis rather than every time borgmatic runs checks. For instance:
|
||||||
borgmatic runs checks. For instance:
|
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
consistency:
|
consistency:
|
||||||
|
@ -97,10 +96,6 @@ within `~/.borgmatic/checks`). If it hasn't been long enough, the check is
|
||||||
skipped. And you still have to run `borgmatic check` (or just `borgmatic`) in
|
skipped. And you still have to run `borgmatic check` (or just `borgmatic`) in
|
||||||
order for checks to run, even when a `frequency` is configured!
|
order for checks to run, even when a `frequency` is configured!
|
||||||
|
|
||||||
This also applies *across* configuration files that have the same repository
|
|
||||||
configured. Just make sure you have the same check frequency configured in
|
|
||||||
each—or the most frequently configured check will apply.
|
|
||||||
|
|
||||||
If you want to temporarily ignore your configured frequencies, you can invoke
|
If you want to temporarily ignore your configured frequencies, you can invoke
|
||||||
`borgmatic check --force` to run checks unconditionally.
|
`borgmatic check --force` to run checks unconditionally.
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ title: How to develop on borgmatic
|
||||||
eleventyNavigation:
|
eleventyNavigation:
|
||||||
key: 🏗️ Develop on borgmatic
|
key: 🏗️ Develop on borgmatic
|
||||||
parent: How-to guides
|
parent: How-to guides
|
||||||
order: 13
|
order: 12
|
||||||
---
|
---
|
||||||
## Source code
|
## Source code
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ title: How to extract a backup
|
||||||
eleventyNavigation:
|
eleventyNavigation:
|
||||||
key: 📤 Extract a backup
|
key: 📤 Extract a backup
|
||||||
parent: How-to guides
|
parent: How-to guides
|
||||||
order: 7
|
order: 6
|
||||||
---
|
---
|
||||||
## Extract
|
## Extract
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ title: How to inspect your backups
|
||||||
eleventyNavigation:
|
eleventyNavigation:
|
||||||
key: 🔎 Inspect your backups
|
key: 🔎 Inspect your backups
|
||||||
parent: How-to guides
|
parent: How-to guides
|
||||||
order: 5
|
order: 4
|
||||||
---
|
---
|
||||||
## Backup progress
|
## Backup progress
|
||||||
|
|
||||||
|
@ -53,10 +53,10 @@ borgmatic info
|
||||||
|
|
||||||
### Searching for a file
|
### Searching for a file
|
||||||
|
|
||||||
<span class="minilink minilink-addedin">New in version 1.6.3</span> Let's say
|
Let's say you've accidentally deleted a file and want to find the backup
|
||||||
you've accidentally deleted a file and want to find the backup archive(s)
|
archive(s) containing it. `borgmatic list` provides a `--find` flag for
|
||||||
containing it. `borgmatic list` provides a `--find` flag for exactly this
|
exactly this purpose (as of borgmatic 1.6.3). For instance, if you're looking
|
||||||
purpose. For instance, if you're looking for a `foo.txt`:
|
for a `foo.txt`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
borgmatic list --find foo.txt
|
borgmatic list --find foo.txt
|
||||||
|
|
|
@ -3,7 +3,7 @@ title: How to make backups redundant
|
||||||
eleventyNavigation:
|
eleventyNavigation:
|
||||||
key: ☁️ Make backups redundant
|
key: ☁️ Make backups redundant
|
||||||
parent: How-to guides
|
parent: How-to guides
|
||||||
order: 3
|
order: 2
|
||||||
---
|
---
|
||||||
## Multiple repositories
|
## Multiple repositories
|
||||||
|
|
||||||
|
|
|
@ -123,7 +123,11 @@ Once this include gets merged in, the resulting configuration would have a
|
||||||
`keep_hourly` value of `24` and an overridden `keep_daily` value of `5`.
|
`keep_hourly` value of `24` and an overridden `keep_daily` value of `5`.
|
||||||
|
|
||||||
When there's an option collision between the local file and the merged
|
When there's an option collision between the local file and the merged
|
||||||
include, the local file's option takes precedence.
|
include, the local file's option takes precedence. And as of borgmatic 1.6.0,
|
||||||
|
this feature performs a deep merge, meaning that values are merged at all
|
||||||
|
levels in the two configuration files. Colliding list values are appended
|
||||||
|
together. This allows you to include common configuration—up to full borgmatic
|
||||||
|
configuration files—while overriding only the parts you want to customize.
|
||||||
|
|
||||||
Note that this `<<` include merging syntax is only for merging in mappings
|
Note that this `<<` include merging syntax is only for merging in mappings
|
||||||
(configuration options and their values). But if you'd like to include a
|
(configuration options and their values). But if you'd like to include a
|
||||||
|
@ -135,16 +139,6 @@ global level, another `<<` within each configuration section, etc. (This is a
|
||||||
YAML limitation.)
|
YAML limitation.)
|
||||||
|
|
||||||
|
|
||||||
### Deep merge
|
|
||||||
|
|
||||||
<span class="minilink minilink-addedin">New in version 1.6.0</span> borgmatic
|
|
||||||
performs a deep merge of merged include files, meaning that values are merged
|
|
||||||
at all levels in the two configuration files. Colliding list values are
|
|
||||||
appended together. This allows you to include common configuration—up to full
|
|
||||||
borgmatic configuration files—while overriding only the parts you want to
|
|
||||||
customize.
|
|
||||||
|
|
||||||
|
|
||||||
## Configuration overrides
|
## Configuration overrides
|
||||||
|
|
||||||
In more complex multi-application setups, you may want to override particular
|
In more complex multi-application setups, you may want to override particular
|
||||||
|
@ -209,5 +203,3 @@ indentation and a leading dash.)
|
||||||
|
|
||||||
Be sure to quote your overrides if they contain spaces or other characters
|
Be sure to quote your overrides if they contain spaces or other characters
|
||||||
that your shell may interpret.
|
that your shell may interpret.
|
||||||
|
|
||||||
An alternate to command-line overrides is passing in your values via [environment variables](https://torsion.org/borgmatic/docs/how-to/provide-your-passwords/).
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ title: How to monitor your backups
|
||||||
eleventyNavigation:
|
eleventyNavigation:
|
||||||
key: 🚨 Monitor your backups
|
key: 🚨 Monitor your backups
|
||||||
parent: How-to guides
|
parent: How-to guides
|
||||||
order: 6
|
order: 5
|
||||||
---
|
---
|
||||||
|
|
||||||
## Monitoring and alerting
|
## Monitoring and alerting
|
||||||
|
@ -38,19 +38,17 @@ below for how to configure this.
|
||||||
|
|
||||||
borgmatic integrates with monitoring services like
|
borgmatic integrates with monitoring services like
|
||||||
[Healthchecks](https://healthchecks.io/), [Cronitor](https://cronitor.io),
|
[Healthchecks](https://healthchecks.io/), [Cronitor](https://cronitor.io),
|
||||||
[Cronhub](https://cronhub.io), [PagerDuty](https://www.pagerduty.com/), and
|
[Cronhub](https://cronhub.io), and [PagerDuty](https://www.pagerduty.com/) and
|
||||||
[ntfy](https://ntfy.sh/) and pings these services whenever borgmatic runs.
|
pings these services whenever borgmatic runs. That way, you'll receive an
|
||||||
That way, you'll receive an alert when something goes wrong or (for certain
|
alert when something goes wrong or (for certain hooks) the service doesn't
|
||||||
hooks) the service doesn't hear from borgmatic for a configured interval. See
|
hear from borgmatic for a configured interval. See [Healthchecks
|
||||||
[Healthchecks
|
|
||||||
hook](https://torsion.org/borgmatic/docs/how-to/monitor-your-backups/#healthchecks-hook),
|
hook](https://torsion.org/borgmatic/docs/how-to/monitor-your-backups/#healthchecks-hook),
|
||||||
[Cronitor
|
[Cronitor
|
||||||
hook](https://torsion.org/borgmatic/docs/how-to/monitor-your-backups/#cronitor-hook),
|
hook](https://torsion.org/borgmatic/docs/how-to/monitor-your-backups/#cronitor-hook),
|
||||||
[Cronhub
|
[Cronhub
|
||||||
hook](https://torsion.org/borgmatic/docs/how-to/monitor-your-backups/#cronhub-hook),
|
hook](https://torsion.org/borgmatic/docs/how-to/monitor-your-backups/#cronhub-hook),
|
||||||
[PagerDuty
|
and [PagerDuty
|
||||||
hook](https://torsion.org/borgmatic/docs/how-to/monitor-your-backups/#pagerduty-hook),
|
hook](https://torsion.org/borgmatic/docs/how-to/monitor-your-backups/#pagerduty-hook)
|
||||||
and [ntfy hook](https://torsion.org/borgmatic/docs/how-to/monitor-your-backups/#ntfy-hook)
|
|
||||||
below for how to configure this.
|
below for how to configure this.
|
||||||
|
|
||||||
While these services offer different features, you probably only need to use
|
While these services offer different features, you probably only need to use
|
||||||
|
@ -61,6 +59,8 @@ one of them at most.
|
||||||
You can use traditional monitoring software to consume borgmatic JSON output
|
You can use traditional monitoring software to consume borgmatic JSON output
|
||||||
and track when the last successful backup occurred. See [scripting
|
and track when the last successful backup occurred. See [scripting
|
||||||
borgmatic](https://torsion.org/borgmatic/docs/how-to/monitor-your-backups/#scripting-borgmatic)
|
borgmatic](https://torsion.org/borgmatic/docs/how-to/monitor-your-backups/#scripting-borgmatic)
|
||||||
|
and [related
|
||||||
|
software](https://torsion.org/borgmatic/docs/how-to/monitor-your-backups/#related-software)
|
||||||
below for how to configure this.
|
below for how to configure this.
|
||||||
|
|
||||||
### Borg hosting providers
|
### Borg hosting providers
|
||||||
|
@ -270,58 +270,6 @@ If you have any issues with the integration, [please contact
|
||||||
us](https://torsion.org/borgmatic/#support-and-contributing).
|
us](https://torsion.org/borgmatic/#support-and-contributing).
|
||||||
|
|
||||||
|
|
||||||
## ntfy hook
|
|
||||||
|
|
||||||
[ntfy](https://ntfy.sh) is a free, simple, service (either hosted or self-hosted)
|
|
||||||
which offers simple pub/sub push notifications to multiple platforms including
|
|
||||||
[web](https://ntfy.sh/stats), [Android](https://play.google.com/store/apps/details?id=io.heckel.ntfy)
|
|
||||||
and [iOS](https://apps.apple.com/us/app/ntfy/id1625396347).
|
|
||||||
|
|
||||||
Since push notifications for regular events might soon become quite annoying,
|
|
||||||
this hook only fires on any errors by default in order to instantly alert you to issues.
|
|
||||||
The `states` list can override this.
|
|
||||||
|
|
||||||
As ntfy is unauthenticated, it isn't a suitable channel for any private information
|
|
||||||
so the default messages are intentionally generic. These can be overridden, depending
|
|
||||||
on your risk assessment. Each `state` can have its own custom messages, priorities and tags
|
|
||||||
or, if none are provided, will use the default.
|
|
||||||
|
|
||||||
A [self-hosted ntfy instance](https://ntfy.sh/docs/install/) can be used if desired,
|
|
||||||
including support for Basic Authentication using the `username` and `password` fields
|
|
||||||
with a custom `server` value
|
|
||||||
|
|
||||||
An example configuration is shown here, with all the available options, including
|
|
||||||
[priorities](https://ntfy.sh/docs/publish/#message-priority) and
|
|
||||||
[tags](https://ntfy.sh/docs/publish/#tags-emojis):
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
hooks:
|
|
||||||
ntfy:
|
|
||||||
topic: my-unique-topic
|
|
||||||
server: https://ntfy.my-domain.com
|
|
||||||
username: borgmatic
|
|
||||||
password: superSecretP@ssw0rd
|
|
||||||
start:
|
|
||||||
title: A Borgmatic backup started
|
|
||||||
message: Watch this space...
|
|
||||||
tags: borgmatic
|
|
||||||
priority: min
|
|
||||||
finish:
|
|
||||||
title: A Borgmatic backup completed successfully
|
|
||||||
message: Nice!
|
|
||||||
tags: borgmatic,+1
|
|
||||||
priority: min
|
|
||||||
fail:
|
|
||||||
title: A Borgmatic backup failed
|
|
||||||
message: You should probably fix it
|
|
||||||
tags: borgmatic,-1,skull
|
|
||||||
priority: max
|
|
||||||
states:
|
|
||||||
- start
|
|
||||||
- finish
|
|
||||||
- fail
|
|
||||||
```
|
|
||||||
|
|
||||||
## Scripting borgmatic
|
## Scripting borgmatic
|
||||||
|
|
||||||
To consume the output of borgmatic in other software, you can include an
|
To consume the output of borgmatic in other software, you can include an
|
||||||
|
@ -333,6 +281,11 @@ suppressed so as not to interfere with the captured JSON. Also note that JSON
|
||||||
output only shows up at the console, and not in syslog.
|
output only shows up at the console, and not in syslog.
|
||||||
|
|
||||||
|
|
||||||
|
## Related software
|
||||||
|
|
||||||
|
* [Borgmacator GNOME AppIndicator](https://github.com/N-Coder/borgmacator/)
|
||||||
|
|
||||||
|
|
||||||
### Latest backups
|
### Latest backups
|
||||||
|
|
||||||
All borgmatic actions that accept an "--archive" flag allow you to specify an
|
All borgmatic actions that accept an "--archive" flag allow you to specify an
|
||||||
|
|
|
@ -1,90 +0,0 @@
|
||||||
---
|
|
||||||
title: How to provide your passwords
|
|
||||||
eleventyNavigation:
|
|
||||||
key: 🔒 Provide your passwords
|
|
||||||
parent: How-to guides
|
|
||||||
order: 2
|
|
||||||
---
|
|
||||||
## Environment variable interpolation
|
|
||||||
|
|
||||||
If you want to use a Borg repository passphrase or database passwords with
|
|
||||||
borgmatic, you can set them directly in your borgmatic configuration file,
|
|
||||||
treating those secrets like any other option value. But if you'd rather store
|
|
||||||
them outside of borgmatic, whether for convenience or security reasons, read
|
|
||||||
on.
|
|
||||||
|
|
||||||
<span class="minilink minilink-addedin">New in version 1.6.4</span> borgmatic
|
|
||||||
supports interpolating arbitrary environment variables directly into option
|
|
||||||
values in your configuration file. That means you can instruct borgmatic to
|
|
||||||
pull your repository passphrase, your database passwords, or any other option
|
|
||||||
values from environment variables. For instance:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
storage:
|
|
||||||
encryption_passphrase: ${MY_PASSPHRASE}
|
|
||||||
```
|
|
||||||
|
|
||||||
This uses the `MY_PASSPHRASE` environment variable as your encryption
|
|
||||||
passphrase. Note that the `{` `}` brackets are required. Just `$MY_PASSPHRASE`
|
|
||||||
will not work.
|
|
||||||
|
|
||||||
In the case of `encryption_passphrase` in particular, an alternate approach
|
|
||||||
is to use Borg's `BORG_PASSPHRASE` environment variable, which doesn't even
|
|
||||||
require setting an explicit `encryption_passphrase` value in borgmatic's
|
|
||||||
configuration file.
|
|
||||||
|
|
||||||
For [database
|
|
||||||
configuration](https://torsion.org/borgmatic/docs/how-to/backup-your-databases/),
|
|
||||||
the same approach applies. For example:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
hooks:
|
|
||||||
postgresql_databases:
|
|
||||||
- name: users
|
|
||||||
password: ${MY_DATABASE_PASSWORD}
|
|
||||||
```
|
|
||||||
|
|
||||||
This uses the `MY_DATABASE_PASSWORD` environment variable as your database
|
|
||||||
password.
|
|
||||||
|
|
||||||
|
|
||||||
### Interpolation defaults
|
|
||||||
|
|
||||||
If you'd like to set a default for your environment variables, you can do so with the following syntax:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
storage:
|
|
||||||
encryption_passphrase: ${MY_PASSPHRASE:-defaultpass}
|
|
||||||
```
|
|
||||||
|
|
||||||
Here, "`defaultpass`" is the default passphrase if the `MY_PASSPHRASE`
|
|
||||||
environment variable is not set. Without a default, if the environment
|
|
||||||
variable doesn't exist, borgmatic will error.
|
|
||||||
|
|
||||||
|
|
||||||
### Disabling interpolation
|
|
||||||
|
|
||||||
To disable this environment variable interpolation feature entirely, you can
|
|
||||||
pass the `--no-environment-interpolation` flag on the command-line.
|
|
||||||
|
|
||||||
Or if you'd like to disable interpolation within a single option value, you
|
|
||||||
can escape it with a backslash. For instance, if your password is literally
|
|
||||||
`${A}@!`:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
storage:
|
|
||||||
encryption_passphrase: \${A}@!
|
|
||||||
```
|
|
||||||
|
|
||||||
### Related features
|
|
||||||
|
|
||||||
Another way to override particular options within a borgmatic configuration
|
|
||||||
file is to use a [configuration
|
|
||||||
override](https://torsion.org/borgmatic/docs/how-to/make-per-application-backups/#configuration-overrides)
|
|
||||||
on the command-line. But please be aware of the security implications of
|
|
||||||
specifying secrets on the command-line.
|
|
||||||
|
|
||||||
Additionally, borgmatic action hooks support their own [variable
|
|
||||||
interpolation](https://torsion.org/borgmatic/docs/how-to/add-preparation-and-cleanup-steps-to-backups/#variable-interpolation),
|
|
||||||
although in that case it's for particular borgmatic runtime values rather than
|
|
||||||
(only) environment variables.
|
|
|
@ -3,7 +3,7 @@ title: How to run arbitrary Borg commands
|
||||||
eleventyNavigation:
|
eleventyNavigation:
|
||||||
key: 🔧 Run arbitrary Borg commands
|
key: 🔧 Run arbitrary Borg commands
|
||||||
parent: How-to guides
|
parent: How-to guides
|
||||||
order: 11
|
order: 10
|
||||||
---
|
---
|
||||||
## Running Borg with borgmatic
|
## Running Borg with borgmatic
|
||||||
|
|
||||||
|
|
|
@ -226,37 +226,24 @@ good idea to test that borgmatic is working. So to run borgmatic and start a
|
||||||
backup, you can invoke it like this:
|
backup, you can invoke it like this:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo borgmatic create --verbosity 1 --files --stats
|
sudo borgmatic --verbosity 1 --files
|
||||||
```
|
```
|
||||||
|
|
||||||
(No borgmatic `--files` flag? It's only present in newer versions of
|
(No borgmatic `--files` flag? It's only present in newer versions of
|
||||||
borgmatic. So try leaving it out, or upgrade borgmatic!)
|
borgmatic. So try leaving it out, or upgrade borgmatic!)
|
||||||
|
|
||||||
The `--verbosity` flag makes borgmatic show the steps it's performing. The
|
By default, this will also prune any old backups as per the configured
|
||||||
`--files` flag lists each file that's new or changed since the last backup.
|
retention policy, compact segments to free up space (with Borg 1.2+), and
|
||||||
And `--stats` shows summary information about the created archive. All of
|
check backups for consistency problems due to things like file damage.
|
||||||
these flags are optional.
|
|
||||||
|
|
||||||
As the command runs, you should eyeball the output to see if it matches your
|
The verbosity flag makes borgmatic show the steps it's performing. And the
|
||||||
expectations based on your configuration.
|
files flag lists each file that's new or changed since the last backup.
|
||||||
|
Eyeball the list and see if it matches your expectations based on the
|
||||||
|
configuration.
|
||||||
|
|
||||||
If you'd like to specify an alternate configuration file path, use the
|
If you'd like to specify an alternate configuration file path, use the
|
||||||
`--config` flag.
|
`--config` flag. See `borgmatic --help` for more information.
|
||||||
|
|
||||||
See `borgmatic --help` and `borgmatic create --help` for more information.
|
|
||||||
|
|
||||||
|
|
||||||
## Default actions
|
|
||||||
|
|
||||||
If you omit `create` and other actions, borgmatic runs through a set of
|
|
||||||
default actions: `prune` any old backups as per the configured retention
|
|
||||||
policy, `compact` segments to free up space (with Borg 1.2+), `create` a
|
|
||||||
backup, *and* `check` backups for consistency problems due to things like file
|
|
||||||
damage. For instance:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo borgmatic --verbosity 1 --files --stats
|
|
||||||
```
|
|
||||||
|
|
||||||
## Autopilot
|
## Autopilot
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ title: How to upgrade borgmatic
|
||||||
eleventyNavigation:
|
eleventyNavigation:
|
||||||
key: 📦 Upgrade borgmatic
|
key: 📦 Upgrade borgmatic
|
||||||
parent: How-to guides
|
parent: How-to guides
|
||||||
order: 12
|
order: 11
|
||||||
---
|
---
|
||||||
## Upgrading
|
## Upgrading
|
||||||
|
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 10 KiB |
|
@ -21,12 +21,6 @@ if [[ $version =~ .*dev* ]]; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! git diff-index --quiet HEAD -- ; then
|
|
||||||
echo "Refusing to release with local changes:"
|
|
||||||
git status --porcelain
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
git tag $version
|
git tag $version
|
||||||
git push origin $version
|
git push origin $version
|
||||||
git push github $version
|
git push github $version
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -1,6 +1,6 @@
|
||||||
from setuptools import find_packages, setup
|
from setuptools import find_packages, setup
|
||||||
|
|
||||||
VERSION = '1.6.5'
|
VERSION = '1.6.3.dev0'
|
||||||
|
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
|
|
|
@ -113,7 +113,7 @@ def test_write_configuration_with_already_existing_file_raises():
|
||||||
def test_write_configuration_with_already_existing_file_and_overwrite_does_not_raise():
|
def test_write_configuration_with_already_existing_file_and_overwrite_does_not_raise():
|
||||||
flexmock(os.path).should_receive('exists').and_return(True)
|
flexmock(os.path).should_receive('exists').and_return(True)
|
||||||
|
|
||||||
module.write_configuration('/tmp/config.yaml', 'config: yaml', overwrite=True)
|
module.write_configuration('config.yaml', 'config: yaml', overwrite=True)
|
||||||
|
|
||||||
|
|
||||||
def test_write_configuration_with_already_existing_directory_does_not_raise():
|
def test_write_configuration_with_already_existing_directory_does_not_raise():
|
||||||
|
|
|
@ -70,27 +70,6 @@ def test_log_outputs_includes_error_output_in_exception():
|
||||||
assert error.value.output
|
assert error.value.output
|
||||||
|
|
||||||
|
|
||||||
def test_log_outputs_logs_multiline_error_output():
|
|
||||||
'''
|
|
||||||
Make sure that all error output lines get logged, not just (for instance) the first few lines
|
|
||||||
of a process' traceback.
|
|
||||||
'''
|
|
||||||
flexmock(module.logger).should_receive('log')
|
|
||||||
flexmock(module).should_receive('exit_code_indicates_error').and_return(True)
|
|
||||||
flexmock(module).should_receive('command_for_process').and_return('grep')
|
|
||||||
|
|
||||||
process = subprocess.Popen(
|
|
||||||
['python', '-c', 'foopydoo'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT
|
|
||||||
)
|
|
||||||
flexmock(module).should_receive('output_buffer_for_process').and_return(process.stdout)
|
|
||||||
flexmock(module.logger).should_call('log').at_least().times(3)
|
|
||||||
|
|
||||||
with pytest.raises(subprocess.CalledProcessError):
|
|
||||||
module.log_outputs(
|
|
||||||
(process,), exclude_stdouts=(), output_log_level=logging.INFO, borg_local_path='borg'
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_log_outputs_skips_error_output_in_exception_for_process_with_none_stdout():
|
def test_log_outputs_skips_error_output_in_exception_for_process_with_none_stdout():
|
||||||
flexmock(module.logger).should_receive('log')
|
flexmock(module.logger).should_receive('log')
|
||||||
flexmock(module).should_receive('exit_code_indicates_error').and_return(True)
|
flexmock(module).should_receive('exit_code_indicates_error').and_return(True)
|
||||||
|
|
|
@ -8,12 +8,8 @@ from ..test_verbosity import insert_logging_mock
|
||||||
|
|
||||||
|
|
||||||
def test_run_arbitrary_borg_calls_borg_with_parameters():
|
def test_run_arbitrary_borg_calls_borg_with_parameters():
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'break-lock', 'repo'),
|
('borg', 'break-lock', 'repo'), output_log_level=logging.WARNING, borg_local_path='borg'
|
||||||
output_log_level=logging.WARNING,
|
|
||||||
borg_local_path='borg',
|
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.run_arbitrary_borg(
|
module.run_arbitrary_borg(
|
||||||
|
@ -22,12 +18,10 @@ def test_run_arbitrary_borg_calls_borg_with_parameters():
|
||||||
|
|
||||||
|
|
||||||
def test_run_arbitrary_borg_with_log_info_calls_borg_with_info_parameter():
|
def test_run_arbitrary_borg_with_log_info_calls_borg_with_info_parameter():
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'break-lock', 'repo', '--info'),
|
('borg', 'break-lock', 'repo', '--info'),
|
||||||
output_log_level=logging.WARNING,
|
output_log_level=logging.WARNING,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
insert_logging_mock(logging.INFO)
|
insert_logging_mock(logging.INFO)
|
||||||
|
|
||||||
|
@ -37,12 +31,10 @@ def test_run_arbitrary_borg_with_log_info_calls_borg_with_info_parameter():
|
||||||
|
|
||||||
|
|
||||||
def test_run_arbitrary_borg_with_log_debug_calls_borg_with_debug_parameter():
|
def test_run_arbitrary_borg_with_log_debug_calls_borg_with_debug_parameter():
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'break-lock', 'repo', '--debug', '--show-rc'),
|
('borg', 'break-lock', 'repo', '--debug', '--show-rc'),
|
||||||
output_log_level=logging.WARNING,
|
output_log_level=logging.WARNING,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
insert_logging_mock(logging.DEBUG)
|
insert_logging_mock(logging.DEBUG)
|
||||||
|
|
||||||
|
@ -53,12 +45,10 @@ def test_run_arbitrary_borg_with_log_debug_calls_borg_with_debug_parameter():
|
||||||
|
|
||||||
def test_run_arbitrary_borg_with_lock_wait_calls_borg_with_lock_wait_parameters():
|
def test_run_arbitrary_borg_with_lock_wait_calls_borg_with_lock_wait_parameters():
|
||||||
storage_config = {'lock_wait': 5}
|
storage_config = {'lock_wait': 5}
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'break-lock', 'repo', '--lock-wait', '5'),
|
('borg', 'break-lock', 'repo', '--lock-wait', '5'),
|
||||||
output_log_level=logging.WARNING,
|
output_log_level=logging.WARNING,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.run_arbitrary_borg(
|
module.run_arbitrary_borg(
|
||||||
|
@ -68,12 +58,10 @@ def test_run_arbitrary_borg_with_lock_wait_calls_borg_with_lock_wait_parameters(
|
||||||
|
|
||||||
def test_run_arbitrary_borg_with_archive_calls_borg_with_archive_parameter():
|
def test_run_arbitrary_borg_with_archive_calls_borg_with_archive_parameter():
|
||||||
storage_config = {}
|
storage_config = {}
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'break-lock', 'repo::archive'),
|
('borg', 'break-lock', 'repo::archive'),
|
||||||
output_log_level=logging.WARNING,
|
output_log_level=logging.WARNING,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.run_arbitrary_borg(
|
module.run_arbitrary_borg(
|
||||||
|
@ -82,12 +70,8 @@ def test_run_arbitrary_borg_with_archive_calls_borg_with_archive_parameter():
|
||||||
|
|
||||||
|
|
||||||
def test_run_arbitrary_borg_with_local_path_calls_borg_via_local_path():
|
def test_run_arbitrary_borg_with_local_path_calls_borg_via_local_path():
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg1', 'break-lock', 'repo'),
|
('borg1', 'break-lock', 'repo'), output_log_level=logging.WARNING, borg_local_path='borg1'
|
||||||
output_log_level=logging.WARNING,
|
|
||||||
borg_local_path='borg1',
|
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.run_arbitrary_borg(
|
module.run_arbitrary_borg(
|
||||||
|
@ -96,12 +80,10 @@ def test_run_arbitrary_borg_with_local_path_calls_borg_via_local_path():
|
||||||
|
|
||||||
|
|
||||||
def test_run_arbitrary_borg_with_remote_path_calls_borg_with_remote_path_parameters():
|
def test_run_arbitrary_borg_with_remote_path_calls_borg_with_remote_path_parameters():
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'break-lock', 'repo', '--remote-path', 'borg1'),
|
('borg', 'break-lock', 'repo', '--remote-path', 'borg1'),
|
||||||
output_log_level=logging.WARNING,
|
output_log_level=logging.WARNING,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.run_arbitrary_borg(
|
module.run_arbitrary_borg(
|
||||||
|
@ -110,12 +92,10 @@ def test_run_arbitrary_borg_with_remote_path_calls_borg_with_remote_path_paramet
|
||||||
|
|
||||||
|
|
||||||
def test_run_arbitrary_borg_passes_borg_specific_parameters_to_borg():
|
def test_run_arbitrary_borg_passes_borg_specific_parameters_to_borg():
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'list', 'repo', '--progress'),
|
('borg', 'list', 'repo', '--progress'),
|
||||||
output_log_level=logging.WARNING,
|
output_log_level=logging.WARNING,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.run_arbitrary_borg(
|
module.run_arbitrary_borg(
|
||||||
|
@ -124,12 +104,8 @@ def test_run_arbitrary_borg_passes_borg_specific_parameters_to_borg():
|
||||||
|
|
||||||
|
|
||||||
def test_run_arbitrary_borg_omits_dash_dash_in_parameters_passed_to_borg():
|
def test_run_arbitrary_borg_omits_dash_dash_in_parameters_passed_to_borg():
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'break-lock', 'repo'),
|
('borg', 'break-lock', 'repo'), output_log_level=logging.WARNING, borg_local_path='borg',
|
||||||
output_log_level=logging.WARNING,
|
|
||||||
borg_local_path='borg',
|
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.run_arbitrary_borg(
|
module.run_arbitrary_borg(
|
||||||
|
@ -138,9 +114,8 @@ def test_run_arbitrary_borg_omits_dash_dash_in_parameters_passed_to_borg():
|
||||||
|
|
||||||
|
|
||||||
def test_run_arbitrary_borg_without_borg_specific_parameters_does_not_raise():
|
def test_run_arbitrary_borg_without_borg_specific_parameters_does_not_raise():
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg',), output_log_level=logging.WARNING, borg_local_path='borg', extra_environment=None,
|
('borg',), output_log_level=logging.WARNING, borg_local_path='borg',
|
||||||
)
|
)
|
||||||
|
|
||||||
module.run_arbitrary_borg(
|
module.run_arbitrary_borg(
|
||||||
|
@ -149,12 +124,8 @@ def test_run_arbitrary_borg_without_borg_specific_parameters_does_not_raise():
|
||||||
|
|
||||||
|
|
||||||
def test_run_arbitrary_borg_passes_key_sub_command_to_borg_before_repository():
|
def test_run_arbitrary_borg_passes_key_sub_command_to_borg_before_repository():
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'key', 'export', 'repo'),
|
('borg', 'key', 'export', 'repo'), output_log_level=logging.WARNING, borg_local_path='borg',
|
||||||
output_log_level=logging.WARNING,
|
|
||||||
borg_local_path='borg',
|
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.run_arbitrary_borg(
|
module.run_arbitrary_borg(
|
||||||
|
@ -163,12 +134,10 @@ def test_run_arbitrary_borg_passes_key_sub_command_to_borg_before_repository():
|
||||||
|
|
||||||
|
|
||||||
def test_run_arbitrary_borg_passes_debug_sub_command_to_borg_before_repository():
|
def test_run_arbitrary_borg_passes_debug_sub_command_to_borg_before_repository():
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'debug', 'dump-manifest', 'repo', 'path'),
|
('borg', 'debug', 'dump-manifest', 'repo', 'path'),
|
||||||
output_log_level=logging.WARNING,
|
output_log_level=logging.WARNING,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.run_arbitrary_borg(
|
module.run_arbitrary_borg(
|
||||||
|
@ -177,12 +146,8 @@ def test_run_arbitrary_borg_passes_debug_sub_command_to_borg_before_repository()
|
||||||
|
|
||||||
|
|
||||||
def test_run_arbitrary_borg_with_debug_info_command_does_not_pass_borg_repository():
|
def test_run_arbitrary_borg_with_debug_info_command_does_not_pass_borg_repository():
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'debug', 'info'),
|
('borg', 'debug', 'info'), output_log_level=logging.WARNING, borg_local_path='borg',
|
||||||
output_log_level=logging.WARNING,
|
|
||||||
borg_local_path='borg',
|
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.run_arbitrary_borg(
|
module.run_arbitrary_borg(
|
||||||
|
@ -191,12 +156,10 @@ def test_run_arbitrary_borg_with_debug_info_command_does_not_pass_borg_repositor
|
||||||
|
|
||||||
|
|
||||||
def test_run_arbitrary_borg_with_debug_convert_profile_command_does_not_pass_borg_repository():
|
def test_run_arbitrary_borg_with_debug_convert_profile_command_does_not_pass_borg_repository():
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'debug', 'convert-profile', 'in', 'out'),
|
('borg', 'debug', 'convert-profile', 'in', 'out'),
|
||||||
output_log_level=logging.WARNING,
|
output_log_level=logging.WARNING,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.run_arbitrary_borg(
|
module.run_arbitrary_borg(
|
||||||
|
|
|
@ -9,10 +9,7 @@ from ..test_verbosity import insert_logging_mock
|
||||||
|
|
||||||
|
|
||||||
def insert_execute_command_mock(command):
|
def insert_execute_command_mock(command):
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
flexmock(module).should_receive('execute_command').with_args(command).once()
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
|
||||||
command, extra_environment=None
|
|
||||||
).once()
|
|
||||||
|
|
||||||
|
|
||||||
def insert_execute_command_never():
|
def insert_execute_command_never():
|
||||||
|
@ -313,11 +310,8 @@ def test_check_archives_with_progress_calls_borg_with_progress_parameter():
|
||||||
)
|
)
|
||||||
flexmock(module).should_receive('make_check_flags').and_return(())
|
flexmock(module).should_receive('make_check_flags').and_return(())
|
||||||
flexmock(module).should_receive('execute_command').never()
|
flexmock(module).should_receive('execute_command').never()
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'check', '--progress', 'repo'),
|
('borg', 'check', '--progress', 'repo'), output_file=module.DO_NOT_CAPTURE
|
||||||
output_file=module.DO_NOT_CAPTURE,
|
|
||||||
extra_environment=None,
|
|
||||||
).once()
|
).once()
|
||||||
flexmock(module).should_receive('make_check_time_path')
|
flexmock(module).should_receive('make_check_time_path')
|
||||||
flexmock(module).should_receive('write_check_time')
|
flexmock(module).should_receive('write_check_time')
|
||||||
|
@ -341,11 +335,8 @@ def test_check_archives_with_repair_calls_borg_with_repair_parameter():
|
||||||
)
|
)
|
||||||
flexmock(module).should_receive('make_check_flags').and_return(())
|
flexmock(module).should_receive('make_check_flags').and_return(())
|
||||||
flexmock(module).should_receive('execute_command').never()
|
flexmock(module).should_receive('execute_command').never()
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'check', '--repair', 'repo'),
|
('borg', 'check', '--repair', 'repo'), output_file=module.DO_NOT_CAPTURE
|
||||||
output_file=module.DO_NOT_CAPTURE,
|
|
||||||
extra_environment=None,
|
|
||||||
).once()
|
).once()
|
||||||
flexmock(module).should_receive('make_check_time_path')
|
flexmock(module).should_receive('make_check_time_path')
|
||||||
flexmock(module).should_receive('write_check_time')
|
flexmock(module).should_receive('write_check_time')
|
||||||
|
|
|
@ -8,12 +8,8 @@ from ..test_verbosity import insert_logging_mock
|
||||||
|
|
||||||
|
|
||||||
def insert_execute_command_mock(compact_command, output_log_level):
|
def insert_execute_command_mock(compact_command, output_log_level):
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
compact_command,
|
compact_command, output_log_level=output_log_level, borg_local_path=compact_command[0]
|
||||||
output_log_level=output_log_level,
|
|
||||||
borg_local_path=compact_command[0],
|
|
||||||
extra_environment=None,
|
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -292,50 +292,12 @@ def test_create_archive_calls_borg_with_parameters():
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create') + ARCHIVE_WITH_PATHS,
|
('borg', 'create') + ARCHIVE_WITH_PATHS,
|
||||||
output_log_level=logging.INFO,
|
output_log_level=logging.INFO,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
|
||||||
|
|
||||||
module.create_archive(
|
|
||||||
dry_run=False,
|
|
||||||
repository='repo',
|
|
||||||
location_config={
|
|
||||||
'source_directories': ['foo', 'bar'],
|
|
||||||
'repositories': ['repo'],
|
|
||||||
'exclude_patterns': None,
|
|
||||||
},
|
|
||||||
storage_config={},
|
|
||||||
local_borg_version='1.2.3',
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_create_archive_calls_borg_with_environment():
|
|
||||||
flexmock(module).should_receive('borgmatic_source_directories').and_return([])
|
|
||||||
flexmock(module).should_receive('deduplicate_directories').and_return(('foo', 'bar'))
|
|
||||||
flexmock(module).should_receive('map_directories_to_devices').and_return({})
|
|
||||||
flexmock(module).should_receive('expand_directories').and_return(())
|
|
||||||
flexmock(module.os.path).should_receive('expanduser').and_raise(TypeError)
|
|
||||||
flexmock(module).should_receive('expand_home_directories').and_return(())
|
|
||||||
flexmock(module).should_receive('write_pattern_file').and_return(None)
|
|
||||||
flexmock(module.feature).should_receive('available').and_return(True)
|
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
|
||||||
environment = {'BORG_THINGY': 'YUP'}
|
|
||||||
flexmock(module.environment).should_receive('make_environment').and_return(environment)
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
|
||||||
('borg', 'create') + ARCHIVE_WITH_PATHS,
|
|
||||||
output_log_level=logging.INFO,
|
|
||||||
output_file=None,
|
|
||||||
borg_local_path='borg',
|
|
||||||
working_directory=None,
|
|
||||||
extra_environment=environment,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.create_archive(
|
module.create_archive(
|
||||||
|
@ -366,14 +328,12 @@ def test_create_archive_with_patterns_calls_borg_with_patterns():
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(pattern_flags)
|
flexmock(module).should_receive('make_pattern_flags').and_return(pattern_flags)
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create') + pattern_flags + ARCHIVE_WITH_PATHS,
|
('borg', 'create') + pattern_flags + ARCHIVE_WITH_PATHS,
|
||||||
output_log_level=logging.INFO,
|
output_log_level=logging.INFO,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.create_archive(
|
module.create_archive(
|
||||||
|
@ -404,14 +364,12 @@ def test_create_archive_with_exclude_patterns_calls_borg_with_excludes():
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(exclude_flags)
|
flexmock(module).should_receive('make_exclude_flags').and_return(exclude_flags)
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create') + exclude_flags + ARCHIVE_WITH_PATHS,
|
('borg', 'create') + exclude_flags + ARCHIVE_WITH_PATHS,
|
||||||
output_log_level=logging.INFO,
|
output_log_level=logging.INFO,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.create_archive(
|
module.create_archive(
|
||||||
|
@ -439,14 +397,12 @@ def test_create_archive_with_log_info_calls_borg_with_info_parameter():
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create', '--info') + ARCHIVE_WITH_PATHS,
|
('borg', 'create', '--info') + ARCHIVE_WITH_PATHS,
|
||||||
output_log_level=logging.INFO,
|
output_log_level=logging.INFO,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
insert_logging_mock(logging.INFO)
|
insert_logging_mock(logging.INFO)
|
||||||
|
|
||||||
|
@ -475,14 +431,12 @@ def test_create_archive_with_log_info_and_json_suppresses_most_borg_output():
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create', '--json') + ARCHIVE_WITH_PATHS,
|
('borg', 'create', '--json') + ARCHIVE_WITH_PATHS,
|
||||||
output_log_level=None,
|
output_log_level=None,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
insert_logging_mock(logging.INFO)
|
insert_logging_mock(logging.INFO)
|
||||||
|
|
||||||
|
@ -512,14 +466,12 @@ def test_create_archive_with_log_debug_calls_borg_with_debug_parameter():
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create', '--debug', '--show-rc') + ARCHIVE_WITH_PATHS,
|
('borg', 'create', '--debug', '--show-rc') + ARCHIVE_WITH_PATHS,
|
||||||
output_log_level=logging.INFO,
|
output_log_level=logging.INFO,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
insert_logging_mock(logging.DEBUG)
|
insert_logging_mock(logging.DEBUG)
|
||||||
|
|
||||||
|
@ -548,14 +500,12 @@ def test_create_archive_with_log_debug_and_json_suppresses_most_borg_output():
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create', '--json') + ARCHIVE_WITH_PATHS,
|
('borg', 'create', '--json') + ARCHIVE_WITH_PATHS,
|
||||||
output_log_level=None,
|
output_log_level=None,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
insert_logging_mock(logging.DEBUG)
|
insert_logging_mock(logging.DEBUG)
|
||||||
|
|
||||||
|
@ -585,14 +535,12 @@ def test_create_archive_with_dry_run_calls_borg_with_dry_run_parameter():
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create', '--dry-run') + ARCHIVE_WITH_PATHS,
|
('borg', 'create', '--dry-run') + ARCHIVE_WITH_PATHS,
|
||||||
output_log_level=logging.INFO,
|
output_log_level=logging.INFO,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.create_archive(
|
module.create_archive(
|
||||||
|
@ -622,14 +570,12 @@ def test_create_archive_with_stats_and_dry_run_calls_borg_without_stats_paramete
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create', '--info', '--dry-run') + ARCHIVE_WITH_PATHS,
|
('borg', 'create', '--info', '--dry-run') + ARCHIVE_WITH_PATHS,
|
||||||
output_log_level=logging.INFO,
|
output_log_level=logging.INFO,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
insert_logging_mock(logging.INFO)
|
insert_logging_mock(logging.INFO)
|
||||||
|
|
||||||
|
@ -659,14 +605,12 @@ def test_create_archive_with_checkpoint_interval_calls_borg_with_checkpoint_inte
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create', '--checkpoint-interval', '600') + ARCHIVE_WITH_PATHS,
|
('borg', 'create', '--checkpoint-interval', '600') + ARCHIVE_WITH_PATHS,
|
||||||
output_log_level=logging.INFO,
|
output_log_level=logging.INFO,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.create_archive(
|
module.create_archive(
|
||||||
|
@ -694,14 +638,12 @@ def test_create_archive_with_chunker_params_calls_borg_with_chunker_params_param
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create', '--chunker-params', '1,2,3,4') + ARCHIVE_WITH_PATHS,
|
('borg', 'create', '--chunker-params', '1,2,3,4') + ARCHIVE_WITH_PATHS,
|
||||||
output_log_level=logging.INFO,
|
output_log_level=logging.INFO,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.create_archive(
|
module.create_archive(
|
||||||
|
@ -729,14 +671,12 @@ def test_create_archive_with_compression_calls_borg_with_compression_parameters(
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create', '--compression', 'rle') + ARCHIVE_WITH_PATHS,
|
('borg', 'create', '--compression', 'rle') + ARCHIVE_WITH_PATHS,
|
||||||
output_log_level=logging.INFO,
|
output_log_level=logging.INFO,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.create_archive(
|
module.create_archive(
|
||||||
|
@ -769,14 +709,12 @@ def test_create_archive_with_remote_rate_limit_calls_borg_with_upload_ratelimit_
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create', option_flag, '100') + ARCHIVE_WITH_PATHS,
|
('borg', 'create', option_flag, '100') + ARCHIVE_WITH_PATHS,
|
||||||
output_log_level=logging.INFO,
|
output_log_level=logging.INFO,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.create_archive(
|
module.create_archive(
|
||||||
|
@ -806,14 +744,12 @@ def test_create_archive_with_working_directory_calls_borg_with_working_directory
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create') + ARCHIVE_WITH_PATHS,
|
('borg', 'create') + ARCHIVE_WITH_PATHS,
|
||||||
output_log_level=logging.INFO,
|
output_log_level=logging.INFO,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory='/working/dir',
|
working_directory='/working/dir',
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.create_archive(
|
module.create_archive(
|
||||||
|
@ -842,14 +778,12 @@ def test_create_archive_with_one_file_system_calls_borg_with_one_file_system_par
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create', '--one-file-system') + ARCHIVE_WITH_PATHS,
|
('borg', 'create', '--one-file-system') + ARCHIVE_WITH_PATHS,
|
||||||
output_log_level=logging.INFO,
|
output_log_level=logging.INFO,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.create_archive(
|
module.create_archive(
|
||||||
|
@ -883,14 +817,12 @@ def test_create_archive_with_numeric_owner_calls_borg_with_numeric_ids_parameter
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create', option_flag) + ARCHIVE_WITH_PATHS,
|
('borg', 'create', option_flag) + ARCHIVE_WITH_PATHS,
|
||||||
output_log_level=logging.INFO,
|
output_log_level=logging.INFO,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.create_archive(
|
module.create_archive(
|
||||||
|
@ -919,14 +851,12 @@ def test_create_archive_with_read_special_calls_borg_with_read_special_parameter
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create', '--read-special') + ARCHIVE_WITH_PATHS,
|
('borg', 'create', '--read-special') + ARCHIVE_WITH_PATHS,
|
||||||
output_log_level=logging.INFO,
|
output_log_level=logging.INFO,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.create_archive(
|
module.create_archive(
|
||||||
|
@ -962,14 +892,12 @@ def test_create_archive_with_basic_option_calls_borg_with_corresponding_paramete
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create') + ((option_flag,) if option_flag else ()) + ARCHIVE_WITH_PATHS,
|
('borg', 'create') + ((option_flag,) if option_flag else ()) + ARCHIVE_WITH_PATHS,
|
||||||
output_log_level=logging.INFO,
|
output_log_level=logging.INFO,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.create_archive(
|
module.create_archive(
|
||||||
|
@ -1009,14 +937,12 @@ def test_create_archive_with_atime_option_calls_borg_with_corresponding_paramete
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create') + ((option_flag,) if option_flag else ()) + ARCHIVE_WITH_PATHS,
|
('borg', 'create') + ((option_flag,) if option_flag else ()) + ARCHIVE_WITH_PATHS,
|
||||||
output_log_level=logging.INFO,
|
output_log_level=logging.INFO,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.create_archive(
|
module.create_archive(
|
||||||
|
@ -1056,14 +982,12 @@ def test_create_archive_with_bsd_flags_option_calls_borg_with_corresponding_para
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create') + ((option_flag,) if option_flag else ()) + ARCHIVE_WITH_PATHS,
|
('borg', 'create') + ((option_flag,) if option_flag else ()) + ARCHIVE_WITH_PATHS,
|
||||||
output_log_level=logging.INFO,
|
output_log_level=logging.INFO,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.create_archive(
|
module.create_archive(
|
||||||
|
@ -1092,14 +1016,12 @@ def test_create_archive_with_files_cache_calls_borg_with_files_cache_parameters(
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create', '--files-cache', 'ctime,size') + ARCHIVE_WITH_PATHS,
|
('borg', 'create', '--files-cache', 'ctime,size') + ARCHIVE_WITH_PATHS,
|
||||||
output_log_level=logging.INFO,
|
output_log_level=logging.INFO,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.create_archive(
|
module.create_archive(
|
||||||
|
@ -1128,14 +1050,12 @@ def test_create_archive_with_local_path_calls_borg_via_local_path():
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg1', 'create') + ARCHIVE_WITH_PATHS,
|
('borg1', 'create') + ARCHIVE_WITH_PATHS,
|
||||||
output_log_level=logging.INFO,
|
output_log_level=logging.INFO,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg1',
|
borg_local_path='borg1',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.create_archive(
|
module.create_archive(
|
||||||
|
@ -1164,14 +1084,12 @@ def test_create_archive_with_remote_path_calls_borg_with_remote_path_parameters(
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create', '--remote-path', 'borg1') + ARCHIVE_WITH_PATHS,
|
('borg', 'create', '--remote-path', 'borg1') + ARCHIVE_WITH_PATHS,
|
||||||
output_log_level=logging.INFO,
|
output_log_level=logging.INFO,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.create_archive(
|
module.create_archive(
|
||||||
|
@ -1200,14 +1118,12 @@ def test_create_archive_with_umask_calls_borg_with_umask_parameters():
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create', '--umask', '740') + ARCHIVE_WITH_PATHS,
|
('borg', 'create', '--umask', '740') + ARCHIVE_WITH_PATHS,
|
||||||
output_log_level=logging.INFO,
|
output_log_level=logging.INFO,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.create_archive(
|
module.create_archive(
|
||||||
|
@ -1235,14 +1151,12 @@ def test_create_archive_with_lock_wait_calls_borg_with_lock_wait_parameters():
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create', '--lock-wait', '5') + ARCHIVE_WITH_PATHS,
|
('borg', 'create', '--lock-wait', '5') + ARCHIVE_WITH_PATHS,
|
||||||
output_log_level=logging.INFO,
|
output_log_level=logging.INFO,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.create_archive(
|
module.create_archive(
|
||||||
|
@ -1270,14 +1184,12 @@ def test_create_archive_with_stats_calls_borg_with_stats_parameter_and_warning_o
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create', '--stats') + ARCHIVE_WITH_PATHS,
|
('borg', 'create', '--stats') + ARCHIVE_WITH_PATHS,
|
||||||
output_log_level=logging.WARNING,
|
output_log_level=logging.WARNING,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.create_archive(
|
module.create_archive(
|
||||||
|
@ -1306,14 +1218,12 @@ def test_create_archive_with_stats_and_log_info_calls_borg_with_stats_parameter_
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create', '--info', '--stats') + ARCHIVE_WITH_PATHS,
|
('borg', 'create', '--info', '--stats') + ARCHIVE_WITH_PATHS,
|
||||||
output_log_level=logging.INFO,
|
output_log_level=logging.INFO,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
insert_logging_mock(logging.INFO)
|
insert_logging_mock(logging.INFO)
|
||||||
|
|
||||||
|
@ -1343,14 +1253,12 @@ def test_create_archive_with_files_calls_borg_with_list_parameter_and_warning_ou
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create', '--list', '--filter', 'AME-') + ARCHIVE_WITH_PATHS,
|
('borg', 'create', '--list', '--filter', 'AME-') + ARCHIVE_WITH_PATHS,
|
||||||
output_log_level=logging.WARNING,
|
output_log_level=logging.WARNING,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.create_archive(
|
module.create_archive(
|
||||||
|
@ -1379,14 +1287,12 @@ def test_create_archive_with_files_and_log_info_calls_borg_with_list_parameter_a
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create', '--list', '--filter', 'AME-', '--info') + ARCHIVE_WITH_PATHS,
|
('borg', 'create', '--list', '--filter', 'AME-', '--info') + ARCHIVE_WITH_PATHS,
|
||||||
output_log_level=logging.INFO,
|
output_log_level=logging.INFO,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
insert_logging_mock(logging.INFO)
|
insert_logging_mock(logging.INFO)
|
||||||
|
|
||||||
|
@ -1416,14 +1322,12 @@ def test_create_archive_with_progress_and_log_info_calls_borg_with_progress_para
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create', '--info', '--progress') + ARCHIVE_WITH_PATHS,
|
('borg', 'create', '--info', '--progress') + ARCHIVE_WITH_PATHS,
|
||||||
output_log_level=logging.INFO,
|
output_log_level=logging.INFO,
|
||||||
output_file=module.DO_NOT_CAPTURE,
|
output_file=module.DO_NOT_CAPTURE,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
insert_logging_mock(logging.INFO)
|
insert_logging_mock(logging.INFO)
|
||||||
|
|
||||||
|
@ -1453,14 +1357,12 @@ def test_create_archive_with_progress_calls_borg_with_progress_parameter():
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create', '--progress') + ARCHIVE_WITH_PATHS,
|
('borg', 'create', '--progress') + ARCHIVE_WITH_PATHS,
|
||||||
output_log_level=logging.INFO,
|
output_log_level=logging.INFO,
|
||||||
output_file=module.DO_NOT_CAPTURE,
|
output_file=module.DO_NOT_CAPTURE,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.create_archive(
|
module.create_archive(
|
||||||
|
@ -1490,7 +1392,6 @@ def test_create_archive_with_progress_and_stream_processes_calls_borg_with_progr
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
||||||
('borg', 'create', '--one-file-system', '--read-special', '--progress')
|
('borg', 'create', '--one-file-system', '--read-special', '--progress')
|
||||||
+ ARCHIVE_WITH_PATHS,
|
+ ARCHIVE_WITH_PATHS,
|
||||||
|
@ -1499,7 +1400,6 @@ def test_create_archive_with_progress_and_stream_processes_calls_borg_with_progr
|
||||||
output_file=module.DO_NOT_CAPTURE,
|
output_file=module.DO_NOT_CAPTURE,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.create_archive(
|
module.create_archive(
|
||||||
|
@ -1529,14 +1429,12 @@ def test_create_archive_with_json_calls_borg_with_json_parameter():
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create', '--json') + ARCHIVE_WITH_PATHS,
|
('borg', 'create', '--json') + ARCHIVE_WITH_PATHS,
|
||||||
output_log_level=None,
|
output_log_level=None,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
).and_return('[]')
|
).and_return('[]')
|
||||||
|
|
||||||
json_output = module.create_archive(
|
json_output = module.create_archive(
|
||||||
|
@ -1567,14 +1465,12 @@ def test_create_archive_with_stats_and_json_calls_borg_without_stats_parameter()
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create', '--json') + ARCHIVE_WITH_PATHS,
|
('borg', 'create', '--json') + ARCHIVE_WITH_PATHS,
|
||||||
output_log_level=None,
|
output_log_level=None,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
).and_return('[]')
|
).and_return('[]')
|
||||||
|
|
||||||
json_output = module.create_archive(
|
json_output = module.create_archive(
|
||||||
|
@ -1606,14 +1502,12 @@ def test_create_archive_with_source_directories_glob_expands():
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create', 'repo::{}'.format(DEFAULT_ARCHIVE_NAME), 'foo', 'food'),
|
('borg', 'create', 'repo::{}'.format(DEFAULT_ARCHIVE_NAME), 'foo', 'food'),
|
||||||
output_log_level=logging.INFO,
|
output_log_level=logging.INFO,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
flexmock(module.glob).should_receive('glob').with_args('foo*').and_return(['foo', 'food'])
|
flexmock(module.glob).should_receive('glob').with_args('foo*').and_return(['foo', 'food'])
|
||||||
|
|
||||||
|
@ -1642,14 +1536,12 @@ def test_create_archive_with_non_matching_source_directories_glob_passes_through
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create', 'repo::{}'.format(DEFAULT_ARCHIVE_NAME), 'foo*'),
|
('borg', 'create', 'repo::{}'.format(DEFAULT_ARCHIVE_NAME), 'foo*'),
|
||||||
output_log_level=logging.INFO,
|
output_log_level=logging.INFO,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
flexmock(module.glob).should_receive('glob').with_args('foo*').and_return([])
|
flexmock(module.glob).should_receive('glob').with_args('foo*').and_return([])
|
||||||
|
|
||||||
|
@ -1678,14 +1570,12 @@ def test_create_archive_with_glob_calls_borg_with_expanded_directories():
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create', 'repo::{}'.format(DEFAULT_ARCHIVE_NAME), 'foo', 'food'),
|
('borg', 'create', 'repo::{}'.format(DEFAULT_ARCHIVE_NAME), 'foo', 'food'),
|
||||||
output_log_level=logging.INFO,
|
output_log_level=logging.INFO,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.create_archive(
|
module.create_archive(
|
||||||
|
@ -1713,14 +1603,12 @@ def test_create_archive_with_archive_name_format_calls_borg_with_archive_name():
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create', 'repo::ARCHIVE_NAME', 'foo', 'bar'),
|
('borg', 'create', 'repo::ARCHIVE_NAME', 'foo', 'bar'),
|
||||||
output_log_level=logging.INFO,
|
output_log_level=logging.INFO,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.create_archive(
|
module.create_archive(
|
||||||
|
@ -1748,14 +1636,12 @@ def test_create_archive_with_archive_name_format_accepts_borg_placeholders():
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create', 'repo::Documents_{hostname}-{now}', 'foo', 'bar'),
|
('borg', 'create', 'repo::Documents_{hostname}-{now}', 'foo', 'bar'),
|
||||||
output_log_level=logging.INFO,
|
output_log_level=logging.INFO,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.create_archive(
|
module.create_archive(
|
||||||
|
@ -1783,14 +1669,12 @@ def test_create_archive_with_repository_accepts_borg_placeholders():
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create', '{fqdn}::Documents_{hostname}-{now}', 'foo', 'bar'),
|
('borg', 'create', '{fqdn}::Documents_{hostname}-{now}', 'foo', 'bar'),
|
||||||
output_log_level=logging.INFO,
|
output_log_level=logging.INFO,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.create_archive(
|
module.create_archive(
|
||||||
|
@ -1818,14 +1702,12 @@ def test_create_archive_with_extra_borg_options_calls_borg_with_extra_options():
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'create', '--extra', '--options') + ARCHIVE_WITH_PATHS,
|
('borg', 'create', '--extra', '--options') + ARCHIVE_WITH_PATHS,
|
||||||
output_log_level=logging.INFO,
|
output_log_level=logging.INFO,
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.create_archive(
|
module.create_archive(
|
||||||
|
@ -1854,7 +1736,6 @@ def test_create_archive_with_stream_processes_calls_borg_with_processes():
|
||||||
flexmock(module).should_receive('ensure_files_readable')
|
flexmock(module).should_receive('ensure_files_readable')
|
||||||
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
flexmock(module).should_receive('make_pattern_flags').and_return(())
|
||||||
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
flexmock(module).should_receive('make_exclude_flags').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
flexmock(module).should_receive('execute_command_with_processes').with_args(
|
||||||
('borg', 'create', '--one-file-system', '--read-special') + ARCHIVE_WITH_PATHS,
|
('borg', 'create', '--one-file-system', '--read-special') + ARCHIVE_WITH_PATHS,
|
||||||
processes=processes,
|
processes=processes,
|
||||||
|
@ -1862,7 +1743,6 @@ def test_create_archive_with_stream_processes_calls_borg_with_processes():
|
||||||
output_file=None,
|
output_file=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.create_archive(
|
module.create_archive(
|
||||||
|
|
|
@ -1,34 +1,84 @@
|
||||||
|
import os
|
||||||
|
|
||||||
from borgmatic.borg import environment as module
|
from borgmatic.borg import environment as module
|
||||||
|
|
||||||
|
|
||||||
def test_make_environment_with_passcommand_should_set_environment():
|
def test_initialize_with_passcommand_should_set_environment():
|
||||||
environment = module.make_environment({'encryption_passcommand': 'command'})
|
orig_environ = os.environ
|
||||||
|
|
||||||
assert environment.get('BORG_PASSCOMMAND') == 'command'
|
try:
|
||||||
|
os.environ = {}
|
||||||
|
module.initialize({'encryption_passcommand': 'command'})
|
||||||
|
assert os.environ.get('BORG_PASSCOMMAND') == 'command'
|
||||||
|
finally:
|
||||||
|
os.environ = orig_environ
|
||||||
|
|
||||||
|
|
||||||
def test_make_environment_with_passphrase_should_set_environment():
|
def test_initialize_with_passphrase_should_set_environment():
|
||||||
environment = module.make_environment({'encryption_passphrase': 'pass'})
|
orig_environ = os.environ
|
||||||
|
|
||||||
assert environment.get('BORG_PASSPHRASE') == 'pass'
|
try:
|
||||||
|
os.environ = {}
|
||||||
|
module.initialize({'encryption_passphrase': 'pass'})
|
||||||
|
assert os.environ.get('BORG_PASSPHRASE') == 'pass'
|
||||||
|
finally:
|
||||||
|
os.environ = orig_environ
|
||||||
|
|
||||||
|
|
||||||
def test_make_environment_with_ssh_command_should_set_environment():
|
def test_initialize_with_ssh_command_should_set_environment():
|
||||||
environment = module.make_environment({'ssh_command': 'ssh -C'})
|
orig_environ = os.environ
|
||||||
|
|
||||||
assert environment.get('BORG_RSH') == 'ssh -C'
|
try:
|
||||||
|
os.environ = {}
|
||||||
|
module.initialize({'ssh_command': 'ssh -C'})
|
||||||
|
assert os.environ.get('BORG_RSH') == 'ssh -C'
|
||||||
|
finally:
|
||||||
|
os.environ = orig_environ
|
||||||
|
|
||||||
|
|
||||||
def test_make_environment_without_configuration_should_only_set_default_environment():
|
def test_initialize_without_configuration_should_only_set_default_environment():
|
||||||
environment = module.make_environment({})
|
orig_environ = os.environ
|
||||||
|
|
||||||
assert environment == {
|
try:
|
||||||
'BORG_RELOCATED_REPO_ACCESS_IS_OK': 'no',
|
os.environ = {}
|
||||||
'BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK': 'no',
|
module.initialize({})
|
||||||
}
|
|
||||||
|
assert {key: value for key, value in os.environ.items() if key.startswith('BORG_')} == {
|
||||||
|
'BORG_RELOCATED_REPO_ACCESS_IS_OK': 'no',
|
||||||
|
'BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK': 'no',
|
||||||
|
}
|
||||||
|
finally:
|
||||||
|
os.environ = orig_environ
|
||||||
|
|
||||||
|
|
||||||
def test_make_environment_with_relocated_repo_access_should_override_default():
|
def test_initialize_with_relocated_repo_access_should_override_default():
|
||||||
environment = module.make_environment({'relocated_repo_access_is_ok': True})
|
orig_environ = os.environ
|
||||||
|
|
||||||
assert environment.get('BORG_RELOCATED_REPO_ACCESS_IS_OK') == 'yes'
|
try:
|
||||||
|
os.environ = {}
|
||||||
|
module.initialize({'relocated_repo_access_is_ok': True})
|
||||||
|
assert os.environ.get('BORG_RELOCATED_REPO_ACCESS_IS_OK') == 'yes'
|
||||||
|
finally:
|
||||||
|
os.environ = orig_environ
|
||||||
|
|
||||||
|
|
||||||
|
def test_initialize_prefers_configuration_option_over_borg_environment_variable():
|
||||||
|
orig_environ = os.environ
|
||||||
|
|
||||||
|
try:
|
||||||
|
os.environ = {'BORG_SSH': 'mosh'}
|
||||||
|
module.initialize({'ssh_command': 'ssh -C'})
|
||||||
|
assert os.environ.get('BORG_RSH') == 'ssh -C'
|
||||||
|
finally:
|
||||||
|
os.environ = orig_environ
|
||||||
|
|
||||||
|
|
||||||
|
def test_initialize_passes_through_existing_borg_environment_variable():
|
||||||
|
orig_environ = os.environ
|
||||||
|
|
||||||
|
try:
|
||||||
|
os.environ = {'BORG_PASSPHRASE': 'pass'}
|
||||||
|
module.initialize({'ssh_command': 'ssh -C'})
|
||||||
|
assert os.environ.get('BORG_PASSPHRASE') == 'pass'
|
||||||
|
finally:
|
||||||
|
os.environ = orig_environ
|
||||||
|
|
|
@ -10,13 +10,11 @@ from ..test_verbosity import insert_logging_mock
|
||||||
def insert_execute_command_mock(
|
def insert_execute_command_mock(
|
||||||
command, output_log_level=logging.INFO, borg_local_path='borg', capture=True
|
command, output_log_level=logging.INFO, borg_local_path='borg', capture=True
|
||||||
):
|
):
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
command,
|
command,
|
||||||
output_file=None if capture else module.DO_NOT_CAPTURE,
|
output_file=None if capture else module.DO_NOT_CAPTURE,
|
||||||
output_log_level=output_log_level,
|
output_log_level=output_log_level,
|
||||||
borg_local_path=borg_local_path,
|
borg_local_path=borg_local_path,
|
||||||
extra_environment=None,
|
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,16 +9,14 @@ from ..test_verbosity import insert_logging_mock
|
||||||
|
|
||||||
|
|
||||||
def insert_execute_command_mock(command, working_directory=None):
|
def insert_execute_command_mock(command, working_directory=None):
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
command, working_directory=working_directory, extra_environment=None,
|
command, working_directory=working_directory
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
|
|
||||||
def insert_execute_command_output_mock(command, result):
|
def insert_execute_command_output_mock(command, result):
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
command, output_log_level=None, borg_local_path=command[0], extra_environment=None,
|
command, output_log_level=None, borg_local_path=command[0]
|
||||||
).and_return(result).once()
|
).and_return(result).once()
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,14 +27,14 @@ def test_extract_last_archive_dry_run_calls_borg_with_last_archive():
|
||||||
insert_execute_command_mock(('borg', 'extract', '--dry-run', 'repo::archive2'))
|
insert_execute_command_mock(('borg', 'extract', '--dry-run', 'repo::archive2'))
|
||||||
flexmock(module.feature).should_receive('available').and_return(True)
|
flexmock(module.feature).should_receive('available').and_return(True)
|
||||||
|
|
||||||
module.extract_last_archive_dry_run(storage_config={}, repository='repo', lock_wait=None)
|
module.extract_last_archive_dry_run(repository='repo', lock_wait=None)
|
||||||
|
|
||||||
|
|
||||||
def test_extract_last_archive_dry_run_without_any_archives_should_not_raise():
|
def test_extract_last_archive_dry_run_without_any_archives_should_not_raise():
|
||||||
insert_execute_command_output_mock(('borg', 'list', '--short', 'repo'), result='\n')
|
insert_execute_command_output_mock(('borg', 'list', '--short', 'repo'), result='\n')
|
||||||
flexmock(module.feature).should_receive('available').and_return(True)
|
flexmock(module.feature).should_receive('available').and_return(True)
|
||||||
|
|
||||||
module.extract_last_archive_dry_run(storage_config={}, repository='repo', lock_wait=None)
|
module.extract_last_archive_dry_run(repository='repo', lock_wait=None)
|
||||||
|
|
||||||
|
|
||||||
def test_extract_last_archive_dry_run_with_log_info_calls_borg_with_info_parameter():
|
def test_extract_last_archive_dry_run_with_log_info_calls_borg_with_info_parameter():
|
||||||
|
@ -47,7 +45,7 @@ def test_extract_last_archive_dry_run_with_log_info_calls_borg_with_info_paramet
|
||||||
insert_logging_mock(logging.INFO)
|
insert_logging_mock(logging.INFO)
|
||||||
flexmock(module.feature).should_receive('available').and_return(True)
|
flexmock(module.feature).should_receive('available').and_return(True)
|
||||||
|
|
||||||
module.extract_last_archive_dry_run(storage_config={}, repository='repo', lock_wait=None)
|
module.extract_last_archive_dry_run(repository='repo', lock_wait=None)
|
||||||
|
|
||||||
|
|
||||||
def test_extract_last_archive_dry_run_with_log_debug_calls_borg_with_debug_parameter():
|
def test_extract_last_archive_dry_run_with_log_debug_calls_borg_with_debug_parameter():
|
||||||
|
@ -60,7 +58,7 @@ def test_extract_last_archive_dry_run_with_log_debug_calls_borg_with_debug_param
|
||||||
insert_logging_mock(logging.DEBUG)
|
insert_logging_mock(logging.DEBUG)
|
||||||
flexmock(module.feature).should_receive('available').and_return(True)
|
flexmock(module.feature).should_receive('available').and_return(True)
|
||||||
|
|
||||||
module.extract_last_archive_dry_run(storage_config={}, repository='repo', lock_wait=None)
|
module.extract_last_archive_dry_run(repository='repo', lock_wait=None)
|
||||||
|
|
||||||
|
|
||||||
def test_extract_last_archive_dry_run_calls_borg_via_local_path():
|
def test_extract_last_archive_dry_run_calls_borg_via_local_path():
|
||||||
|
@ -70,9 +68,7 @@ def test_extract_last_archive_dry_run_calls_borg_via_local_path():
|
||||||
insert_execute_command_mock(('borg1', 'extract', '--dry-run', 'repo::archive2'))
|
insert_execute_command_mock(('borg1', 'extract', '--dry-run', 'repo::archive2'))
|
||||||
flexmock(module.feature).should_receive('available').and_return(True)
|
flexmock(module.feature).should_receive('available').and_return(True)
|
||||||
|
|
||||||
module.extract_last_archive_dry_run(
|
module.extract_last_archive_dry_run(repository='repo', lock_wait=None, local_path='borg1')
|
||||||
storage_config={}, repository='repo', lock_wait=None, local_path='borg1'
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_extract_last_archive_dry_run_calls_borg_with_remote_path_parameters():
|
def test_extract_last_archive_dry_run_calls_borg_with_remote_path_parameters():
|
||||||
|
@ -84,9 +80,7 @@ def test_extract_last_archive_dry_run_calls_borg_with_remote_path_parameters():
|
||||||
)
|
)
|
||||||
flexmock(module.feature).should_receive('available').and_return(True)
|
flexmock(module.feature).should_receive('available').and_return(True)
|
||||||
|
|
||||||
module.extract_last_archive_dry_run(
|
module.extract_last_archive_dry_run(repository='repo', lock_wait=None, remote_path='borg1')
|
||||||
storage_config={}, repository='repo', lock_wait=None, remote_path='borg1'
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_extract_last_archive_dry_run_calls_borg_with_lock_wait_parameters():
|
def test_extract_last_archive_dry_run_calls_borg_with_lock_wait_parameters():
|
||||||
|
@ -98,7 +92,7 @@ def test_extract_last_archive_dry_run_calls_borg_with_lock_wait_parameters():
|
||||||
)
|
)
|
||||||
flexmock(module.feature).should_receive('available').and_return(True)
|
flexmock(module.feature).should_receive('available').and_return(True)
|
||||||
|
|
||||||
module.extract_last_archive_dry_run(storage_config={}, repository='repo', lock_wait=5)
|
module.extract_last_archive_dry_run(repository='repo', lock_wait=5)
|
||||||
|
|
||||||
|
|
||||||
def test_extract_archive_calls_borg_with_path_parameters():
|
def test_extract_archive_calls_borg_with_path_parameters():
|
||||||
|
@ -273,12 +267,10 @@ def test_extract_archive_calls_borg_with_strip_components():
|
||||||
|
|
||||||
def test_extract_archive_calls_borg_with_progress_parameter():
|
def test_extract_archive_calls_borg_with_progress_parameter():
|
||||||
flexmock(module.os.path).should_receive('abspath').and_return('repo')
|
flexmock(module.os.path).should_receive('abspath').and_return('repo')
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'extract', '--progress', 'repo::archive'),
|
('borg', 'extract', '--progress', 'repo::archive'),
|
||||||
output_file=module.DO_NOT_CAPTURE,
|
output_file=module.DO_NOT_CAPTURE,
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
extra_environment=None,
|
|
||||||
).once()
|
).once()
|
||||||
flexmock(module.feature).should_receive('available').and_return(True)
|
flexmock(module.feature).should_receive('available').and_return(True)
|
||||||
|
|
||||||
|
@ -314,13 +306,11 @@ def test_extract_archive_with_progress_and_extract_to_stdout_raises():
|
||||||
def test_extract_archive_calls_borg_with_stdout_parameter_and_returns_process():
|
def test_extract_archive_calls_borg_with_stdout_parameter_and_returns_process():
|
||||||
flexmock(module.os.path).should_receive('abspath').and_return('repo')
|
flexmock(module.os.path).should_receive('abspath').and_return('repo')
|
||||||
process = flexmock()
|
process = flexmock()
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'extract', '--stdout', 'repo::archive'),
|
('borg', 'extract', '--stdout', 'repo::archive'),
|
||||||
output_file=module.subprocess.PIPE,
|
output_file=module.subprocess.PIPE,
|
||||||
working_directory=None,
|
working_directory=None,
|
||||||
run_to_completion=False,
|
run_to_completion=False,
|
||||||
extra_environment=None,
|
|
||||||
).and_return(process).once()
|
).and_return(process).once()
|
||||||
flexmock(module.feature).should_receive('available').and_return(True)
|
flexmock(module.feature).should_receive('available').and_return(True)
|
||||||
|
|
||||||
|
@ -341,9 +331,8 @@ def test_extract_archive_calls_borg_with_stdout_parameter_and_returns_process():
|
||||||
|
|
||||||
def test_extract_archive_skips_abspath_for_remote_repository():
|
def test_extract_archive_skips_abspath_for_remote_repository():
|
||||||
flexmock(module.os.path).should_receive('abspath').never()
|
flexmock(module.os.path).should_receive('abspath').never()
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'extract', 'server:repo::archive'), working_directory=None, extra_environment=None,
|
('borg', 'extract', 'server:repo::archive'), working_directory=None
|
||||||
).once()
|
).once()
|
||||||
flexmock(module.feature).should_receive('available').and_return(True)
|
flexmock(module.feature).should_receive('available').and_return(True)
|
||||||
|
|
||||||
|
|
|
@ -9,12 +9,8 @@ from ..test_verbosity import insert_logging_mock
|
||||||
|
|
||||||
|
|
||||||
def test_display_archives_info_calls_borg_with_parameters():
|
def test_display_archives_info_calls_borg_with_parameters():
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'info', 'repo'),
|
('borg', 'info', 'repo'), output_log_level=logging.WARNING, borg_local_path='borg'
|
||||||
output_log_level=logging.WARNING,
|
|
||||||
borg_local_path='borg',
|
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.display_archives_info(
|
module.display_archives_info(
|
||||||
|
@ -23,12 +19,8 @@ def test_display_archives_info_calls_borg_with_parameters():
|
||||||
|
|
||||||
|
|
||||||
def test_display_archives_info_with_log_info_calls_borg_with_info_parameter():
|
def test_display_archives_info_with_log_info_calls_borg_with_info_parameter():
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'info', '--info', 'repo'),
|
('borg', 'info', '--info', 'repo'), output_log_level=logging.WARNING, borg_local_path='borg'
|
||||||
output_log_level=logging.WARNING,
|
|
||||||
borg_local_path='borg',
|
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
insert_logging_mock(logging.INFO)
|
insert_logging_mock(logging.INFO)
|
||||||
module.display_archives_info(
|
module.display_archives_info(
|
||||||
|
@ -37,12 +29,8 @@ def test_display_archives_info_with_log_info_calls_borg_with_info_parameter():
|
||||||
|
|
||||||
|
|
||||||
def test_display_archives_info_with_log_info_and_json_suppresses_most_borg_output():
|
def test_display_archives_info_with_log_info_and_json_suppresses_most_borg_output():
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'info', '--json', 'repo'),
|
('borg', 'info', '--json', 'repo'), output_log_level=None, borg_local_path='borg'
|
||||||
output_log_level=None,
|
|
||||||
borg_local_path='borg',
|
|
||||||
extra_environment=None,
|
|
||||||
).and_return('[]')
|
).and_return('[]')
|
||||||
|
|
||||||
insert_logging_mock(logging.INFO)
|
insert_logging_mock(logging.INFO)
|
||||||
|
@ -54,12 +42,10 @@ def test_display_archives_info_with_log_info_and_json_suppresses_most_borg_outpu
|
||||||
|
|
||||||
|
|
||||||
def test_display_archives_info_with_log_debug_calls_borg_with_debug_parameter():
|
def test_display_archives_info_with_log_debug_calls_borg_with_debug_parameter():
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'info', '--debug', '--show-rc', 'repo'),
|
('borg', 'info', '--debug', '--show-rc', 'repo'),
|
||||||
output_log_level=logging.WARNING,
|
output_log_level=logging.WARNING,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
insert_logging_mock(logging.DEBUG)
|
insert_logging_mock(logging.DEBUG)
|
||||||
|
|
||||||
|
@ -69,12 +55,8 @@ def test_display_archives_info_with_log_debug_calls_borg_with_debug_parameter():
|
||||||
|
|
||||||
|
|
||||||
def test_display_archives_info_with_log_debug_and_json_suppresses_most_borg_output():
|
def test_display_archives_info_with_log_debug_and_json_suppresses_most_borg_output():
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'info', '--json', 'repo'),
|
('borg', 'info', '--json', 'repo'), output_log_level=None, borg_local_path='borg'
|
||||||
output_log_level=None,
|
|
||||||
borg_local_path='borg',
|
|
||||||
extra_environment=None,
|
|
||||||
).and_return('[]')
|
).and_return('[]')
|
||||||
|
|
||||||
insert_logging_mock(logging.DEBUG)
|
insert_logging_mock(logging.DEBUG)
|
||||||
|
@ -86,12 +68,8 @@ def test_display_archives_info_with_log_debug_and_json_suppresses_most_borg_outp
|
||||||
|
|
||||||
|
|
||||||
def test_display_archives_info_with_json_calls_borg_with_json_parameter():
|
def test_display_archives_info_with_json_calls_borg_with_json_parameter():
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'info', '--json', 'repo'),
|
('borg', 'info', '--json', 'repo'), output_log_level=None, borg_local_path='borg'
|
||||||
output_log_level=None,
|
|
||||||
borg_local_path='borg',
|
|
||||||
extra_environment=None,
|
|
||||||
).and_return('[]')
|
).and_return('[]')
|
||||||
|
|
||||||
json_output = module.display_archives_info(
|
json_output = module.display_archives_info(
|
||||||
|
@ -102,12 +80,8 @@ def test_display_archives_info_with_json_calls_borg_with_json_parameter():
|
||||||
|
|
||||||
|
|
||||||
def test_display_archives_info_with_archive_calls_borg_with_archive_parameter():
|
def test_display_archives_info_with_archive_calls_borg_with_archive_parameter():
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'info', 'repo::archive'),
|
('borg', 'info', 'repo::archive'), output_log_level=logging.WARNING, borg_local_path='borg'
|
||||||
output_log_level=logging.WARNING,
|
|
||||||
borg_local_path='borg',
|
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.display_archives_info(
|
module.display_archives_info(
|
||||||
|
@ -116,12 +90,8 @@ def test_display_archives_info_with_archive_calls_borg_with_archive_parameter():
|
||||||
|
|
||||||
|
|
||||||
def test_display_archives_info_with_local_path_calls_borg_via_local_path():
|
def test_display_archives_info_with_local_path_calls_borg_via_local_path():
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg1', 'info', 'repo'),
|
('borg1', 'info', 'repo'), output_log_level=logging.WARNING, borg_local_path='borg1'
|
||||||
output_log_level=logging.WARNING,
|
|
||||||
borg_local_path='borg1',
|
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.display_archives_info(
|
module.display_archives_info(
|
||||||
|
@ -133,12 +103,10 @@ def test_display_archives_info_with_local_path_calls_borg_via_local_path():
|
||||||
|
|
||||||
|
|
||||||
def test_display_archives_info_with_remote_path_calls_borg_with_remote_path_parameters():
|
def test_display_archives_info_with_remote_path_calls_borg_with_remote_path_parameters():
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'info', '--remote-path', 'borg1', 'repo'),
|
('borg', 'info', '--remote-path', 'borg1', 'repo'),
|
||||||
output_log_level=logging.WARNING,
|
output_log_level=logging.WARNING,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.display_archives_info(
|
module.display_archives_info(
|
||||||
|
@ -151,12 +119,10 @@ def test_display_archives_info_with_remote_path_calls_borg_with_remote_path_para
|
||||||
|
|
||||||
def test_display_archives_info_with_lock_wait_calls_borg_with_lock_wait_parameters():
|
def test_display_archives_info_with_lock_wait_calls_borg_with_lock_wait_parameters():
|
||||||
storage_config = {'lock_wait': 5}
|
storage_config = {'lock_wait': 5}
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'info', '--lock-wait', '5', 'repo'),
|
('borg', 'info', '--lock-wait', '5', 'repo'),
|
||||||
output_log_level=logging.WARNING,
|
output_log_level=logging.WARNING,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.display_archives_info(
|
module.display_archives_info(
|
||||||
|
@ -168,12 +134,10 @@ def test_display_archives_info_with_lock_wait_calls_borg_with_lock_wait_paramete
|
||||||
|
|
||||||
@pytest.mark.parametrize('argument_name', ('prefix', 'glob_archives', 'sort_by', 'first', 'last'))
|
@pytest.mark.parametrize('argument_name', ('prefix', 'glob_archives', 'sort_by', 'first', 'last'))
|
||||||
def test_display_archives_info_passes_through_arguments_to_borg(argument_name):
|
def test_display_archives_info_passes_through_arguments_to_borg(argument_name):
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'info', '--' + argument_name.replace('_', '-'), 'value', 'repo'),
|
('borg', 'info', '--' + argument_name.replace('_', '-'), 'value', 'repo'),
|
||||||
output_log_level=logging.WARNING,
|
output_log_level=logging.WARNING,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
extra_environment=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
module.display_archives_info(
|
module.display_archives_info(
|
||||||
|
|
|
@ -23,12 +23,8 @@ def insert_info_command_not_found_mock():
|
||||||
|
|
||||||
|
|
||||||
def insert_init_command_mock(init_command, **kwargs):
|
def insert_init_command_mock(init_command, **kwargs):
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
init_command,
|
init_command, output_file=module.DO_NOT_CAPTURE, borg_local_path=init_command[0]
|
||||||
output_file=module.DO_NOT_CAPTURE,
|
|
||||||
borg_local_path=init_command[0],
|
|
||||||
extra_environment=None,
|
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
|
|
||||||
|
@ -41,7 +37,6 @@ def test_initialize_repository_calls_borg_with_parameters():
|
||||||
|
|
||||||
def test_initialize_repository_raises_for_borg_init_error():
|
def test_initialize_repository_raises_for_borg_init_error():
|
||||||
insert_info_command_not_found_mock()
|
insert_info_command_not_found_mock()
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').and_raise(
|
flexmock(module).should_receive('execute_command').and_raise(
|
||||||
module.subprocess.CalledProcessError(2, 'borg init')
|
module.subprocess.CalledProcessError(2, 'borg init')
|
||||||
)
|
)
|
||||||
|
|
|
@ -24,12 +24,8 @@ def test_resolve_archive_name_passes_through_non_latest_archive_name():
|
||||||
|
|
||||||
def test_resolve_archive_name_calls_borg_with_parameters():
|
def test_resolve_archive_name_calls_borg_with_parameters():
|
||||||
expected_archive = 'archive-name'
|
expected_archive = 'archive-name'
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'list') + BORG_LIST_LATEST_ARGUMENTS,
|
('borg', 'list') + BORG_LIST_LATEST_ARGUMENTS, output_log_level=None, borg_local_path='borg'
|
||||||
output_log_level=None,
|
|
||||||
borg_local_path='borg',
|
|
||||||
extra_environment=None,
|
|
||||||
).and_return(expected_archive + '\n')
|
).and_return(expected_archive + '\n')
|
||||||
|
|
||||||
assert module.resolve_archive_name('repo', 'latest', storage_config={}) == expected_archive
|
assert module.resolve_archive_name('repo', 'latest', storage_config={}) == expected_archive
|
||||||
|
@ -37,12 +33,10 @@ def test_resolve_archive_name_calls_borg_with_parameters():
|
||||||
|
|
||||||
def test_resolve_archive_name_with_log_info_calls_borg_with_info_parameter():
|
def test_resolve_archive_name_with_log_info_calls_borg_with_info_parameter():
|
||||||
expected_archive = 'archive-name'
|
expected_archive = 'archive-name'
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'list', '--info') + BORG_LIST_LATEST_ARGUMENTS,
|
('borg', 'list', '--info') + BORG_LIST_LATEST_ARGUMENTS,
|
||||||
output_log_level=None,
|
output_log_level=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
extra_environment=None,
|
|
||||||
).and_return(expected_archive + '\n')
|
).and_return(expected_archive + '\n')
|
||||||
insert_logging_mock(logging.INFO)
|
insert_logging_mock(logging.INFO)
|
||||||
|
|
||||||
|
@ -51,12 +45,10 @@ def test_resolve_archive_name_with_log_info_calls_borg_with_info_parameter():
|
||||||
|
|
||||||
def test_resolve_archive_name_with_log_debug_calls_borg_with_debug_parameter():
|
def test_resolve_archive_name_with_log_debug_calls_borg_with_debug_parameter():
|
||||||
expected_archive = 'archive-name'
|
expected_archive = 'archive-name'
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'list', '--debug', '--show-rc') + BORG_LIST_LATEST_ARGUMENTS,
|
('borg', 'list', '--debug', '--show-rc') + BORG_LIST_LATEST_ARGUMENTS,
|
||||||
output_log_level=None,
|
output_log_level=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
extra_environment=None,
|
|
||||||
).and_return(expected_archive + '\n')
|
).and_return(expected_archive + '\n')
|
||||||
insert_logging_mock(logging.DEBUG)
|
insert_logging_mock(logging.DEBUG)
|
||||||
|
|
||||||
|
@ -65,12 +57,10 @@ def test_resolve_archive_name_with_log_debug_calls_borg_with_debug_parameter():
|
||||||
|
|
||||||
def test_resolve_archive_name_with_local_path_calls_borg_via_local_path():
|
def test_resolve_archive_name_with_local_path_calls_borg_via_local_path():
|
||||||
expected_archive = 'archive-name'
|
expected_archive = 'archive-name'
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg1', 'list') + BORG_LIST_LATEST_ARGUMENTS,
|
('borg1', 'list') + BORG_LIST_LATEST_ARGUMENTS,
|
||||||
output_log_level=None,
|
output_log_level=None,
|
||||||
borg_local_path='borg1',
|
borg_local_path='borg1',
|
||||||
extra_environment=None,
|
|
||||||
).and_return(expected_archive + '\n')
|
).and_return(expected_archive + '\n')
|
||||||
|
|
||||||
assert (
|
assert (
|
||||||
|
@ -81,12 +71,10 @@ def test_resolve_archive_name_with_local_path_calls_borg_via_local_path():
|
||||||
|
|
||||||
def test_resolve_archive_name_with_remote_path_calls_borg_with_remote_path_parameters():
|
def test_resolve_archive_name_with_remote_path_calls_borg_with_remote_path_parameters():
|
||||||
expected_archive = 'archive-name'
|
expected_archive = 'archive-name'
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'list', '--remote-path', 'borg1') + BORG_LIST_LATEST_ARGUMENTS,
|
('borg', 'list', '--remote-path', 'borg1') + BORG_LIST_LATEST_ARGUMENTS,
|
||||||
output_log_level=None,
|
output_log_level=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
extra_environment=None,
|
|
||||||
).and_return(expected_archive + '\n')
|
).and_return(expected_archive + '\n')
|
||||||
|
|
||||||
assert (
|
assert (
|
||||||
|
@ -96,12 +84,8 @@ def test_resolve_archive_name_with_remote_path_calls_borg_with_remote_path_param
|
||||||
|
|
||||||
|
|
||||||
def test_resolve_archive_name_without_archives_raises():
|
def test_resolve_archive_name_without_archives_raises():
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'list') + BORG_LIST_LATEST_ARGUMENTS,
|
('borg', 'list') + BORG_LIST_LATEST_ARGUMENTS, output_log_level=None, borg_local_path='borg'
|
||||||
output_log_level=None,
|
|
||||||
borg_local_path='borg',
|
|
||||||
extra_environment=None,
|
|
||||||
).and_return('')
|
).and_return('')
|
||||||
|
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
|
@ -111,12 +95,10 @@ def test_resolve_archive_name_without_archives_raises():
|
||||||
def test_resolve_archive_name_with_lock_wait_calls_borg_with_lock_wait_parameters():
|
def test_resolve_archive_name_with_lock_wait_calls_borg_with_lock_wait_parameters():
|
||||||
expected_archive = 'archive-name'
|
expected_archive = 'archive-name'
|
||||||
|
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'list', '--lock-wait', 'okay') + BORG_LIST_LATEST_ARGUMENTS,
|
('borg', 'list', '--lock-wait', 'okay') + BORG_LIST_LATEST_ARGUMENTS,
|
||||||
output_log_level=None,
|
output_log_level=None,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
extra_environment=None,
|
|
||||||
).and_return(expected_archive + '\n')
|
).and_return(expected_archive + '\n')
|
||||||
|
|
||||||
assert (
|
assert (
|
||||||
|
@ -314,12 +296,8 @@ def test_list_archives_calls_borg_with_parameters():
|
||||||
remote_path=None,
|
remote_path=None,
|
||||||
).and_return(('borg', 'list', 'repo'))
|
).and_return(('borg', 'list', 'repo'))
|
||||||
flexmock(module).should_receive('make_find_paths').and_return(())
|
flexmock(module).should_receive('make_find_paths').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'list', 'repo'),
|
('borg', 'list', 'repo'), output_log_level=logging.WARNING, borg_local_path='borg'
|
||||||
output_log_level=logging.WARNING,
|
|
||||||
borg_local_path='borg',
|
|
||||||
extra_environment=None,
|
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.list_archives(
|
module.list_archives(
|
||||||
|
@ -338,12 +316,8 @@ def test_list_archives_with_json_suppresses_most_borg_output():
|
||||||
remote_path=None,
|
remote_path=None,
|
||||||
).and_return(('borg', 'list', 'repo'))
|
).and_return(('borg', 'list', 'repo'))
|
||||||
flexmock(module).should_receive('make_find_paths').and_return(())
|
flexmock(module).should_receive('make_find_paths').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'list', 'repo'),
|
('borg', 'list', 'repo'), output_log_level=None, borg_local_path='borg'
|
||||||
output_log_level=None,
|
|
||||||
borg_local_path='borg',
|
|
||||||
extra_environment=None,
|
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.list_archives(
|
module.list_archives(
|
||||||
|
@ -362,12 +336,8 @@ def test_list_archives_calls_borg_with_local_path():
|
||||||
remote_path=None,
|
remote_path=None,
|
||||||
).and_return(('borg2', 'list', 'repo'))
|
).and_return(('borg2', 'list', 'repo'))
|
||||||
flexmock(module).should_receive('make_find_paths').and_return(())
|
flexmock(module).should_receive('make_find_paths').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg2', 'list', 'repo'),
|
('borg2', 'list', 'repo'), output_log_level=logging.WARNING, borg_local_path='borg2'
|
||||||
output_log_level=logging.WARNING,
|
|
||||||
borg_local_path='borg2',
|
|
||||||
extra_environment=None,
|
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.list_archives(
|
module.list_archives(
|
||||||
|
@ -385,27 +355,20 @@ def test_list_archives_calls_borg_multiple_times_with_find_paths():
|
||||||
('borg', 'list', 'repo')
|
('borg', 'list', 'repo')
|
||||||
).and_return(('borg', 'list', 'repo::archive1')).and_return(('borg', 'list', 'repo::archive2'))
|
).and_return(('borg', 'list', 'repo::archive1')).and_return(('borg', 'list', 'repo::archive2'))
|
||||||
flexmock(module).should_receive('make_find_paths').and_return(glob_paths)
|
flexmock(module).should_receive('make_find_paths').and_return(glob_paths)
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'list', 'repo'),
|
('borg', 'list', 'repo'), output_log_level=None, borg_local_path='borg'
|
||||||
output_log_level=None,
|
|
||||||
borg_local_path='borg',
|
|
||||||
extra_environment=None,
|
|
||||||
).and_return(
|
).and_return(
|
||||||
'archive1 Sun, 2022-05-29 15:27:04 [abc]\narchive2 Mon, 2022-05-30 19:47:15 [xyz]'
|
'archive1 Sun, 2022-05-29 15:27:04 [abc]\narchive2 Mon, 2022-05-30 19:47:15 [xyz]'
|
||||||
).once()
|
).once()
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'list', 'repo::archive1') + glob_paths,
|
('borg', 'list', 'repo::archive1') + glob_paths,
|
||||||
output_log_level=logging.WARNING,
|
output_log_level=logging.WARNING,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
extra_environment=None,
|
|
||||||
).once()
|
).once()
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'list', 'repo::archive2') + glob_paths,
|
('borg', 'list', 'repo::archive2') + glob_paths,
|
||||||
output_log_level=logging.WARNING,
|
output_log_level=logging.WARNING,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
extra_environment=None,
|
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.list_archives(
|
module.list_archives(
|
||||||
|
@ -424,12 +387,8 @@ def test_list_archives_calls_borg_with_archive():
|
||||||
remote_path=None,
|
remote_path=None,
|
||||||
).and_return(('borg', 'list', 'repo::archive'))
|
).and_return(('borg', 'list', 'repo::archive'))
|
||||||
flexmock(module).should_receive('make_find_paths').and_return(())
|
flexmock(module).should_receive('make_find_paths').and_return(())
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'list', 'repo::archive'),
|
('borg', 'list', 'repo::archive'), output_log_level=logging.WARNING, borg_local_path='borg'
|
||||||
output_log_level=logging.WARNING,
|
|
||||||
borg_local_path='borg',
|
|
||||||
extra_environment=None,
|
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.list_archives(
|
module.list_archives(
|
||||||
|
|
|
@ -8,9 +8,8 @@ from ..test_verbosity import insert_logging_mock
|
||||||
|
|
||||||
|
|
||||||
def insert_execute_command_mock(command):
|
def insert_execute_command_mock(command):
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
command, borg_local_path='borg', extra_environment=None,
|
command, borg_local_path='borg'
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
|
|
||||||
|
@ -118,12 +117,10 @@ def test_mount_archive_with_log_debug_calls_borg_with_debug_parameters():
|
||||||
|
|
||||||
|
|
||||||
def test_mount_archive_calls_borg_with_foreground_parameter():
|
def test_mount_archive_calls_borg_with_foreground_parameter():
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
('borg', 'mount', '--foreground', 'repo::archive', '/mnt'),
|
('borg', 'mount', '--foreground', 'repo::archive', '/mnt'),
|
||||||
output_file=module.DO_NOT_CAPTURE,
|
output_file=module.DO_NOT_CAPTURE,
|
||||||
borg_local_path='borg',
|
borg_local_path='borg',
|
||||||
extra_environment=None,
|
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
module.mount_archive(
|
module.mount_archive(
|
||||||
|
|
|
@ -9,12 +9,8 @@ from ..test_verbosity import insert_logging_mock
|
||||||
|
|
||||||
|
|
||||||
def insert_execute_command_mock(prune_command, output_log_level):
|
def insert_execute_command_mock(prune_command, output_log_level):
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
prune_command,
|
prune_command, output_log_level=output_log_level, borg_local_path=prune_command[0]
|
||||||
output_log_level=output_log_level,
|
|
||||||
borg_local_path=prune_command[0],
|
|
||||||
extra_environment=None,
|
|
||||||
).once()
|
).once()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,45 +11,39 @@ VERSION = '1.2.3'
|
||||||
|
|
||||||
|
|
||||||
def insert_execute_command_mock(command, borg_local_path='borg', version_output=f'borg {VERSION}'):
|
def insert_execute_command_mock(command, borg_local_path='borg', version_output=f'borg {VERSION}'):
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
flexmock(module).should_receive('execute_command').with_args(
|
flexmock(module).should_receive('execute_command').with_args(
|
||||||
command, output_log_level=None, borg_local_path=borg_local_path, extra_environment=None,
|
command, output_log_level=None, borg_local_path=borg_local_path
|
||||||
).once().and_return(version_output)
|
).once().and_return(version_output)
|
||||||
|
|
||||||
|
|
||||||
def test_local_borg_version_calls_borg_with_required_parameters():
|
def test_local_borg_version_calls_borg_with_required_parameters():
|
||||||
insert_execute_command_mock(('borg', '--version'))
|
insert_execute_command_mock(('borg', '--version'))
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
|
|
||||||
assert module.local_borg_version({}) == VERSION
|
assert module.local_borg_version() == VERSION
|
||||||
|
|
||||||
|
|
||||||
def test_local_borg_version_with_log_info_calls_borg_with_info_parameter():
|
def test_local_borg_version_with_log_info_calls_borg_with_info_parameter():
|
||||||
insert_execute_command_mock(('borg', '--version', '--info'))
|
insert_execute_command_mock(('borg', '--version', '--info'))
|
||||||
insert_logging_mock(logging.INFO)
|
insert_logging_mock(logging.INFO)
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
|
|
||||||
assert module.local_borg_version({}) == VERSION
|
assert module.local_borg_version() == VERSION
|
||||||
|
|
||||||
|
|
||||||
def test_local_borg_version_with_log_debug_calls_borg_with_debug_parameters():
|
def test_local_borg_version_with_log_debug_calls_borg_with_debug_parameters():
|
||||||
insert_execute_command_mock(('borg', '--version', '--debug', '--show-rc'))
|
insert_execute_command_mock(('borg', '--version', '--debug', '--show-rc'))
|
||||||
insert_logging_mock(logging.DEBUG)
|
insert_logging_mock(logging.DEBUG)
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
|
|
||||||
assert module.local_borg_version({}) == VERSION
|
assert module.local_borg_version() == VERSION
|
||||||
|
|
||||||
|
|
||||||
def test_local_borg_version_with_local_borg_path_calls_borg_with_it():
|
def test_local_borg_version_with_local_borg_path_calls_borg_with_it():
|
||||||
insert_execute_command_mock(('borg1', '--version'), borg_local_path='borg1')
|
insert_execute_command_mock(('borg1', '--version'), borg_local_path='borg1')
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
|
|
||||||
assert module.local_borg_version({}, 'borg1') == VERSION
|
assert module.local_borg_version('borg1') == VERSION
|
||||||
|
|
||||||
|
|
||||||
def test_local_borg_version_with_invalid_version_raises():
|
def test_local_borg_version_with_invalid_version_raises():
|
||||||
insert_execute_command_mock(('borg', '--version'), version_output='wtf')
|
insert_execute_command_mock(('borg', '--version'), version_output='wtf')
|
||||||
flexmock(module.environment).should_receive('make_environment')
|
|
||||||
|
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
module.local_borg_version({})
|
module.local_borg_version()
|
||||||
|
|
|
@ -9,6 +9,7 @@ from borgmatic.commands import borgmatic as module
|
||||||
|
|
||||||
|
|
||||||
def test_run_configuration_runs_actions_for_each_repository():
|
def test_run_configuration_runs_actions_for_each_repository():
|
||||||
|
flexmock(module.borg_environment).should_receive('initialize')
|
||||||
flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock())
|
flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock())
|
||||||
expected_results = [flexmock(), flexmock()]
|
expected_results = [flexmock(), flexmock()]
|
||||||
flexmock(module).should_receive('run_actions').and_return(expected_results[:1]).and_return(
|
flexmock(module).should_receive('run_actions').and_return(expected_results[:1]).and_return(
|
||||||
|
@ -23,6 +24,7 @@ def test_run_configuration_runs_actions_for_each_repository():
|
||||||
|
|
||||||
|
|
||||||
def test_run_configuration_with_invalid_borg_version_errors():
|
def test_run_configuration_with_invalid_borg_version_errors():
|
||||||
|
flexmock(module.borg_environment).should_receive('initialize')
|
||||||
flexmock(module.borg_version).should_receive('local_borg_version').and_raise(ValueError)
|
flexmock(module.borg_version).should_receive('local_borg_version').and_raise(ValueError)
|
||||||
flexmock(module.command).should_receive('execute_hook').never()
|
flexmock(module.command).should_receive('execute_hook').never()
|
||||||
flexmock(module.dispatch).should_receive('call_hooks').never()
|
flexmock(module.dispatch).should_receive('call_hooks').never()
|
||||||
|
@ -34,6 +36,7 @@ def test_run_configuration_with_invalid_borg_version_errors():
|
||||||
|
|
||||||
|
|
||||||
def test_run_configuration_logs_monitor_start_error():
|
def test_run_configuration_logs_monitor_start_error():
|
||||||
|
flexmock(module.borg_environment).should_receive('initialize')
|
||||||
flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock())
|
flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock())
|
||||||
flexmock(module.dispatch).should_receive('call_hooks').and_raise(OSError).and_return(
|
flexmock(module.dispatch).should_receive('call_hooks').and_raise(OSError).and_return(
|
||||||
None
|
None
|
||||||
|
@ -50,6 +53,7 @@ def test_run_configuration_logs_monitor_start_error():
|
||||||
|
|
||||||
|
|
||||||
def test_run_configuration_bails_for_monitor_start_soft_failure():
|
def test_run_configuration_bails_for_monitor_start_soft_failure():
|
||||||
|
flexmock(module.borg_environment).should_receive('initialize')
|
||||||
flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock())
|
flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock())
|
||||||
error = subprocess.CalledProcessError(borgmatic.hooks.command.SOFT_FAIL_EXIT_CODE, 'try again')
|
error = subprocess.CalledProcessError(borgmatic.hooks.command.SOFT_FAIL_EXIT_CODE, 'try again')
|
||||||
flexmock(module.dispatch).should_receive('call_hooks').and_raise(error)
|
flexmock(module.dispatch).should_receive('call_hooks').and_raise(error)
|
||||||
|
@ -64,6 +68,7 @@ def test_run_configuration_bails_for_monitor_start_soft_failure():
|
||||||
|
|
||||||
|
|
||||||
def test_run_configuration_logs_actions_error():
|
def test_run_configuration_logs_actions_error():
|
||||||
|
flexmock(module.borg_environment).should_receive('initialize')
|
||||||
flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock())
|
flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock())
|
||||||
flexmock(module.command).should_receive('execute_hook')
|
flexmock(module.command).should_receive('execute_hook')
|
||||||
flexmock(module.dispatch).should_receive('call_hooks')
|
flexmock(module.dispatch).should_receive('call_hooks')
|
||||||
|
@ -79,6 +84,7 @@ def test_run_configuration_logs_actions_error():
|
||||||
|
|
||||||
|
|
||||||
def test_run_configuration_bails_for_actions_soft_failure():
|
def test_run_configuration_bails_for_actions_soft_failure():
|
||||||
|
flexmock(module.borg_environment).should_receive('initialize')
|
||||||
flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock())
|
flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock())
|
||||||
flexmock(module.dispatch).should_receive('call_hooks')
|
flexmock(module.dispatch).should_receive('call_hooks')
|
||||||
error = subprocess.CalledProcessError(borgmatic.hooks.command.SOFT_FAIL_EXIT_CODE, 'try again')
|
error = subprocess.CalledProcessError(borgmatic.hooks.command.SOFT_FAIL_EXIT_CODE, 'try again')
|
||||||
|
@ -94,6 +100,7 @@ def test_run_configuration_bails_for_actions_soft_failure():
|
||||||
|
|
||||||
|
|
||||||
def test_run_configuration_logs_monitor_finish_error():
|
def test_run_configuration_logs_monitor_finish_error():
|
||||||
|
flexmock(module.borg_environment).should_receive('initialize')
|
||||||
flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock())
|
flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock())
|
||||||
flexmock(module.dispatch).should_receive('call_hooks').and_return(None).and_return(
|
flexmock(module.dispatch).should_receive('call_hooks').and_return(None).and_return(
|
||||||
None
|
None
|
||||||
|
@ -110,6 +117,7 @@ def test_run_configuration_logs_monitor_finish_error():
|
||||||
|
|
||||||
|
|
||||||
def test_run_configuration_bails_for_monitor_finish_soft_failure():
|
def test_run_configuration_bails_for_monitor_finish_soft_failure():
|
||||||
|
flexmock(module.borg_environment).should_receive('initialize')
|
||||||
flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock())
|
flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock())
|
||||||
error = subprocess.CalledProcessError(borgmatic.hooks.command.SOFT_FAIL_EXIT_CODE, 'try again')
|
error = subprocess.CalledProcessError(borgmatic.hooks.command.SOFT_FAIL_EXIT_CODE, 'try again')
|
||||||
flexmock(module.dispatch).should_receive('call_hooks').and_return(None).and_return(
|
flexmock(module.dispatch).should_receive('call_hooks').and_return(None).and_return(
|
||||||
|
@ -127,6 +135,7 @@ def test_run_configuration_bails_for_monitor_finish_soft_failure():
|
||||||
|
|
||||||
|
|
||||||
def test_run_configuration_logs_on_error_hook_error():
|
def test_run_configuration_logs_on_error_hook_error():
|
||||||
|
flexmock(module.borg_environment).should_receive('initialize')
|
||||||
flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock())
|
flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock())
|
||||||
flexmock(module.command).should_receive('execute_hook').and_raise(OSError)
|
flexmock(module.command).should_receive('execute_hook').and_raise(OSError)
|
||||||
expected_results = [flexmock(), flexmock()]
|
expected_results = [flexmock(), flexmock()]
|
||||||
|
@ -143,6 +152,7 @@ def test_run_configuration_logs_on_error_hook_error():
|
||||||
|
|
||||||
|
|
||||||
def test_run_configuration_bails_for_on_error_hook_soft_failure():
|
def test_run_configuration_bails_for_on_error_hook_soft_failure():
|
||||||
|
flexmock(module.borg_environment).should_receive('initialize')
|
||||||
flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock())
|
flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock())
|
||||||
error = subprocess.CalledProcessError(borgmatic.hooks.command.SOFT_FAIL_EXIT_CODE, 'try again')
|
error = subprocess.CalledProcessError(borgmatic.hooks.command.SOFT_FAIL_EXIT_CODE, 'try again')
|
||||||
flexmock(module.command).should_receive('execute_hook').and_raise(error)
|
flexmock(module.command).should_receive('execute_hook').and_raise(error)
|
||||||
|
@ -159,6 +169,7 @@ def test_run_configuration_bails_for_on_error_hook_soft_failure():
|
||||||
|
|
||||||
def test_run_configuration_retries_soft_error():
|
def test_run_configuration_retries_soft_error():
|
||||||
# Run action first fails, second passes
|
# Run action first fails, second passes
|
||||||
|
flexmock(module.borg_environment).should_receive('initialize')
|
||||||
flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock())
|
flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock())
|
||||||
flexmock(module.command).should_receive('execute_hook')
|
flexmock(module.command).should_receive('execute_hook')
|
||||||
flexmock(module).should_receive('run_actions').and_raise(OSError).and_return([])
|
flexmock(module).should_receive('run_actions').and_raise(OSError).and_return([])
|
||||||
|
@ -171,6 +182,7 @@ def test_run_configuration_retries_soft_error():
|
||||||
|
|
||||||
def test_run_configuration_retries_hard_error():
|
def test_run_configuration_retries_hard_error():
|
||||||
# Run action fails twice
|
# Run action fails twice
|
||||||
|
flexmock(module.borg_environment).should_receive('initialize')
|
||||||
flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock())
|
flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock())
|
||||||
flexmock(module.command).should_receive('execute_hook')
|
flexmock(module.command).should_receive('execute_hook')
|
||||||
flexmock(module).should_receive('run_actions').and_raise(OSError).times(2)
|
flexmock(module).should_receive('run_actions').and_raise(OSError).times(2)
|
||||||
|
@ -191,6 +203,7 @@ def test_run_configuration_retries_hard_error():
|
||||||
|
|
||||||
|
|
||||||
def test_run_repos_ordered():
|
def test_run_repos_ordered():
|
||||||
|
flexmock(module.borg_environment).should_receive('initialize')
|
||||||
flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock())
|
flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock())
|
||||||
flexmock(module.command).should_receive('execute_hook')
|
flexmock(module.command).should_receive('execute_hook')
|
||||||
flexmock(module).should_receive('run_actions').and_raise(OSError).times(2)
|
flexmock(module).should_receive('run_actions').and_raise(OSError).times(2)
|
||||||
|
@ -208,6 +221,7 @@ def test_run_repos_ordered():
|
||||||
|
|
||||||
|
|
||||||
def test_run_configuration_retries_round_robbin():
|
def test_run_configuration_retries_round_robbin():
|
||||||
|
flexmock(module.borg_environment).should_receive('initialize')
|
||||||
flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock())
|
flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock())
|
||||||
flexmock(module.command).should_receive('execute_hook')
|
flexmock(module.command).should_receive('execute_hook')
|
||||||
flexmock(module).should_receive('run_actions').and_raise(OSError).times(4)
|
flexmock(module).should_receive('run_actions').and_raise(OSError).times(4)
|
||||||
|
@ -238,6 +252,7 @@ def test_run_configuration_retries_round_robbin():
|
||||||
|
|
||||||
|
|
||||||
def test_run_configuration_retries_one_passes():
|
def test_run_configuration_retries_one_passes():
|
||||||
|
flexmock(module.borg_environment).should_receive('initialize')
|
||||||
flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock())
|
flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock())
|
||||||
flexmock(module.command).should_receive('execute_hook')
|
flexmock(module.command).should_receive('execute_hook')
|
||||||
flexmock(module).should_receive('run_actions').and_raise(OSError).and_raise(OSError).and_return(
|
flexmock(module).should_receive('run_actions').and_raise(OSError).and_raise(OSError).and_return(
|
||||||
|
@ -266,6 +281,7 @@ def test_run_configuration_retries_one_passes():
|
||||||
|
|
||||||
|
|
||||||
def test_run_configuration_retry_wait():
|
def test_run_configuration_retry_wait():
|
||||||
|
flexmock(module.borg_environment).should_receive('initialize')
|
||||||
flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock())
|
flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock())
|
||||||
flexmock(module.command).should_receive('execute_hook')
|
flexmock(module.command).should_receive('execute_hook')
|
||||||
flexmock(module).should_receive('run_actions').and_raise(OSError).times(4)
|
flexmock(module).should_receive('run_actions').and_raise(OSError).times(4)
|
||||||
|
@ -304,6 +320,7 @@ def test_run_configuration_retry_wait():
|
||||||
|
|
||||||
|
|
||||||
def test_run_configuration_retries_timeout_multiple_repos():
|
def test_run_configuration_retries_timeout_multiple_repos():
|
||||||
|
flexmock(module.borg_environment).should_receive('initialize')
|
||||||
flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock())
|
flexmock(module.borg_version).should_receive('local_borg_version').and_return(flexmock())
|
||||||
flexmock(module.command).should_receive('execute_hook')
|
flexmock(module.command).should_receive('execute_hook')
|
||||||
flexmock(module).should_receive('run_actions').and_raise(OSError).and_raise(OSError).and_return(
|
flexmock(module).should_receive('run_actions').and_raise(OSError).and_raise(OSError).and_return(
|
||||||
|
|
|
@ -1,87 +0,0 @@
|
||||||
import pytest
|
|
||||||
|
|
||||||
from borgmatic.config import environment as module
|
|
||||||
|
|
||||||
|
|
||||||
def test_env(monkeypatch):
|
|
||||||
monkeypatch.setenv('MY_CUSTOM_VALUE', 'foo')
|
|
||||||
config = {'key': 'Hello $MY_CUSTOM_VALUE'}
|
|
||||||
module.resolve_env_variables(config)
|
|
||||||
assert config == {'key': 'Hello $MY_CUSTOM_VALUE'}
|
|
||||||
|
|
||||||
|
|
||||||
def test_env_braces(monkeypatch):
|
|
||||||
monkeypatch.setenv('MY_CUSTOM_VALUE', 'foo')
|
|
||||||
config = {'key': 'Hello ${MY_CUSTOM_VALUE}'}
|
|
||||||
module.resolve_env_variables(config)
|
|
||||||
assert config == {'key': 'Hello foo'}
|
|
||||||
|
|
||||||
|
|
||||||
def test_env_multi(monkeypatch):
|
|
||||||
monkeypatch.setenv('MY_CUSTOM_VALUE', 'foo')
|
|
||||||
monkeypatch.setenv('MY_CUSTOM_VALUE2', 'bar')
|
|
||||||
config = {'key': 'Hello ${MY_CUSTOM_VALUE}${MY_CUSTOM_VALUE2}'}
|
|
||||||
module.resolve_env_variables(config)
|
|
||||||
assert config == {'key': 'Hello foobar'}
|
|
||||||
|
|
||||||
|
|
||||||
def test_env_escape(monkeypatch):
|
|
||||||
monkeypatch.setenv('MY_CUSTOM_VALUE', 'foo')
|
|
||||||
monkeypatch.setenv('MY_CUSTOM_VALUE2', 'bar')
|
|
||||||
config = {'key': r'Hello ${MY_CUSTOM_VALUE} \${MY_CUSTOM_VALUE}'}
|
|
||||||
module.resolve_env_variables(config)
|
|
||||||
assert config == {'key': r'Hello foo ${MY_CUSTOM_VALUE}'}
|
|
||||||
|
|
||||||
|
|
||||||
def test_env_default_value(monkeypatch):
|
|
||||||
monkeypatch.delenv('MY_CUSTOM_VALUE', raising=False)
|
|
||||||
config = {'key': 'Hello ${MY_CUSTOM_VALUE:-bar}'}
|
|
||||||
module.resolve_env_variables(config)
|
|
||||||
assert config == {'key': 'Hello bar'}
|
|
||||||
|
|
||||||
|
|
||||||
def test_env_unknown(monkeypatch):
|
|
||||||
monkeypatch.delenv('MY_CUSTOM_VALUE', raising=False)
|
|
||||||
config = {'key': 'Hello ${MY_CUSTOM_VALUE}'}
|
|
||||||
with pytest.raises(ValueError):
|
|
||||||
module.resolve_env_variables(config)
|
|
||||||
|
|
||||||
|
|
||||||
def test_env_full(monkeypatch):
|
|
||||||
monkeypatch.setenv('MY_CUSTOM_VALUE', 'foo')
|
|
||||||
monkeypatch.delenv('MY_CUSTOM_VALUE2', raising=False)
|
|
||||||
config = {
|
|
||||||
'key': 'Hello $MY_CUSTOM_VALUE is not resolved',
|
|
||||||
'dict': {
|
|
||||||
'key': 'value',
|
|
||||||
'anotherdict': {
|
|
||||||
'key': 'My ${MY_CUSTOM_VALUE} here',
|
|
||||||
'other': '${MY_CUSTOM_VALUE}',
|
|
||||||
'escaped': r'\${MY_CUSTOM_VALUE}',
|
|
||||||
'list': [
|
|
||||||
'/home/${MY_CUSTOM_VALUE}/.local',
|
|
||||||
'/var/log/',
|
|
||||||
'/home/${MY_CUSTOM_VALUE2:-bar}/.config',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'list': [
|
|
||||||
'/home/${MY_CUSTOM_VALUE}/.local',
|
|
||||||
'/var/log/',
|
|
||||||
'/home/${MY_CUSTOM_VALUE2-bar}/.config',
|
|
||||||
],
|
|
||||||
}
|
|
||||||
module.resolve_env_variables(config)
|
|
||||||
assert config == {
|
|
||||||
'key': 'Hello $MY_CUSTOM_VALUE is not resolved',
|
|
||||||
'dict': {
|
|
||||||
'key': 'value',
|
|
||||||
'anotherdict': {
|
|
||||||
'key': 'My foo here',
|
|
||||||
'other': 'foo',
|
|
||||||
'escaped': '${MY_CUSTOM_VALUE}',
|
|
||||||
'list': ['/home/foo/.local', '/var/log/', '/home/bar/.config'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'list': ['/home/foo/.local', '/var/log/', '/home/bar/.config'],
|
|
||||||
}
|
|
|
@ -5,9 +5,7 @@ from borgmatic.hooks import cronhub as module
|
||||||
|
|
||||||
def test_ping_monitor_rewrites_ping_url_for_start_state():
|
def test_ping_monitor_rewrites_ping_url_for_start_state():
|
||||||
hook_config = {'ping_url': 'https://example.com/start/abcdef'}
|
hook_config = {'ping_url': 'https://example.com/start/abcdef'}
|
||||||
flexmock(module.requests).should_receive('get').with_args(
|
flexmock(module.requests).should_receive('get').with_args('https://example.com/start/abcdef')
|
||||||
'https://example.com/start/abcdef'
|
|
||||||
).and_return(flexmock(ok=True))
|
|
||||||
|
|
||||||
module.ping_monitor(
|
module.ping_monitor(
|
||||||
hook_config,
|
hook_config,
|
||||||
|
@ -20,9 +18,7 @@ def test_ping_monitor_rewrites_ping_url_for_start_state():
|
||||||
|
|
||||||
def test_ping_monitor_rewrites_ping_url_and_state_for_start_state():
|
def test_ping_monitor_rewrites_ping_url_and_state_for_start_state():
|
||||||
hook_config = {'ping_url': 'https://example.com/ping/abcdef'}
|
hook_config = {'ping_url': 'https://example.com/ping/abcdef'}
|
||||||
flexmock(module.requests).should_receive('get').with_args(
|
flexmock(module.requests).should_receive('get').with_args('https://example.com/start/abcdef')
|
||||||
'https://example.com/start/abcdef'
|
|
||||||
).and_return(flexmock(ok=True))
|
|
||||||
|
|
||||||
module.ping_monitor(
|
module.ping_monitor(
|
||||||
hook_config,
|
hook_config,
|
||||||
|
@ -35,9 +31,7 @@ def test_ping_monitor_rewrites_ping_url_and_state_for_start_state():
|
||||||
|
|
||||||
def test_ping_monitor_rewrites_ping_url_for_finish_state():
|
def test_ping_monitor_rewrites_ping_url_for_finish_state():
|
||||||
hook_config = {'ping_url': 'https://example.com/start/abcdef'}
|
hook_config = {'ping_url': 'https://example.com/start/abcdef'}
|
||||||
flexmock(module.requests).should_receive('get').with_args(
|
flexmock(module.requests).should_receive('get').with_args('https://example.com/finish/abcdef')
|
||||||
'https://example.com/finish/abcdef'
|
|
||||||
).and_return(flexmock(ok=True))
|
|
||||||
|
|
||||||
module.ping_monitor(
|
module.ping_monitor(
|
||||||
hook_config,
|
hook_config,
|
||||||
|
@ -50,9 +44,7 @@ def test_ping_monitor_rewrites_ping_url_for_finish_state():
|
||||||
|
|
||||||
def test_ping_monitor_rewrites_ping_url_for_fail_state():
|
def test_ping_monitor_rewrites_ping_url_for_fail_state():
|
||||||
hook_config = {'ping_url': 'https://example.com/start/abcdef'}
|
hook_config = {'ping_url': 'https://example.com/start/abcdef'}
|
||||||
flexmock(module.requests).should_receive('get').with_args(
|
flexmock(module.requests).should_receive('get').with_args('https://example.com/fail/abcdef')
|
||||||
'https://example.com/fail/abcdef'
|
|
||||||
).and_return(flexmock(ok=True))
|
|
||||||
|
|
||||||
module.ping_monitor(
|
module.ping_monitor(
|
||||||
hook_config, 'config.yaml', module.monitor.State.FAIL, monitoring_log_level=1, dry_run=False
|
hook_config, 'config.yaml', module.monitor.State.FAIL, monitoring_log_level=1, dry_run=False
|
||||||
|
@ -68,32 +60,11 @@ def test_ping_monitor_dry_run_does_not_hit_ping_url():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_ping_monitor_with_connection_error_logs_warning():
|
def test_ping_monitor_with_connection_error_does_not_raise():
|
||||||
hook_config = {'ping_url': 'https://example.com/start/abcdef'}
|
hook_config = {'ping_url': 'https://example.com/start/abcdef'}
|
||||||
flexmock(module.requests).should_receive('get').and_raise(
|
flexmock(module.requests).should_receive('get').and_raise(
|
||||||
module.requests.exceptions.ConnectionError
|
module.requests.exceptions.ConnectionError
|
||||||
)
|
)
|
||||||
flexmock(module.logger).should_receive('warning').once()
|
|
||||||
|
|
||||||
module.ping_monitor(
|
|
||||||
hook_config,
|
|
||||||
'config.yaml',
|
|
||||||
module.monitor.State.START,
|
|
||||||
monitoring_log_level=1,
|
|
||||||
dry_run=False,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_ping_monitor_with_other_error_logs_warning():
|
|
||||||
hook_config = {'ping_url': 'https://example.com/start/abcdef'}
|
|
||||||
response = flexmock(ok=False)
|
|
||||||
response.should_receive('raise_for_status').and_raise(
|
|
||||||
module.requests.exceptions.RequestException
|
|
||||||
)
|
|
||||||
flexmock(module.requests).should_receive('get').with_args(
|
|
||||||
'https://example.com/start/abcdef'
|
|
||||||
).and_return(response)
|
|
||||||
flexmock(module.logger).should_receive('warning').once()
|
|
||||||
|
|
||||||
module.ping_monitor(
|
module.ping_monitor(
|
||||||
hook_config,
|
hook_config,
|
||||||
|
|
|
@ -5,9 +5,7 @@ from borgmatic.hooks import cronitor as module
|
||||||
|
|
||||||
def test_ping_monitor_hits_ping_url_for_start_state():
|
def test_ping_monitor_hits_ping_url_for_start_state():
|
||||||
hook_config = {'ping_url': 'https://example.com'}
|
hook_config = {'ping_url': 'https://example.com'}
|
||||||
flexmock(module.requests).should_receive('get').with_args('https://example.com/run').and_return(
|
flexmock(module.requests).should_receive('get').with_args('https://example.com/run')
|
||||||
flexmock(ok=True)
|
|
||||||
)
|
|
||||||
|
|
||||||
module.ping_monitor(
|
module.ping_monitor(
|
||||||
hook_config,
|
hook_config,
|
||||||
|
@ -20,9 +18,7 @@ def test_ping_monitor_hits_ping_url_for_start_state():
|
||||||
|
|
||||||
def test_ping_monitor_hits_ping_url_for_finish_state():
|
def test_ping_monitor_hits_ping_url_for_finish_state():
|
||||||
hook_config = {'ping_url': 'https://example.com'}
|
hook_config = {'ping_url': 'https://example.com'}
|
||||||
flexmock(module.requests).should_receive('get').with_args(
|
flexmock(module.requests).should_receive('get').with_args('https://example.com/complete')
|
||||||
'https://example.com/complete'
|
|
||||||
).and_return(flexmock(ok=True))
|
|
||||||
|
|
||||||
module.ping_monitor(
|
module.ping_monitor(
|
||||||
hook_config,
|
hook_config,
|
||||||
|
@ -35,9 +31,7 @@ def test_ping_monitor_hits_ping_url_for_finish_state():
|
||||||
|
|
||||||
def test_ping_monitor_hits_ping_url_for_fail_state():
|
def test_ping_monitor_hits_ping_url_for_fail_state():
|
||||||
hook_config = {'ping_url': 'https://example.com'}
|
hook_config = {'ping_url': 'https://example.com'}
|
||||||
flexmock(module.requests).should_receive('get').with_args(
|
flexmock(module.requests).should_receive('get').with_args('https://example.com/fail')
|
||||||
'https://example.com/fail'
|
|
||||||
).and_return(flexmock(ok=True))
|
|
||||||
|
|
||||||
module.ping_monitor(
|
module.ping_monitor(
|
||||||
hook_config, 'config.yaml', module.monitor.State.FAIL, monitoring_log_level=1, dry_run=False
|
hook_config, 'config.yaml', module.monitor.State.FAIL, monitoring_log_level=1, dry_run=False
|
||||||
|
@ -53,32 +47,11 @@ def test_ping_monitor_dry_run_does_not_hit_ping_url():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_ping_monitor_with_connection_error_logs_warning():
|
def test_ping_monitor_with_connection_error_does_not_raise():
|
||||||
hook_config = {'ping_url': 'https://example.com'}
|
hook_config = {'ping_url': 'https://example.com'}
|
||||||
flexmock(module.requests).should_receive('get').and_raise(
|
flexmock(module.requests).should_receive('get').and_raise(
|
||||||
module.requests.exceptions.ConnectionError
|
module.requests.exceptions.ConnectionError
|
||||||
)
|
)
|
||||||
flexmock(module.logger).should_receive('warning').once()
|
|
||||||
|
|
||||||
module.ping_monitor(
|
|
||||||
hook_config,
|
|
||||||
'config.yaml',
|
|
||||||
module.monitor.State.START,
|
|
||||||
monitoring_log_level=1,
|
|
||||||
dry_run=False,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_ping_monitor_with_other_error_logs_warning():
|
|
||||||
hook_config = {'ping_url': 'https://example.com'}
|
|
||||||
response = flexmock(ok=False)
|
|
||||||
response.should_receive('raise_for_status').and_raise(
|
|
||||||
module.requests.exceptions.RequestException
|
|
||||||
)
|
|
||||||
flexmock(module.requests).should_receive('get').with_args('https://example.com/run').and_return(
|
|
||||||
response
|
|
||||||
)
|
|
||||||
flexmock(module.logger).should_receive('warning').once()
|
|
||||||
|
|
||||||
module.ping_monitor(
|
module.ping_monitor(
|
||||||
hook_config,
|
hook_config,
|
||||||
|
|
|
@ -139,7 +139,7 @@ def test_ping_monitor_hits_ping_url_for_start_state():
|
||||||
hook_config = {'ping_url': 'https://example.com'}
|
hook_config = {'ping_url': 'https://example.com'}
|
||||||
flexmock(module.requests).should_receive('post').with_args(
|
flexmock(module.requests).should_receive('post').with_args(
|
||||||
'https://example.com/start', data=''.encode('utf-8')
|
'https://example.com/start', data=''.encode('utf-8')
|
||||||
).and_return(flexmock(ok=True))
|
)
|
||||||
|
|
||||||
module.ping_monitor(
|
module.ping_monitor(
|
||||||
hook_config,
|
hook_config,
|
||||||
|
@ -156,7 +156,7 @@ def test_ping_monitor_hits_ping_url_for_finish_state():
|
||||||
flexmock(module).should_receive('format_buffered_logs_for_payload').and_return(payload)
|
flexmock(module).should_receive('format_buffered_logs_for_payload').and_return(payload)
|
||||||
flexmock(module.requests).should_receive('post').with_args(
|
flexmock(module.requests).should_receive('post').with_args(
|
||||||
'https://example.com', data=payload.encode('utf-8')
|
'https://example.com', data=payload.encode('utf-8')
|
||||||
).and_return(flexmock(ok=True))
|
)
|
||||||
|
|
||||||
module.ping_monitor(
|
module.ping_monitor(
|
||||||
hook_config,
|
hook_config,
|
||||||
|
@ -173,7 +173,7 @@ def test_ping_monitor_hits_ping_url_for_fail_state():
|
||||||
flexmock(module).should_receive('format_buffered_logs_for_payload').and_return(payload)
|
flexmock(module).should_receive('format_buffered_logs_for_payload').and_return(payload)
|
||||||
flexmock(module.requests).should_receive('post').with_args(
|
flexmock(module.requests).should_receive('post').with_args(
|
||||||
'https://example.com/fail', data=payload.encode('utf')
|
'https://example.com/fail', data=payload.encode('utf')
|
||||||
).and_return(flexmock(ok=True))
|
)
|
||||||
|
|
||||||
module.ping_monitor(
|
module.ping_monitor(
|
||||||
hook_config,
|
hook_config,
|
||||||
|
@ -190,7 +190,7 @@ def test_ping_monitor_with_ping_uuid_hits_corresponding_url():
|
||||||
flexmock(module).should_receive('format_buffered_logs_for_payload').and_return(payload)
|
flexmock(module).should_receive('format_buffered_logs_for_payload').and_return(payload)
|
||||||
flexmock(module.requests).should_receive('post').with_args(
|
flexmock(module.requests).should_receive('post').with_args(
|
||||||
'https://hc-ping.com/{}'.format(hook_config['ping_url']), data=payload.encode('utf-8')
|
'https://hc-ping.com/{}'.format(hook_config['ping_url']), data=payload.encode('utf-8')
|
||||||
).and_return(flexmock(ok=True))
|
)
|
||||||
|
|
||||||
module.ping_monitor(
|
module.ping_monitor(
|
||||||
hook_config,
|
hook_config,
|
||||||
|
@ -234,7 +234,7 @@ def test_ping_monitor_hits_ping_url_when_states_matching():
|
||||||
hook_config = {'ping_url': 'https://example.com', 'states': ['start', 'finish']}
|
hook_config = {'ping_url': 'https://example.com', 'states': ['start', 'finish']}
|
||||||
flexmock(module.requests).should_receive('post').with_args(
|
flexmock(module.requests).should_receive('post').with_args(
|
||||||
'https://example.com/start', data=''.encode('utf-8')
|
'https://example.com/start', data=''.encode('utf-8')
|
||||||
).and_return(flexmock(ok=True))
|
)
|
||||||
|
|
||||||
module.ping_monitor(
|
module.ping_monitor(
|
||||||
hook_config,
|
hook_config,
|
||||||
|
@ -245,34 +245,13 @@ def test_ping_monitor_hits_ping_url_when_states_matching():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_ping_monitor_with_connection_error_logs_warning():
|
def test_ping_monitor_with_connection_error_does_not_raise():
|
||||||
flexmock(module).should_receive('Forgetful_buffering_handler')
|
flexmock(module).should_receive('Forgetful_buffering_handler')
|
||||||
|
flexmock(module.logger).should_receive('warning')
|
||||||
hook_config = {'ping_url': 'https://example.com'}
|
hook_config = {'ping_url': 'https://example.com'}
|
||||||
flexmock(module.requests).should_receive('post').with_args(
|
flexmock(module.requests).should_receive('post').with_args(
|
||||||
'https://example.com/start', data=''.encode('utf-8')
|
'https://example.com/start', data=''.encode('utf-8')
|
||||||
).and_raise(module.requests.exceptions.ConnectionError)
|
).and_raise(module.requests.exceptions.ConnectionError)
|
||||||
flexmock(module.logger).should_receive('warning').once()
|
|
||||||
|
|
||||||
module.ping_monitor(
|
|
||||||
hook_config,
|
|
||||||
'config.yaml',
|
|
||||||
state=module.monitor.State.START,
|
|
||||||
monitoring_log_level=1,
|
|
||||||
dry_run=False,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_ping_monitor_with_other_error_logs_warning():
|
|
||||||
flexmock(module).should_receive('Forgetful_buffering_handler')
|
|
||||||
hook_config = {'ping_url': 'https://example.com'}
|
|
||||||
response = flexmock(ok=False)
|
|
||||||
response.should_receive('raise_for_status').and_raise(
|
|
||||||
module.requests.exceptions.RequestException
|
|
||||||
)
|
|
||||||
flexmock(module.requests).should_receive('post').with_args(
|
|
||||||
'https://example.com/start', data=''.encode('utf-8')
|
|
||||||
).and_return(response)
|
|
||||||
flexmock(module.logger).should_receive('warning').once()
|
|
||||||
|
|
||||||
module.ping_monitor(
|
module.ping_monitor(
|
||||||
hook_config,
|
hook_config,
|
||||||
|
|
|
@ -1,177 +0,0 @@
|
||||||
from enum import Enum
|
|
||||||
|
|
||||||
from flexmock import flexmock
|
|
||||||
|
|
||||||
from borgmatic.hooks import ntfy as module
|
|
||||||
|
|
||||||
default_base_url = 'https://ntfy.sh'
|
|
||||||
custom_base_url = 'https://ntfy.example.com'
|
|
||||||
topic = 'borgmatic-unit-testing'
|
|
||||||
|
|
||||||
custom_message_config = {
|
|
||||||
'title': 'Borgmatic unit testing',
|
|
||||||
'message': 'Borgmatic unit testing',
|
|
||||||
'priority': 'min',
|
|
||||||
'tags': '+1',
|
|
||||||
}
|
|
||||||
|
|
||||||
custom_message_headers = {
|
|
||||||
'X-Title': custom_message_config['title'],
|
|
||||||
'X-Message': custom_message_config['message'],
|
|
||||||
'X-Priority': custom_message_config['priority'],
|
|
||||||
'X-Tags': custom_message_config['tags'],
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def return_default_message_headers(state=Enum):
|
|
||||||
headers = {
|
|
||||||
'X-Title': f'A Borgmatic {state.name} event happened',
|
|
||||||
'X-Message': f'A Borgmatic {state.name} event happened',
|
|
||||||
'X-Priority': 'default',
|
|
||||||
'X-Tags': 'borgmatic',
|
|
||||||
}
|
|
||||||
return headers
|
|
||||||
|
|
||||||
|
|
||||||
def test_ping_monitor_minimal_config_hits_hosted_ntfy_on_fail():
|
|
||||||
hook_config = {'topic': topic}
|
|
||||||
flexmock(module.requests).should_receive('post').with_args(
|
|
||||||
f'{default_base_url}/{topic}',
|
|
||||||
headers=return_default_message_headers(module.monitor.State.FAIL),
|
|
||||||
).and_return(flexmock(ok=True)).once()
|
|
||||||
|
|
||||||
module.ping_monitor(
|
|
||||||
hook_config, 'config.yaml', module.monitor.State.FAIL, monitoring_log_level=1, dry_run=False
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_ping_monitor_minimal_config_does_not_hit_hosted_ntfy_on_start():
|
|
||||||
hook_config = {'topic': topic}
|
|
||||||
flexmock(module.requests).should_receive('post').never()
|
|
||||||
|
|
||||||
module.ping_monitor(
|
|
||||||
hook_config,
|
|
||||||
'config.yaml',
|
|
||||||
module.monitor.State.START,
|
|
||||||
monitoring_log_level=1,
|
|
||||||
dry_run=False,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_ping_monitor_minimal_config_does_not_hit_hosted_ntfy_on_finish():
|
|
||||||
hook_config = {'topic': topic}
|
|
||||||
flexmock(module.requests).should_receive('post').never()
|
|
||||||
|
|
||||||
module.ping_monitor(
|
|
||||||
hook_config,
|
|
||||||
'config.yaml',
|
|
||||||
module.monitor.State.FINISH,
|
|
||||||
monitoring_log_level=1,
|
|
||||||
dry_run=False,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_ping_monitor_minimal_config_hits_selfhosted_ntfy_on_fail():
|
|
||||||
hook_config = {'topic': topic, 'server': custom_base_url}
|
|
||||||
flexmock(module.requests).should_receive('post').with_args(
|
|
||||||
f'{custom_base_url}/{topic}',
|
|
||||||
headers=return_default_message_headers(module.monitor.State.FAIL),
|
|
||||||
).and_return(flexmock(ok=True)).once()
|
|
||||||
|
|
||||||
module.ping_monitor(
|
|
||||||
hook_config, 'config.yaml', module.monitor.State.FAIL, monitoring_log_level=1, dry_run=False
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_ping_monitor_minimal_config_does_not_hit_hosted_ntfy_on_fail_dry_run():
|
|
||||||
hook_config = {'topic': topic}
|
|
||||||
flexmock(module.requests).should_receive('post').never()
|
|
||||||
|
|
||||||
module.ping_monitor(
|
|
||||||
hook_config, 'config.yaml', module.monitor.State.FAIL, monitoring_log_level=1, dry_run=True
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_ping_monitor_custom_message_hits_hosted_ntfy_on_fail():
|
|
||||||
hook_config = {'topic': topic, 'fail': custom_message_config}
|
|
||||||
flexmock(module.requests).should_receive('post').with_args(
|
|
||||||
f'{default_base_url}/{topic}', headers=custom_message_headers,
|
|
||||||
).and_return(flexmock(ok=True)).once()
|
|
||||||
|
|
||||||
module.ping_monitor(
|
|
||||||
hook_config, 'config.yaml', module.monitor.State.FAIL, monitoring_log_level=1, dry_run=False
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_ping_monitor_custom_state_hits_hosted_ntfy_on_start():
|
|
||||||
hook_config = {'topic': topic, 'states': ['start', 'fail']}
|
|
||||||
flexmock(module.requests).should_receive('post').with_args(
|
|
||||||
f'{default_base_url}/{topic}',
|
|
||||||
headers=return_default_message_headers(module.monitor.State.START),
|
|
||||||
).and_return(flexmock(ok=True)).once()
|
|
||||||
|
|
||||||
module.ping_monitor(
|
|
||||||
hook_config,
|
|
||||||
'config.yaml',
|
|
||||||
module.monitor.State.START,
|
|
||||||
monitoring_log_level=1,
|
|
||||||
dry_run=False,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_ping_monitor_with_connection_error_logs_warning():
|
|
||||||
hook_config = {'topic': topic}
|
|
||||||
flexmock(module.requests).should_receive('post').with_args(
|
|
||||||
f'{default_base_url}/{topic}',
|
|
||||||
headers=return_default_message_headers(module.monitor.State.FAIL),
|
|
||||||
).and_raise(module.requests.exceptions.ConnectionError)
|
|
||||||
flexmock(module.logger).should_receive('warning').once()
|
|
||||||
|
|
||||||
module.ping_monitor(
|
|
||||||
hook_config,
|
|
||||||
'config.yaml',
|
|
||||||
module.monitor.State.FAIL,
|
|
||||||
monitoring_log_level=1,
|
|
||||||
dry_run=False,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_ping_monitor_with_other_error_logs_warning():
|
|
||||||
hook_config = {'topic': topic}
|
|
||||||
response = flexmock(ok=False)
|
|
||||||
response.should_receive('raise_for_status').and_raise(
|
|
||||||
module.requests.exceptions.RequestException
|
|
||||||
)
|
|
||||||
flexmock(module.requests).should_receive('post').with_args(
|
|
||||||
f'{default_base_url}/{topic}',
|
|
||||||
headers=return_default_message_headers(module.monitor.State.FAIL),
|
|
||||||
).and_return(response)
|
|
||||||
flexmock(module.logger).should_receive('warning').once()
|
|
||||||
|
|
||||||
module.ping_monitor(
|
|
||||||
hook_config,
|
|
||||||
'config.yaml',
|
|
||||||
module.monitor.State.FAIL,
|
|
||||||
monitoring_log_level=1,
|
|
||||||
dry_run=False,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_ping_monitor_minimal_config_hits_selfhosted_with_custom_auth():
|
|
||||||
hook_config = {
|
|
||||||
'topic': topic,
|
|
||||||
'server': custom_base_url,
|
|
||||||
'username': 'unittesting',
|
|
||||||
'password': 'dummypassword',
|
|
||||||
}
|
|
||||||
expected_headers = {
|
|
||||||
**return_default_message_headers(module.monitor.State.FAIL),
|
|
||||||
'Authorization': 'unittesting:dummypassword',
|
|
||||||
}
|
|
||||||
flexmock(module.requests).should_receive('post').with_args(
|
|
||||||
f'{custom_base_url}/{topic}', headers=expected_headers,
|
|
||||||
).and_return(flexmock(ok=True)).once()
|
|
||||||
|
|
||||||
module.ping_monitor(
|
|
||||||
hook_config, 'config.yaml', module.monitor.State.FAIL, monitoring_log_level=1, dry_run=False
|
|
||||||
)
|
|
|
@ -28,7 +28,7 @@ def test_ping_monitor_ignores_finish_state():
|
||||||
|
|
||||||
|
|
||||||
def test_ping_monitor_calls_api_for_fail_state():
|
def test_ping_monitor_calls_api_for_fail_state():
|
||||||
flexmock(module.requests).should_receive('post').and_return(flexmock(ok=True))
|
flexmock(module.requests).should_receive('post')
|
||||||
|
|
||||||
module.ping_monitor(
|
module.ping_monitor(
|
||||||
{'integration_key': 'abc123'},
|
{'integration_key': 'abc123'},
|
||||||
|
@ -51,27 +51,10 @@ def test_ping_monitor_dry_run_does_not_call_api():
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_ping_monitor_with_connection_error_logs_warning():
|
def test_ping_monitor_with_connection_error_does_not_raise():
|
||||||
flexmock(module.requests).should_receive('post').and_raise(
|
flexmock(module.requests).should_receive('post').and_raise(
|
||||||
module.requests.exceptions.ConnectionError
|
module.requests.exceptions.ConnectionError
|
||||||
)
|
)
|
||||||
flexmock(module.logger).should_receive('warning').once()
|
|
||||||
|
|
||||||
module.ping_monitor(
|
|
||||||
{'integration_key': 'abc123'},
|
|
||||||
'config.yaml',
|
|
||||||
module.monitor.State.FAIL,
|
|
||||||
monitoring_log_level=1,
|
|
||||||
dry_run=False,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_ping_monitor_with_other_error_logs_warning():
|
|
||||||
response = flexmock(ok=False)
|
|
||||||
response.should_receive('raise_for_status').and_raise(
|
|
||||||
module.requests.exceptions.RequestException
|
|
||||||
)
|
|
||||||
flexmock(module.requests).should_receive('post').and_return(response)
|
|
||||||
flexmock(module.logger).should_receive('warning')
|
flexmock(module.logger).should_receive('warning')
|
||||||
|
|
||||||
module.ping_monitor(
|
module.ping_monitor(
|
||||||
|
|
Loading…
Reference in New Issue