From 72bd96c656a46bf1e2961b0e42a50041606d030b Mon Sep 17 00:00:00 2001 From: Dan Helfman Date: Wed, 12 Aug 2020 11:32:00 -0700 Subject: [PATCH] Fix traceback when a configuration directory is non-readable due to directory permissions (#350). --- NEWS | 1 + borgmatic/config/collect.py | 3 +++ tests/unit/config/test_collect.py | 18 ++++++++++++++++++ 3 files changed, 22 insertions(+) diff --git a/NEWS b/NEWS index 83c5e63..12c2718 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,5 @@ 1.5.10.dev0 + * #350: Fix traceback when a configuration directory is non-readable due to directory permissions. * Clarify documentation on configuration overrides, specifically the portion about list syntax: http://torsion.org/borgmatic/docs/how-to/make-per-application-backups/#configuration-overrides * Clarify documentation overview of monitoring options: diff --git a/borgmatic/config/collect.py b/borgmatic/config/collect.py index 97c9410..a13472e 100644 --- a/borgmatic/config/collect.py +++ b/borgmatic/config/collect.py @@ -44,6 +44,9 @@ def collect_config_filenames(config_paths): yield path continue + if not os.access(path, os.R_OK): + continue + for filename in sorted(os.listdir(path)): full_filename = os.path.join(path, filename) matching_filetype = full_filename.endswith('.yaml') or full_filename.endswith('.yml') diff --git a/tests/unit/config/test_collect.py b/tests/unit/config/test_collect.py index 4c4420a..5bab1ae 100644 --- a/tests/unit/config/test_collect.py +++ b/tests/unit/config/test_collect.py @@ -45,6 +45,7 @@ def test_collect_config_filenames_collects_yml_file_endings(): mock_path.should_receive('isdir').with_args('config.yaml').and_return(False) mock_path.should_receive('isdir').with_args('/etc/borgmatic.d').and_return(True) mock_path.should_receive('isdir').with_args('/etc/borgmatic.d/foo.yml').and_return(False) + flexmock(module.os).should_receive('access').and_return(True) flexmock(module.os).should_receive('listdir') flexmock(sys.modules['builtins']).should_receive('sorted').and_return(['foo.yml']) @@ -62,6 +63,7 @@ def test_collect_config_filenames_collects_files_from_given_directories_and_igno mock_path.should_receive('isdir').with_args('/etc/borgmatic.d/foo.yaml').and_return(False) mock_path.should_receive('isdir').with_args('/etc/borgmatic.d/bar').and_return(True) mock_path.should_receive('isdir').with_args('/etc/borgmatic.d/baz.yaml').and_return(False) + flexmock(module.os).should_receive('access').and_return(True) flexmock(module.os).should_receive('listdir') flexmock(sys.modules['builtins']).should_receive('sorted').and_return( ['foo.yaml', 'bar', 'baz.yaml'] @@ -84,6 +86,7 @@ def test_collect_config_filenames_collects_files_from_given_directories_and_igno mock_path.should_receive('isdir').with_args('/etc/borgmatic.d/foo.yaml').and_return(False) mock_path.should_receive('isdir').with_args('/etc/borgmatic.d/bar.yaml~').and_return(False) mock_path.should_receive('isdir').with_args('/etc/borgmatic.d/baz.txt').and_return(False) + flexmock(module.os).should_receive('access').and_return(True) flexmock(module.os).should_receive('listdir') flexmock(sys.modules['builtins']).should_receive('sorted').and_return( ['foo.yaml', 'bar.yaml~', 'baz.txt'] @@ -94,6 +97,21 @@ def test_collect_config_filenames_collects_files_from_given_directories_and_igno assert config_filenames == ('/etc/borgmatic.d/foo.yaml',) +def test_collect_config_filenames_skips_permission_denied_directories(): + config_paths = ('config.yaml', '/etc/borgmatic.d') + mock_path = flexmock(module.os.path) + mock_path.should_receive('exists').and_return(True) + mock_path.should_receive('isdir').with_args('config.yaml').and_return(False) + mock_path.should_receive('isdir').with_args('/etc/borgmatic.d').and_return(True) + flexmock(module.os).should_receive('access').and_return(False) + flexmock(module.os).should_receive('listdir') + flexmock(sys.modules['builtins']).should_receive('sorted').and_return(['config.yaml']) + + config_filenames = tuple(module.collect_config_filenames(config_paths)) + + assert config_filenames == ('config.yaml',) + + def test_collect_config_filenames_skips_etc_borgmatic_config_dot_yaml_if_it_does_not_exist(): config_paths = ('config.yaml', '/etc/borgmatic/config.yaml') mock_path = flexmock(module.os.path)