From d29ba29276f824a08985be60e0fd40a786c0cf18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Sch=C3=A4fer?= Date: Mon, 12 Feb 2018 14:51:17 +0100 Subject: [PATCH] Add restrictions to Path.remove_hierarchy When an iso file is used as repo, this iso will be loop mounted on the host and bind mounted into the image root as long as the image builds. When the mount is released a recursive cleanup of the complete path happens. This is done by calling Path.remove_hierarchy. However if a sub path of the mount path contains a system root directory which is mandatory for the Linux root system it is not allowed to be deleted even if it is empty at the time of the mount cleanup. Thus this patch adds a lookup for protected directory names and only runs the recursive deletion as long as no protected member is part of the path. This fixes bsc#1080301 --- kiwi/path.py | 18 ++++++++++++++++-- test/unit/path_test.py | 15 ++++++++++----- 2 files changed, 26 insertions(+), 7 deletions(-) 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')