mirror of
https://github.com/borgmatic-collective/borgmatic.git
synced 2026-07-24 10:53:02 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9ec75ccf3f | ||
|
|
7c890be76d | ||
|
|
39e5aac479 | ||
|
|
e25f2c4e6c | ||
|
|
7ad8f9ac6f | ||
|
|
2add3ff7ad | ||
|
|
0602ca1862 | ||
|
|
e973802fc1 | ||
|
|
2bdf6dfd70 | ||
|
|
f894c49540 | ||
|
|
7900e5ea53 | ||
|
|
5587f48bda | ||
|
|
de3ee07566 | ||
|
|
fe39453598 | ||
|
|
9c75063c05 | ||
|
|
5cf2ef1732 | ||
|
|
f35e6ea7ad |
@@ -1,3 +1,10 @@
|
||||
1.3.13
|
||||
* #199: Add note to documentation about using spaces instead of tabs for indentation, as YAML does
|
||||
not allow tabs.
|
||||
* #203: Fix compatibility with ruamel.yaml 0.16.x.
|
||||
* If a "prefix" option in borgmatic's configuration has an empty value (blank or ""), then disable
|
||||
default prefix.
|
||||
|
||||
1.3.12
|
||||
* Only log to syslog when run from a non-interactive console (e.g. a cron job).
|
||||
* Remove unicode byte order mark from syslog output so it doesn't show up as a literal in rsyslog
|
||||
|
||||
@@ -64,7 +64,7 @@ href="https://asciinema.org/a/203761" target="_blank">screencast</a>.
|
||||
* [Deal with very large backups](https://torsion.org/borgmatic/docs/how-to/deal-with-very-large-backups/)
|
||||
* [Inspect your backups](https://torsion.org/borgmatic/docs/how-to/inspect-your-backups/)
|
||||
* [Restore a backup](https://torsion.org/borgmatic/docs/how-to/restore-a-backup/)
|
||||
* [Run preparation steps before backups](https://torsion.org/borgmatic/docs/how-to/run-preparation-steps-before-backups/)
|
||||
* [Add preparation and cleanup steps to backups](https://torsion.org/borgmatic/docs/how-to/add-preparation-and-cleanup-steps-to-backups/)
|
||||
* [Upgrade borgmatic](https://torsion.org/borgmatic/docs/how-to/upgrade/)
|
||||
* [Develop on borgmatic](https://torsion.org/borgmatic/docs/how-to/develop-on-borgmatic/)
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ def _make_check_flags(checks, check_last=None, prefix=None):
|
||||
'''
|
||||
if 'archives' in checks:
|
||||
last_flags = ('--last', str(check_last)) if check_last else ()
|
||||
prefix_flags = ('--prefix', prefix) if prefix else ('--prefix', DEFAULT_PREFIX)
|
||||
prefix_flags = ('--prefix', prefix) if prefix else ()
|
||||
else:
|
||||
last_flags = ()
|
||||
prefix_flags = ()
|
||||
@@ -102,7 +102,7 @@ def check_archives(
|
||||
if logger.isEnabledFor(logging.DEBUG):
|
||||
verbosity_flags = ('--debug', '--show-rc')
|
||||
|
||||
prefix = consistency_config.get('prefix')
|
||||
prefix = consistency_config.get('prefix', DEFAULT_PREFIX)
|
||||
|
||||
full_command = (
|
||||
(local_path, 'check', repository)
|
||||
|
||||
@@ -21,12 +21,15 @@ def _make_prune_flags(retention_config):
|
||||
('--keep-monthly', '6'),
|
||||
)
|
||||
'''
|
||||
if not retention_config.get('prefix'):
|
||||
retention_config['prefix'] = '{hostname}-'
|
||||
config = retention_config.copy()
|
||||
|
||||
if 'prefix' not in config:
|
||||
config['prefix'] = '{hostname}-'
|
||||
elif not config['prefix']:
|
||||
config.pop('prefix')
|
||||
|
||||
return (
|
||||
('--' + option_name.replace('_', '-'), str(retention_config[option_name]))
|
||||
for option_name, value in retention_config.items()
|
||||
('--' + option_name.replace('_', '-'), str(value)) for option_name, value in config.items()
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -269,7 +269,7 @@ map:
|
||||
desc: |
|
||||
When pruning, only consider archive names starting with this prefix.
|
||||
Borg placeholders can be used. See the output of "borg help placeholders" for
|
||||
details. Defaults to "{hostname}-".
|
||||
details. Defaults to "{hostname}-". Use an empty value to disable the default.
|
||||
example: sourcehostname
|
||||
consistency:
|
||||
desc: |
|
||||
@@ -311,7 +311,8 @@ map:
|
||||
desc: |
|
||||
When performing the "archives" check, only consider archive names starting with
|
||||
this prefix. Borg placeholders can be used. See the output of
|
||||
"borg help placeholders" for details. Defaults to "{hostname}-".
|
||||
"borg help placeholders" for details. Defaults to "{hostname}-". Use an empty
|
||||
value to disable the default.
|
||||
example: sourcehostname
|
||||
output:
|
||||
desc: |
|
||||
@@ -345,9 +346,11 @@ map:
|
||||
on_error:
|
||||
seq:
|
||||
- type: scalar
|
||||
desc: List of one or more shell commands or scripts to execute in case an exception has occurred.
|
||||
desc: |
|
||||
List of one or more shell commands or scripts to execute when an exception occurs
|
||||
during a backup or when running a hook.
|
||||
example:
|
||||
- echo "Error while creating a backup."
|
||||
- echo "Error while creating a backup or running a hook."
|
||||
umask:
|
||||
type: scalar
|
||||
desc: Umask used when executing hooks. Defaults to the umask that borgmatic is run with.
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
FROM python:3.7.3-alpine3.9 as borgmatic
|
||||
FROM python:3.7.3-alpine3.10 as borgmatic
|
||||
|
||||
COPY . /app
|
||||
RUN pip install --no-cache /app && generate-borgmatic-config && chmod +r /etc/borgmatic/config.yaml
|
||||
@@ -7,7 +7,7 @@ RUN borgmatic --help > /command-line.txt \
|
||||
echo -e "\n--------------------------------------------------------------------------------\n" >> /command-line.txt \
|
||||
&& borgmatic "$action" --help >> /command-line.txt; done
|
||||
|
||||
FROM node:11.15.0-alpine as html
|
||||
FROM node:12.4.0-alpine as html
|
||||
|
||||
WORKDIR /source
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
---
|
||||
title: Add preparation and cleanup steps to backups
|
||||
---
|
||||
## Preparation and cleanup hooks
|
||||
|
||||
If you find yourself performing prepraration tasks before your backup runs, or
|
||||
cleanup work afterwards, borgmatic hooks may be of interest. Hooks are
|
||||
shell commands that borgmatic executes for you at various points, and they're
|
||||
configured in the `hooks` section of your configuration file.
|
||||
|
||||
For instance, you can specify `before_backup` hooks to dump a database to file
|
||||
before backing it up, and specify `after_backup` hooks to delete the temporary
|
||||
file afterwards. Here's an example:
|
||||
|
||||
```yaml
|
||||
hooks:
|
||||
before_backup:
|
||||
- dump-a-database /to/file.sql
|
||||
after_backup:
|
||||
- rm /to/file.sql
|
||||
```
|
||||
|
||||
borgmatic hooks run once per configuration file. `before_backup` hooks run
|
||||
prior to backups of all repositories. `after_backup` hooks run afterwards, but
|
||||
not if an error occurs in a previous hook or in the backups themselves.
|
||||
|
||||
|
||||
## Error hooks
|
||||
|
||||
borgmatic also runs `on_error` hooks if an error occurs, either when creating
|
||||
a backup or running another hook. Here's an example configuration:
|
||||
|
||||
```yaml
|
||||
hooks:
|
||||
on_error:
|
||||
- echo "Error while creating a backup or running a hook."
|
||||
```
|
||||
|
||||
## Hook output
|
||||
|
||||
Any output produced by your hooks shows up both at the console and in syslog
|
||||
(when run in a non-interactive console). For more information, read about <a
|
||||
href="https://torsion.org/borgmatic/docs/how-to/inspect-your-backups.md">inspecting
|
||||
your backups</a>.
|
||||
|
||||
## Security
|
||||
|
||||
An important security note about hooks: borgmatic executes all hook commands
|
||||
with the user permissions of borgmatic itself. So to prevent potential shell
|
||||
injection or privilege escalation, do not forget to set secure permissions
|
||||
(`chmod 0700`) on borgmatic configuration files and scripts invoked by hooks.
|
||||
|
||||
|
||||
## Related documentation
|
||||
|
||||
* [Set up backups with borgmatic](https://torsion.org/borgmatic/docs/how-to/set-up-backups.md)
|
||||
* [Make per-application backups](https://torsion.org/borgmatic/docs/how-to/make-per-application-backups.md)
|
||||
* [Inspect your backups](https://torsion.org/borgmatic/docs/how-to/inspect-your-backups.md)
|
||||
@@ -1,58 +1,3 @@
|
||||
---
|
||||
title: How to run preparation steps before backups
|
||||
---
|
||||
## Preparation and cleanup hooks
|
||||
|
||||
If you find yourself performing prepraration tasks before your backup runs, or
|
||||
cleanup work afterwards, borgmatic hooks may be of interest. Hooks are
|
||||
shell commands that borgmatic executes for you at various points, and they're
|
||||
configured in the `hooks` section of your configuration file.
|
||||
|
||||
For instance, you can specify `before_backup` hooks to dump a database to file
|
||||
before backing it up, and specify `after_backup` hooks to delete the temporary
|
||||
file afterwards. Here's an example:
|
||||
|
||||
```yaml
|
||||
hooks:
|
||||
before_backup:
|
||||
- dump-a-database /to/file.sql
|
||||
after_backup:
|
||||
- rm /to/file.sql
|
||||
```
|
||||
|
||||
borgmatic hooks run once per configuration file. `before_backup` hooks run
|
||||
prior to backups of all repositories. `after_backup` hooks run afterwards, but
|
||||
not if an error occurs in a previous hook or in the backups themselves.
|
||||
|
||||
|
||||
## Error hooks
|
||||
|
||||
borgmatic also runs `on_error` hooks if an error occurs. Here's an example
|
||||
configuration:
|
||||
|
||||
```yaml
|
||||
hooks:
|
||||
on_error:
|
||||
- echo "Error while creating a backup."
|
||||
```
|
||||
|
||||
## Hook output
|
||||
|
||||
Any output produced by your hooks shows up both at the console and in syslog
|
||||
(when run in a non-interactive console). For more information, read about <a
|
||||
href="https://torsion.org/borgmatic/docs/how-to/inspect-your-backups.md">inspecting
|
||||
your backups</a>.
|
||||
|
||||
## Security
|
||||
|
||||
An important security note about hooks: borgmatic executes all hook commands
|
||||
with the user permissions of borgmatic itself. So to prevent potential shell
|
||||
injection or privilege escalation, do not forget to set secure permissions
|
||||
(`chmod 0700`) on borgmatic configuration files and scripts invoked by hooks.
|
||||
|
||||
|
||||
## Related documentation
|
||||
|
||||
* [Set up backups with borgmatic](https://torsion.org/borgmatic/docs/how-to/set-up-backups.md)
|
||||
* [Make per-application backups](https://torsion.org/borgmatic/docs/how-to/make-per-application-backups.md)
|
||||
* [Inspect your backups](https://torsion.org/borgmatic/docs/how-to/inspect-your-backups.md)
|
||||
<head>
|
||||
<meta http-equiv='refresh' content='0; URL=https://torsion.org/borgmatic/docs/how-to/add-preparation-and-cleanup-steps-to-backups/'>
|
||||
</head>
|
||||
|
||||
@@ -38,6 +38,7 @@ borgmatic:
|
||||
* [Arch Linux](https://aur.archlinux.org/packages/borgmatic/)
|
||||
* [OpenBSD](http://ports.su/sysutils/borgmatic)
|
||||
* [openSUSE](https://software.opensuse.org/package/borgmatic)
|
||||
* [stand-alone binary](https://github.com/cmarquardt/borgmatic-binary)
|
||||
|
||||
|
||||
## Hosting providers
|
||||
@@ -71,7 +72,8 @@ to ignore anything you don't need.
|
||||
Note that the configuration file is organized into distinct sections, each
|
||||
with a section name like `location:` or `storage:`. So take care that if you
|
||||
uncomment a particular option, also uncomment its containing section name, or
|
||||
else borgmatic won't recognize the option.
|
||||
else borgmatic won't recognize the option. Also be sure to use spaces rather
|
||||
than tabs for indentation; YAML does not allow tabs.
|
||||
|
||||
You can also get the same sample configuration file from the [configuration
|
||||
reference](https://torsion.org/borgmatic/docs/reference/configuration.md), the authoritative set of
|
||||
@@ -212,6 +214,22 @@ section of configuration.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "found character that cannot start any token" error
|
||||
|
||||
If you run borgmatic and see an error looking something like this, it probably
|
||||
means you've used tabs instead of spaces:
|
||||
|
||||
```
|
||||
test.yaml: Error parsing configuration file
|
||||
An error occurred while parsing a configuration file at config.yaml:
|
||||
while scanning for the next token
|
||||
found character that cannot start any token
|
||||
in "config.yaml", line 230, column 1
|
||||
```
|
||||
|
||||
YAML does not allow tabs. So to fix this, simply replace any tabs in your
|
||||
configuration file with the requisite number of spaces.
|
||||
|
||||
### libyaml compilation errors
|
||||
|
||||
borgmatic depends on a Python YAML library (ruamel.yaml) that will optionally
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from setuptools import find_packages, setup
|
||||
|
||||
VERSION = '1.3.12'
|
||||
VERSION = '1.3.13'
|
||||
|
||||
|
||||
setup(
|
||||
@@ -31,7 +31,7 @@ setup(
|
||||
obsoletes=['atticmatic'],
|
||||
install_requires=(
|
||||
'pykwalify>=1.6.0,<14.06',
|
||||
'ruamel.yaml>0.15.0,<0.16.0',
|
||||
'ruamel.yaml>0.15.0,<0.17.0',
|
||||
'setuptools',
|
||||
'colorama>=0.4.1,<0.5',
|
||||
),
|
||||
|
||||
@@ -20,5 +20,5 @@ pytest==4.6.3
|
||||
pytest-cov==2.7.1
|
||||
python-dateutil==2.8.0
|
||||
PyYAML==5.1.1
|
||||
ruamel.yaml>0.15.0,<0.16.0
|
||||
ruamel.yaml>0.15.0,<0.17.0
|
||||
toml==0.10.0
|
||||
|
||||
@@ -52,14 +52,16 @@ def test_make_check_flags_with_extract_omits_extract_flag():
|
||||
assert flags == ()
|
||||
|
||||
|
||||
def test_make_check_flags_with_default_checks_returns_default_flags():
|
||||
flags = module._make_check_flags(module.DEFAULT_CHECKS)
|
||||
def test_make_check_flags_with_default_checks_and_default_prefix_returns_default_flags():
|
||||
flags = module._make_check_flags(module.DEFAULT_CHECKS, prefix=module.DEFAULT_PREFIX)
|
||||
|
||||
assert flags == ('--prefix', module.DEFAULT_PREFIX)
|
||||
|
||||
|
||||
def test_make_check_flags_with_all_checks_returns_default_flags():
|
||||
flags = module._make_check_flags(module.DEFAULT_CHECKS + ('extract',))
|
||||
def test_make_check_flags_with_all_checks_and_default_prefix_returns_default_flags():
|
||||
flags = module._make_check_flags(
|
||||
module.DEFAULT_CHECKS + ('extract',), prefix=module.DEFAULT_PREFIX
|
||||
)
|
||||
|
||||
assert flags == ('--prefix', module.DEFAULT_PREFIX)
|
||||
|
||||
@@ -67,7 +69,7 @@ def test_make_check_flags_with_all_checks_returns_default_flags():
|
||||
def test_make_check_flags_with_archives_check_and_last_includes_last_flag():
|
||||
flags = module._make_check_flags(('archives',), check_last=3)
|
||||
|
||||
assert flags == ('--archives-only', '--last', '3', '--prefix', module.DEFAULT_PREFIX)
|
||||
assert flags == ('--archives-only', '--last', '3')
|
||||
|
||||
|
||||
def test_make_check_flags_with_repository_check_and_last_omits_last_flag():
|
||||
@@ -79,7 +81,7 @@ def test_make_check_flags_with_repository_check_and_last_omits_last_flag():
|
||||
def test_make_check_flags_with_default_checks_and_last_includes_last_flag():
|
||||
flags = module._make_check_flags(module.DEFAULT_CHECKS, check_last=3)
|
||||
|
||||
assert flags == ('--last', '3', '--prefix', module.DEFAULT_PREFIX)
|
||||
assert flags == ('--last', '3')
|
||||
|
||||
|
||||
def test_make_check_flags_with_archives_check_and_prefix_includes_prefix_flag():
|
||||
@@ -88,6 +90,18 @@ def test_make_check_flags_with_archives_check_and_prefix_includes_prefix_flag():
|
||||
assert flags == ('--archives-only', '--prefix', 'foo-')
|
||||
|
||||
|
||||
def test_make_check_flags_with_archives_check_and_empty_prefix_omits_prefix_flag():
|
||||
flags = module._make_check_flags(('archives',), prefix='')
|
||||
|
||||
assert flags == ('--archives-only',)
|
||||
|
||||
|
||||
def test_make_check_flags_with_archives_check_and_none_prefix_omits_prefix_flag():
|
||||
flags = module._make_check_flags(('archives',), prefix=None)
|
||||
|
||||
assert flags == ('--archives-only',)
|
||||
|
||||
|
||||
def test_make_check_flags_with_repository_check_and_prefix_omits_prefix_flag():
|
||||
flags = module._make_check_flags(('repository',), prefix='foo-')
|
||||
|
||||
@@ -114,7 +128,7 @@ def test_check_archives_calls_borg_with_parameters(checks):
|
||||
consistency_config = {'check_last': check_last}
|
||||
flexmock(module).should_receive('_parse_checks').and_return(checks)
|
||||
flexmock(module).should_receive('_make_check_flags').with_args(
|
||||
checks, check_last, None
|
||||
checks, check_last, module.DEFAULT_PREFIX
|
||||
).and_return(())
|
||||
insert_execute_command_mock(('borg', 'check', 'repo'))
|
||||
|
||||
@@ -179,7 +193,7 @@ def test_check_archives_with_local_path_calls_borg_via_local_path():
|
||||
consistency_config = {'check_last': check_last}
|
||||
flexmock(module).should_receive('_parse_checks').and_return(checks)
|
||||
flexmock(module).should_receive('_make_check_flags').with_args(
|
||||
checks, check_last, None
|
||||
checks, check_last, module.DEFAULT_PREFIX
|
||||
).and_return(())
|
||||
insert_execute_command_mock(('borg1', 'check', 'repo'))
|
||||
|
||||
@@ -197,7 +211,7 @@ def test_check_archives_with_remote_path_calls_borg_with_remote_path_parameters(
|
||||
consistency_config = {'check_last': check_last}
|
||||
flexmock(module).should_receive('_parse_checks').and_return(checks)
|
||||
flexmock(module).should_receive('_make_check_flags').with_args(
|
||||
checks, check_last, None
|
||||
checks, check_last, module.DEFAULT_PREFIX
|
||||
).and_return(())
|
||||
insert_execute_command_mock(('borg', 'check', 'repo', '--remote-path', 'borg1'))
|
||||
|
||||
@@ -215,7 +229,7 @@ def test_check_archives_with_lock_wait_calls_borg_with_lock_wait_parameters():
|
||||
consistency_config = {'check_last': check_last}
|
||||
flexmock(module).should_receive('_parse_checks').and_return(checks)
|
||||
flexmock(module).should_receive('_make_check_flags').with_args(
|
||||
checks, check_last, None
|
||||
checks, check_last, module.DEFAULT_PREFIX
|
||||
).and_return(())
|
||||
insert_execute_command_mock(('borg', 'check', 'repo', '--lock-wait', '5'))
|
||||
|
||||
|
||||
@@ -33,6 +33,26 @@ def test_make_prune_flags_accepts_prefix_with_placeholders():
|
||||
assert tuple(result) == expected
|
||||
|
||||
|
||||
def test_make_prune_flags_treats_empty_prefix_as_no_prefix():
|
||||
retention_config = OrderedDict((('keep_daily', 1), ('prefix', '')))
|
||||
|
||||
result = module._make_prune_flags(retention_config)
|
||||
|
||||
expected = (('--keep-daily', '1'),)
|
||||
|
||||
assert tuple(result) == expected
|
||||
|
||||
|
||||
def test_make_prune_flags_treats_none_prefix_as_no_prefix():
|
||||
retention_config = OrderedDict((('keep_daily', 1), ('prefix', None)))
|
||||
|
||||
result = module._make_prune_flags(retention_config)
|
||||
|
||||
expected = (('--keep-daily', '1'),)
|
||||
|
||||
assert tuple(result) == expected
|
||||
|
||||
|
||||
PRUNE_COMMAND = (
|
||||
'borg',
|
||||
'prune',
|
||||
|
||||
Reference in New Issue
Block a user