Add per-action hooks: "before_prune", "after_prune", "before_check", and "after_check" (#255).

This commit is contained in:
Dan Helfman 2020-01-27 11:07:07 -08:00
parent b15c9b7dab
commit 8ad8a9c422
6 changed files with 80 additions and 9 deletions

3
NEWS
View file

@ -1,4 +1,5 @@
1.4.23.dev0 1.5.0
* #255: Add per-action hooks: "before_prune", "after_prune", "before_check", and "after_check".
* #274: Add ~/.config/borgmatic.d as another configuration directory default. * #274: Add ~/.config/borgmatic.d as another configuration directory default.
* #277: Customize Healthchecks log level via borgmatic "--monitoring-verbosity" flag. * #277: Customize Healthchecks log level via borgmatic "--monitoring-verbosity" flag.
* #280: Change "exclude_if_present" option to support multiple filenames that indicate a directory * #280: Change "exclude_if_present" option to support multiple filenames that indicate a directory

View file

@ -66,6 +66,14 @@ def run_configuration(config_filename, config, arguments):
monitoring_log_level, monitoring_log_level,
global_arguments.dry_run, global_arguments.dry_run,
) )
if 'prune' in arguments:
command.execute_hook(
hooks.get('before_prune'),
hooks.get('umask'),
config_filename,
'pre-prune',
global_arguments.dry_run,
)
if 'create' in arguments: if 'create' in arguments:
command.execute_hook( command.execute_hook(
hooks.get('before_backup'), hooks.get('before_backup'),
@ -82,13 +90,21 @@ def run_configuration(config_filename, config, arguments):
location, location,
global_arguments.dry_run, global_arguments.dry_run,
) )
if 'check' in arguments:
command.execute_hook(
hooks.get('before_check'),
hooks.get('umask'),
config_filename,
'pre-check',
global_arguments.dry_run,
)
except (OSError, CalledProcessError) as error: except (OSError, CalledProcessError) as error:
if command.considered_soft_failure(config_filename, error): if command.considered_soft_failure(config_filename, error):
return return
encountered_error = error encountered_error = error
yield from make_error_log_records( yield from make_error_log_records(
'{}: Error running pre-backup hook'.format(config_filename), error '{}: Error running pre hook'.format(config_filename), error
) )
if not encountered_error: if not encountered_error:
@ -114,6 +130,14 @@ def run_configuration(config_filename, config, arguments):
if not encountered_error: if not encountered_error:
try: try:
if 'prune' in arguments:
command.execute_hook(
hooks.get('after_prune'),
hooks.get('umask'),
config_filename,
'post-prune',
global_arguments.dry_run,
)
if 'create' in arguments: if 'create' in arguments:
dispatch.call_hooks( dispatch.call_hooks(
'remove_database_dumps', 'remove_database_dumps',
@ -130,6 +154,14 @@ def run_configuration(config_filename, config, arguments):
'post-backup', 'post-backup',
global_arguments.dry_run, global_arguments.dry_run,
) )
if 'check' in arguments:
command.execute_hook(
hooks.get('after_check'),
hooks.get('umask'),
config_filename,
'post-check',
global_arguments.dry_run,
)
if {'prune', 'create', 'check'}.intersection(arguments): if {'prune', 'create', 'check'}.intersection(arguments):
dispatch.call_hooks( dispatch.call_hooks(
'ping_monitor', 'ping_monitor',
@ -146,7 +178,7 @@ def run_configuration(config_filename, config, arguments):
encountered_error = error encountered_error = error
yield from make_error_log_records( yield from make_error_log_records(
'{}: Error running post-backup hook'.format(config_filename), error '{}: Error running post hook'.format(config_filename), error
) )
if encountered_error and prune_create_or_check: if encountered_error and prune_create_or_check:

View file

@ -395,6 +395,22 @@ map:
backup, run once per configuration file. backup, run once per configuration file.
example: example:
- echo "Starting a backup." - echo "Starting a backup."
before_prune:
seq:
- type: str
desc: |
List of one or more shell commands or scripts to execute before pruning, run
once per configuration file.
example:
- echo "Starting pruning."
before_check:
seq:
- type: str
desc: |
List of one or more shell commands or scripts to execute before consistency
checks, run once per configuration file.
example:
- echo "Starting checks."
after_backup: after_backup:
seq: seq:
- type: str - type: str
@ -402,15 +418,32 @@ map:
List of one or more shell commands or scripts to execute after creating a List of one or more shell commands or scripts to execute after creating a
backup, run once per configuration file. backup, run once per configuration file.
example: example:
- echo "Created a backup." - echo "Finished a backup."
after_prune:
seq:
- type: str
desc: |
List of one or more shell commands or scripts to execute after pruning, run once
per configuration file.
example:
- echo "Finished pruning."
after_check:
seq:
- type: str
desc: |
List of one or more shell commands or scripts to execute after consistency
checks, run once per configuration file.
example:
- echo "Finished checks."
on_error: on_error:
seq: seq:
- type: str - type: str
desc: | desc: |
List of one or more shell commands or scripts to execute when an exception List of one or more shell commands or scripts to execute when an exception
occurs during a backup or when running a before_backup or after_backup hook. occurs during a "prune", "create", or "check" action or an associated
before/after hook.
example: example:
- echo "Error while creating a backup or running a backup hook." - echo "Error during prune/create/check."
postgresql_databases: postgresql_databases:
seq: seq:
- map: - map:

View file

@ -29,6 +29,10 @@ configuration file, right before the `create` action. `after_backup` hooks run
afterwards, but not if an error occurs in a previous hook or in the backups afterwards, but not if an error occurs in a previous hook or in the backups
themselves. themselves.
There are additional hooks for the `prune` and `check` actions as well.
`before_prune` and `after_prune` run if there are any `prune` actions, while
`before_check` and `after_check` run if there are any `check` actions.
You can also use `before_everything` and `after_everything` hooks to perform You can also use `before_everything` and `after_everything` hooks to perform
global setup or cleanup: global setup or cleanup:

View file

@ -95,8 +95,9 @@ There are some caveats you should be aware of with this feature.
* The soft failure doesn't have to apply to a repository. You can even perform * The soft failure doesn't have to apply to a repository. You can even perform
a test to make sure that individual source directories are mounted and a test to make sure that individual source directories are mounted and
available. Use your imagination! available. Use your imagination!
* This feature does not apply to `before_everything` or `after_everything` * The soft failure feature also works for `before_prune`, `after_prune`,
hooks. `before_check`, and `after_check` hooks. However it is not implemented for
`before_everything` or `after_everything`.
## Related documentation ## Related documentation

View file

@ -1,6 +1,6 @@
from setuptools import find_packages, setup from setuptools import find_packages, setup
VERSION = '1.4.23.dev0' VERSION = '1.5.0'
setup( setup(