diff --git a/kiwi/path.py b/kiwi/path.py index 0dd18eae..a1a8e037 100644 --- a/kiwi/path.py +++ b/kiwi/path.py @@ -90,13 +90,27 @@ class Path(object): def remove_hierarchy(self, path): """ Recursively remove an empty path and its sub directories - ignore non empty paths and leave them untouched + ignore non empty or protected paths and leave them untouched :param string path: path name """ Command.run( - ['rmdir', '-p', '--ignore-fail-on-non-empty', path] + ['rmdir', '--ignore-fail-on-non-empty', path] ) + path_elements = path.split(os.sep) + protected_elements = [ + 'boot', 'dev', 'proc', 'run', 'sys', 'tmp' + ] + for path_index in reversed(range(0, len(path_elements))): + sub_path = os.sep.join(path_elements[0:path_index]) + if path_elements[path_index - 1] in protected_elements: + log.warning( + 'remove_hierarchy: path {0} is protected'.format(sub_path) + ) + return + Command.run( + ['rmdir', '--ignore-fail-on-non-empty', sub_path] + ) @classmethod def which( diff --git a/test/unit/path_test.py b/test/unit/path_test.py index 8abb9b29..83489e27 100644 --- a/test/unit/path_test.py +++ b/test/unit/path_test.py @@ -1,4 +1,4 @@ -from mock import patch +from mock import patch, call import os @@ -34,10 +34,15 @@ class TestPath(object): ) @patch('kiwi.command.Command.run') - def test_remove_hierarchy(self, mock_command): - Path.remove_hierarchy('foo') - mock_command.assert_called_once_with( - ['rmdir', '-p', '--ignore-fail-on-non-empty', 'foo'] + @patch('kiwi.logger.log.warning') + def test_remove_hierarchy(self, mock_log_warn, mock_command): + Path.remove_hierarchy('/my_root/tmp/foo/bar') + assert mock_command.call_args_list == [ + call(['rmdir', '--ignore-fail-on-non-empty', '/my_root/tmp/foo/bar']), + call(['rmdir', '--ignore-fail-on-non-empty', '/my_root/tmp/foo']) + ] + mock_log_warn.assert_called_once_with( + 'remove_hierarchy: path /my_root/tmp is protected' ) @patch('os.access')