diff --git a/borgmatic/commands/borgmatic.py b/borgmatic/commands/borgmatic.py index b39668ad..3115bc41 100644 --- a/borgmatic/commands/borgmatic.py +++ b/borgmatic/commands/borgmatic.py @@ -1,4 +1,5 @@ import collections +import fcntl import json import logging import os @@ -54,37 +55,48 @@ def run_configuration(config_filename, config, arguments): error_repository = '' prune_create_or_check = {'prune', 'create', 'check'}.intersection(arguments) - try: - if prune_create_or_check: - dispatch.call_hooks( - 'ping_monitor', - hooks, - config_filename, - monitor.MONITOR_HOOK_NAMES, - monitor.State.START, - global_arguments.dry_run, + if location.get("lock_client", False): + lock_f = open(config_filename) + try: + fcntl.flock(lock_f.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB) + except IOError as error: + encountered_error = error + yield from make_error_log_records( + '{}: Failed to acquire lock'.format(config_filename), error ) - if 'create' in arguments: - command.execute_hook( - hooks.get('before_backup'), - hooks.get('umask'), - config_filename, - 'pre-backup', - global_arguments.dry_run, + + if not encountered_error: + try: + if prune_create_or_check: + dispatch.call_hooks( + 'ping_monitor', + hooks, + config_filename, + monitor.MONITOR_HOOK_NAMES, + monitor.State.START, + global_arguments.dry_run, + ) + if 'create' in arguments: + command.execute_hook( + hooks.get('before_backup'), + hooks.get('umask'), + config_filename, + 'pre-backup', + global_arguments.dry_run, + ) + dispatch.call_hooks( + 'dump_databases', + hooks, + config_filename, + dump.DATABASE_HOOK_NAMES, + location, + global_arguments.dry_run, + ) + except (OSError, CalledProcessError) as error: + encountered_error = error + yield from make_error_log_records( + '{}: Error running pre-backup hook'.format(config_filename), error ) - dispatch.call_hooks( - 'dump_databases', - hooks, - config_filename, - dump.DATABASE_HOOK_NAMES, - location, - global_arguments.dry_run, - ) - except (OSError, CalledProcessError) as error: - encountered_error = error - yield from make_error_log_records( - '{}: Error running pre-backup hook'.format(config_filename), error - ) if not encountered_error: for repository_path in location['repositories']: diff --git a/borgmatic/config/schema.yaml b/borgmatic/config/schema.yaml index c58ebdec..d541065c 100644 --- a/borgmatic/config/schema.yaml +++ b/borgmatic/config/schema.yaml @@ -32,6 +32,10 @@ map: type: bool desc: Stay in same file system (do not cross mount points). Defaults to false. example: true + lock_client: + type: bool + desc: Lock config when running borgmatic to prevent multiple instances from running simultaneously. Defaults to false. + example: true numeric_owner: type: bool desc: Only store/extract numeric user and group identifiers. Defaults to false.