Fix traceback when a configuration directory is non-readable due to directory permissions (#350).

This commit is contained in:
Dan Helfman 2020-08-12 11:32:00 -07:00
parent f611fe7be3
commit 72bd96c656
3 changed files with 22 additions and 0 deletions

1
NEWS
View file

@ -1,4 +1,5 @@
1.5.10.dev0 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: * Clarify documentation on configuration overrides, specifically the portion about list syntax:
http://torsion.org/borgmatic/docs/how-to/make-per-application-backups/#configuration-overrides http://torsion.org/borgmatic/docs/how-to/make-per-application-backups/#configuration-overrides
* Clarify documentation overview of monitoring options: * Clarify documentation overview of monitoring options:

View file

@ -44,6 +44,9 @@ def collect_config_filenames(config_paths):
yield path yield path
continue continue
if not os.access(path, os.R_OK):
continue
for filename in sorted(os.listdir(path)): for filename in sorted(os.listdir(path)):
full_filename = os.path.join(path, filename) full_filename = os.path.join(path, filename)
matching_filetype = full_filename.endswith('.yaml') or full_filename.endswith('.yml') matching_filetype = full_filename.endswith('.yaml') or full_filename.endswith('.yml')

View file

@ -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('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').and_return(True)
mock_path.should_receive('isdir').with_args('/etc/borgmatic.d/foo.yml').and_return(False) 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(module.os).should_receive('listdir')
flexmock(sys.modules['builtins']).should_receive('sorted').and_return(['foo.yml']) 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/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/bar').and_return(True)
mock_path.should_receive('isdir').with_args('/etc/borgmatic.d/baz.yaml').and_return(False) 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(module.os).should_receive('listdir')
flexmock(sys.modules['builtins']).should_receive('sorted').and_return( flexmock(sys.modules['builtins']).should_receive('sorted').and_return(
['foo.yaml', 'bar', 'baz.yaml'] ['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/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/bar.yaml~').and_return(False)
mock_path.should_receive('isdir').with_args('/etc/borgmatic.d/baz.txt').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(module.os).should_receive('listdir')
flexmock(sys.modules['builtins']).should_receive('sorted').and_return( flexmock(sys.modules['builtins']).should_receive('sorted').and_return(
['foo.yaml', 'bar.yaml~', 'baz.txt'] ['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',) 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(): def test_collect_config_filenames_skips_etc_borgmatic_config_dot_yaml_if_it_does_not_exist():
config_paths = ('config.yaml', '/etc/borgmatic/config.yaml') config_paths = ('config.yaml', '/etc/borgmatic/config.yaml')
mock_path = flexmock(module.os.path) mock_path = flexmock(module.os.path)