mirror of
https://github.com/borgmatic-collective/borgmatic.git
synced 2026-07-22 02:03:01 +02:00
BREAKING: Treat most Borg warnings as errors by default and deprecate the "source_directories_must_exist" option (#1092).
This commit is contained in:
@@ -3,6 +3,12 @@
|
||||
* #485: When running commands (database clients, command hooks, etc.), elevate stderr output to
|
||||
show up as borgmatic error logs.
|
||||
* #858: With the "--log-json" flag, log borgmatic's own logs as JSON, not just Borg's.
|
||||
* #1092: BREAKING: Treat most Borg warnings as errors by default, so for instance backups now fail
|
||||
when source directories are missing. You can still override this behavior with the
|
||||
"borg_exit_codes" option. See the documentation for more information:
|
||||
https://torsion.org/borgmatic/how-to/customize-warnings-and-errors/
|
||||
* #1092: Deprecate the "source_directories_must_exist" option, as borgmatic now treats "backup file
|
||||
not found" warnings from Borg as errors, which accomplishes the same thing.
|
||||
* #1132: BREAKING/SECURITY: For the Healthchecks, Apprise, Pagerduty, and Loki monitoring hooks,
|
||||
disable log sending when not explicitly enabled. This avoids revealing private log information to
|
||||
third-party services. To send logs anyway, set the monitoring hook's "send_logs" option to
|
||||
|
||||
@@ -180,6 +180,9 @@ def make_base_create_command( # noqa: PLR0912
|
||||
open pattern file handle).
|
||||
'''
|
||||
if config.get('source_directories_must_exist', False):
|
||||
logger.warning(
|
||||
'The "source_directories_must_exist" option is deprecated and will be removed from a future release; borgmatic now errors on missing files as Borg runs'
|
||||
)
|
||||
borgmatic.borg.pattern.check_all_root_patterns_exist(patterns)
|
||||
|
||||
patterns_file = borgmatic.borg.pattern.write_patterns_file(
|
||||
|
||||
@@ -21,11 +21,7 @@ properties:
|
||||
type: string
|
||||
description: |
|
||||
List of source directories and files to back up. Globs and tildes
|
||||
are expanded. Do not backslash spaces in path names. Be aware that
|
||||
by default, Borg treats missing source directories as warnings
|
||||
rather than errors. If you'd like to change that behavior, see
|
||||
https://torsion.org/borgmatic/how-to/customize-warnings-and-errors/
|
||||
or the "source_directories_must_exist" option.
|
||||
are expanded. Do not backslash spaces in path names.
|
||||
example:
|
||||
- /home
|
||||
- /etc
|
||||
@@ -34,8 +30,11 @@ properties:
|
||||
source_directories_must_exist:
|
||||
type: boolean
|
||||
description: |
|
||||
If true, then source directories (and root pattern paths) must
|
||||
exist. If they don't, an error is raised. Defaults to false.
|
||||
Deprecated. Replaced by borgmatic treating Borg's "backup file not
|
||||
found" warning as an error by default. But if
|
||||
"source_directories_must_exist" is true, then source directories
|
||||
(and root pattern paths) must exist before a backup begins. If they
|
||||
don't, borgmatic errors. Defaults to false.
|
||||
example: true
|
||||
repositories:
|
||||
type: array
|
||||
@@ -468,9 +467,9 @@ properties:
|
||||
description: |
|
||||
A list of Borg exit codes that should be elevated to errors or
|
||||
squashed to warnings as indicated. By default, Borg error exit codes
|
||||
(2 to 99) are treated as errors while warning exit codes (1 and
|
||||
100+) are treated as warnings. Exit codes other than 1 and 2 are
|
||||
only present in Borg 1.4.0+.
|
||||
(2 to 99) are treated as errors and most warning exit codes (1 and
|
||||
100+) are treated as errors as well. Exit codes other than 1 and 2
|
||||
are only present in Borg 1.4.0+.
|
||||
example:
|
||||
- code: 13
|
||||
treat_as: warning
|
||||
|
||||
+13
-3
@@ -16,6 +16,9 @@ ERROR_OUTPUT_MAX_LINE_COUNT = 25
|
||||
BORG_ERROR_EXIT_CODE_START = 2
|
||||
BORG_ERROR_EXIT_CODE_END = 99
|
||||
|
||||
# See https://borgbackup.readthedocs.io/en/stable/internals/frontends.html#message-ids
|
||||
BORG_WARNING_EXIT_CODES_TREATED_AS_ERRORS = {101, 102, 104, 105, 106, 107}
|
||||
|
||||
|
||||
class Exit_status(enum.Enum):
|
||||
STILL_RUNNING = 1
|
||||
@@ -24,7 +27,7 @@ class Exit_status(enum.Enum):
|
||||
ERROR = 4
|
||||
|
||||
|
||||
def interpret_exit_code(command, exit_code, borg_local_path=None, borg_exit_codes=None):
|
||||
def interpret_exit_code(command, exit_code, borg_local_path=None, borg_exit_codes=None): # noqa: PLR0911
|
||||
'''
|
||||
Return an Exit_status value (e.g. SUCCESS, ERROR, or WARNING) based on interpreting the given
|
||||
exit code. If a Borg local path is given and matches the process' command, then interpret the
|
||||
@@ -55,8 +58,15 @@ def interpret_exit_code(command, exit_code, borg_local_path=None, borg_exit_code
|
||||
)
|
||||
return Exit_status.WARNING
|
||||
|
||||
# If the exit code doesn't have explicit configuration, then fall back to the default Borg
|
||||
# behavior.
|
||||
# If the exit code doesn't have explicit configuration, then fall back to the default
|
||||
# behavior of treating Borg errors as errors and some Borg warnings as errors.
|
||||
if exit_code in BORG_WARNING_EXIT_CODES_TREATED_AS_ERRORS:
|
||||
logger.error(
|
||||
f'Treating exit code {exit_code} as an error, as per borgmatic defaults',
|
||||
)
|
||||
|
||||
return Exit_status.ERROR
|
||||
|
||||
return (
|
||||
Exit_status.ERROR
|
||||
if (
|
||||
|
||||
@@ -5,40 +5,44 @@ eleventyNavigation:
|
||||
parent: How-to guides
|
||||
order: 13
|
||||
---
|
||||
After Borg runs, it indicates whether it succeeded via its exit code, a
|
||||
numeric ID indicating success, warning, or error. borgmatic consumes this exit
|
||||
code to decide how to respond. Normally, a Borg error results in a borgmatic
|
||||
error, while a Borg warning or success doesn't.
|
||||
|
||||
After Borg runs, it indicates whether it succeeded via its exit code, a numeric
|
||||
ID indicating success, warning, or error. borgmatic consumes this exit code to
|
||||
decide how to respond. By default, Borg errors (and some warnings) result
|
||||
in a borgmatic error, while Borg successes don't.
|
||||
|
||||
<span class="minilink minilink-addedin">New in borgmatic version 2.1.0</span>
|
||||
borgmatic elevates most Borg warnings to errors by default. For instance, if a
|
||||
source directory is missing during backup, Borg indicates that with a warning
|
||||
exit code (`107`). And starting in borgmatic 2.1.0, that exit code is considered
|
||||
an error, so you'll actually find out about missing files.
|
||||
|
||||
<span class="minilink minilink-addedin">With Borg version 1.4+</span> If the
|
||||
default behavior isn't sufficient for your needs, you can customize how
|
||||
borgmatic interprets [Borg's exit
|
||||
codes](https://borgbackup.readthedocs.io/en/stable/usage/general.html#return-codes).
|
||||
codes](https://borgbackup.readthedocs.io/en/stable/internals/frontends.html#message-ids).
|
||||
|
||||
For instance, this borgmatic configuration elevates all Borg backup file
|
||||
permission warnings (exit code `105`)—and only those warnings—to errors:
|
||||
For instance, this borgmatic configuration elevates a Borg warning about source files
|
||||
changes during backup (exit code `100`)—and only those warnings—to
|
||||
errors:
|
||||
|
||||
```yaml
|
||||
borg_exit_codes:
|
||||
- code: 105
|
||||
- code: 100
|
||||
treat_as: error
|
||||
```
|
||||
|
||||
The following configuration does that *and* elevates backup file not found
|
||||
warnings (exit code `107`) to errors as well:
|
||||
The following configuration does that *and* treats Borg's backup file not found
|
||||
(exit code `107`) as a warning:
|
||||
|
||||
```yaml
|
||||
borg_exit_codes:
|
||||
- code: 105
|
||||
- code: 100
|
||||
treat_as: error
|
||||
- code: 107
|
||||
treat_as: error
|
||||
treat_as: warning
|
||||
```
|
||||
|
||||
See the full list of [Borg 1.4 error and warning exit
|
||||
codes](https://borgbackup.readthedocs.io/en/stable/internals/frontends.html#message-ids).
|
||||
The `rc:` numeric value there tells you the exit code for each.
|
||||
|
||||
If you don't know the exit code for a particular Borg error or warning you're
|
||||
experiencing, you can usually find it in your borgmatic output when `--verbosity
|
||||
2` is enabled. For instance, here's a snippet of that output when a backup file
|
||||
@@ -50,8 +54,8 @@ is not found:
|
||||
terminating with warning status, rc 107
|
||||
```
|
||||
|
||||
So if you want to configure borgmatic to treat this as an error instead of a
|
||||
warning, the exit status to use is `107`.
|
||||
So if you want to configure borgmatic to treat this as an warning instead of an
|
||||
error, the exit status to use is `107`.
|
||||
|
||||
<span class="minilink minilink-addedin">With Borg version 1.2 and earlier</span>
|
||||
Older versions of Borg didn't support granular exit codes, but still
|
||||
@@ -67,15 +71,4 @@ borg_exit_codes:
|
||||
|
||||
Be aware though that Borg exits with a warning code for a variety of benign
|
||||
situations such as files changing while they're being read, so this example
|
||||
may not meet your needs.
|
||||
|
||||
Here's another Borg 1.2 example that squashes Borg errors to warnings:
|
||||
|
||||
```yaml
|
||||
borg_exit_codes:
|
||||
- code: 2
|
||||
treat_as: warning
|
||||
```
|
||||
|
||||
Be careful with this example though, because it prevents borgmatic from
|
||||
erroring when Borg errors, which may not be desirable.
|
||||
may not meet your needs. Upgrading to Borg 1.4+ is recommended.
|
||||
|
||||
@@ -40,7 +40,22 @@ from borgmatic import execute as module
|
||||
(['borg'], 2, 'borg', [{'code': 99, 'treat_as': 'warning'}], module.Exit_status.ERROR),
|
||||
(['borg'], 2, 'borg', [{'code': 2, 'treat_as': 'warning'}], module.Exit_status.WARNING),
|
||||
(['borg'], 100, 'borg', [{'code': 1, 'treat_as': 'error'}], module.Exit_status.WARNING),
|
||||
(['borg'], 100, 'borg', [], module.Exit_status.WARNING),
|
||||
(['borg'], 100, 'borg', [{'code': 100, 'treat_as': 'error'}], module.Exit_status.ERROR),
|
||||
(['borg'], 101, 'borg', [], module.Exit_status.ERROR),
|
||||
(['borg'], 101, 'borg', [{'code': 101, 'treat_as': 'warning'}], module.Exit_status.WARNING),
|
||||
(['borg'], 102, 'borg', [], module.Exit_status.ERROR),
|
||||
(['borg'], 102, 'borg', [{'code': 102, 'treat_as': 'warning'}], module.Exit_status.WARNING),
|
||||
(['borg'], 103, 'borg', [], module.Exit_status.WARNING),
|
||||
(['borg'], 103, 'borg', [{'code': 103, 'treat_as': 'error'}], module.Exit_status.ERROR),
|
||||
(['borg'], 104, 'borg', [], module.Exit_status.ERROR),
|
||||
(['borg'], 104, 'borg', [{'code': 104, 'treat_as': 'warning'}], module.Exit_status.WARNING),
|
||||
(['borg'], 105, 'borg', [], module.Exit_status.ERROR),
|
||||
(['borg'], 105, 'borg', [{'code': 105, 'treat_as': 'warning'}], module.Exit_status.WARNING),
|
||||
(['borg'], 106, 'borg', [], module.Exit_status.ERROR),
|
||||
(['borg'], 106, 'borg', [{'code': 106, 'treat_as': 'warning'}], module.Exit_status.WARNING),
|
||||
(['borg'], 107, 'borg', [], module.Exit_status.ERROR),
|
||||
(['borg'], 107, 'borg', [{'code': 107, 'treat_as': 'warning'}], module.Exit_status.WARNING),
|
||||
),
|
||||
)
|
||||
def test_interpret_exit_code_respects_exit_code_and_borg_local_path(
|
||||
|
||||
Reference in New Issue
Block a user