Fix "borgmatic umount" so it only runs Borg once instead of once per repository / configuration file.
This commit is contained in:
parent
65cc4c9429
commit
b94999bba4
3 changed files with 47 additions and 7 deletions
2
NEWS
2
NEWS
|
@ -1,5 +1,7 @@
|
||||||
1.4.18
|
1.4.18
|
||||||
* Fix "--repository" flag to accept relative paths.
|
* Fix "--repository" flag to accept relative paths.
|
||||||
|
* Fix "borgmatic umount" so it only runs Borg once instead of once per repository / configuration
|
||||||
|
file.
|
||||||
* #253: Mount whole repositories via "borgmatic mount" without any "--archive" flag.
|
* #253: Mount whole repositories via "borgmatic mount" without any "--archive" flag.
|
||||||
|
|
||||||
1.4.17
|
1.4.17
|
||||||
|
|
|
@ -274,13 +274,6 @@ def run_actions(
|
||||||
local_path=local_path,
|
local_path=local_path,
|
||||||
remote_path=remote_path,
|
remote_path=remote_path,
|
||||||
)
|
)
|
||||||
if 'umount' in arguments:
|
|
||||||
logger.info(
|
|
||||||
'{}: Unmounting mount point {}'.format(repository, arguments['umount'].mount_point)
|
|
||||||
)
|
|
||||||
borg_umount.unmount_archive(
|
|
||||||
mount_point=arguments['umount'].mount_point, local_path=local_path
|
|
||||||
)
|
|
||||||
if 'restore' in arguments:
|
if 'restore' in arguments:
|
||||||
if arguments['restore'].repository is None or validate.repositories_match(
|
if arguments['restore'].repository is None or validate.repositories_match(
|
||||||
repository, arguments['restore'].repository
|
repository, arguments['restore'].repository
|
||||||
|
@ -447,6 +440,14 @@ def make_error_log_records(message, error=None):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def get_local_path(configs):
|
||||||
|
'''
|
||||||
|
Arbitrarily return the local path from the first configuration dict. Default to "borg" if not
|
||||||
|
set.
|
||||||
|
'''
|
||||||
|
return next(iter(configs.values())).get('location', {}).get('local_path', 'borg')
|
||||||
|
|
||||||
|
|
||||||
def collect_configuration_run_summary_logs(configs, arguments):
|
def collect_configuration_run_summary_logs(configs, arguments):
|
||||||
'''
|
'''
|
||||||
Given a dict of configuration filename to corresponding parsed configuration, and parsed
|
Given a dict of configuration filename to corresponding parsed configuration, and parsed
|
||||||
|
@ -517,6 +518,15 @@ def collect_configuration_run_summary_logs(configs, arguments):
|
||||||
if results:
|
if results:
|
||||||
json_results.extend(results)
|
json_results.extend(results)
|
||||||
|
|
||||||
|
if 'umount' in arguments:
|
||||||
|
logger.info('Unmounting mount point {}'.format(arguments['umount'].mount_point))
|
||||||
|
try:
|
||||||
|
borg_umount.unmount_archive(
|
||||||
|
mount_point=arguments['umount'].mount_point, local_path=get_local_path(configs)
|
||||||
|
)
|
||||||
|
except (CalledProcessError, OSError) as error:
|
||||||
|
yield from make_error_log_records('Error unmounting mount point', error)
|
||||||
|
|
||||||
if json_results:
|
if json_results:
|
||||||
sys.stdout.write(json.dumps(json_results))
|
sys.stdout.write(json.dumps(json_results))
|
||||||
|
|
||||||
|
|
|
@ -169,6 +169,18 @@ def test_make_error_log_records_generates_nothing_for_other_error():
|
||||||
assert logs == ()
|
assert logs == ()
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_local_path_uses_configuration_value():
|
||||||
|
assert module.get_local_path({'test.yaml': {'location': {'local_path': 'borg1'}}}) == 'borg1'
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_local_path_without_location_defaults_to_borg():
|
||||||
|
assert module.get_local_path({'test.yaml': {}}) == 'borg'
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_local_path_without_local_path_defaults_to_borg():
|
||||||
|
assert module.get_local_path({'test.yaml': {'location': {}}}) == 'borg'
|
||||||
|
|
||||||
|
|
||||||
def test_collect_configuration_run_summary_logs_info_for_success():
|
def test_collect_configuration_run_summary_logs_info_for_success():
|
||||||
flexmock(module.command).should_receive('execute_hook').never()
|
flexmock(module.command).should_receive('execute_hook').never()
|
||||||
flexmock(module).should_receive('run_configuration').and_return([])
|
flexmock(module).should_receive('run_configuration').and_return([])
|
||||||
|
@ -324,6 +336,22 @@ def test_collect_configuration_run_summary_logs_run_configuration_error():
|
||||||
assert {log.levelno for log in logs} == {logging.CRITICAL}
|
assert {log.levelno for log in logs} == {logging.CRITICAL}
|
||||||
|
|
||||||
|
|
||||||
|
def test_collect_configuration_run_summary_logs_run_umount_error():
|
||||||
|
flexmock(module.validate).should_receive('guard_configuration_contains_repository')
|
||||||
|
flexmock(module).should_receive('run_configuration').and_return([])
|
||||||
|
flexmock(module.borg_umount).should_receive('unmount_archive').and_raise(OSError)
|
||||||
|
flexmock(module).should_receive('make_error_log_records').and_return(
|
||||||
|
[logging.makeLogRecord(dict(levelno=logging.CRITICAL, levelname='CRITICAL', msg='Error'))]
|
||||||
|
)
|
||||||
|
arguments = {'umount': flexmock(mount_point='/mnt')}
|
||||||
|
|
||||||
|
logs = tuple(
|
||||||
|
module.collect_configuration_run_summary_logs({'test.yaml': {}}, arguments=arguments)
|
||||||
|
)
|
||||||
|
|
||||||
|
assert {log.levelno for log in logs} == {logging.INFO, logging.CRITICAL}
|
||||||
|
|
||||||
|
|
||||||
def test_collect_configuration_run_summary_logs_outputs_merged_json_results():
|
def test_collect_configuration_run_summary_logs_outputs_merged_json_results():
|
||||||
flexmock(module).should_receive('run_configuration').and_return(['foo', 'bar']).and_return(
|
flexmock(module).should_receive('run_configuration').and_return(['foo', 'bar']).and_return(
|
||||||
['baz']
|
['baz']
|
||||||
|
|
Loading…
Reference in a new issue