From 8dbf932c05c7b7ebfdfbcd49cb2d4e37b5cdc06c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Sch=C3=A4fer?= Date: Wed, 17 Feb 2016 10:56:40 +0100 Subject: [PATCH] Fixed host to image root data setup On bind mounts check if the origin path exists on the host. On copy check if the origin file exists on the host --- kiwi/root_bind.py | 48 ++++++++++++---------- test/unit/root_bind_test.py | 80 +++++++++++++++++++++++++------------ 2 files changed, 81 insertions(+), 47 deletions(-) diff --git a/kiwi/root_bind.py b/kiwi/root_bind.py index 5d9d8c13..e13589fa 100644 --- a/kiwi/root_bind.py +++ b/kiwi/root_bind.py @@ -59,13 +59,14 @@ class RootBind(object): def mount_kernel_file_systems(self): try: for location in self.bind_locations: - Command.run( - [ - 'mount', '-n', '--bind', location, - self.root_dir + location - ] - ) - self.mount_stack.append(location) + if os.path.exists(location): + Command.run( + [ + 'mount', '-n', '--bind', location, + self.root_dir + location + ] + ) + self.mount_stack.append(location) except Exception as e: self.cleanup() raise KiwiMountKernelFileSystemsError( @@ -93,14 +94,15 @@ class RootBind(object): def setup_intermediate_config(self): try: for config in self.config_files: - self.cleanup_files.append(config + '.kiwi') - Command.run( - ['cp', config, self.root_dir + config + '.kiwi'] - ) - link_target = os.path.basename(config) + '.kiwi' - Command.run( - ['ln', '-s', '-f', link_target, self.root_dir + config] - ) + if os.path.exists(config): + self.cleanup_files.append(config + '.kiwi') + Command.run( + ['cp', config, self.root_dir + config + '.kiwi'] + ) + link_target = os.path.basename(config) + '.kiwi' + Command.run( + ['ln', '-s', '-f', link_target, self.root_dir + config] + ) except Exception as e: self.cleanup() raise KiwiSetupIntermediateConfigError( @@ -144,13 +146,15 @@ class RootBind(object): ) def __cleanup_mount_stack(self): - try: - Command.run(['umount', '-l'] + self.__build_mount_list()) - except Exception as e: - log.warning( - 'Image root directory %s not cleanly umounted: %s', - self.root_dir, format(e) - ) + mount_list = self.__build_mount_list() + if mount_list: + try: + Command.run(['umount', '-l'] + mount_list) + except Exception as e: + log.warning( + 'Image root directory %s not cleanly umounted: %s', + self.root_dir, format(e) + ) del self.mount_stack[:] diff --git a/test/unit/root_bind_test.py b/test/unit/root_bind_test.py index d67a418a..a23d935d 100644 --- a/test/unit/root_bind_test.py +++ b/test/unit/root_bind_test.py @@ -1,6 +1,6 @@ from nose.tools import * from mock import patch - +from mock import call import mock import nose_helper @@ -34,7 +34,11 @@ class TestRootBind(object): @raises(KiwiMountKernelFileSystemsError) @patch('kiwi.command.Command.run') @patch('kiwi.root_bind.RootBind.cleanup') - def test_kernel_file_systems_raises_error(self, mock_cleanup, mock_command): + @patch('os.path.exists') + def test_kernel_file_systems_raises_error( + self, mock_exists, mock_cleanup, mock_command + ): + mock_exists.return_value = True mock_command.side_effect = KiwiMountKernelFileSystemsError( 'mount-error' ) @@ -54,7 +58,11 @@ class TestRootBind(object): @raises(KiwiSetupIntermediateConfigError) @patch('kiwi.command.Command.run') @patch('kiwi.root_bind.RootBind.cleanup') - def test_intermediate_config_raises_error(self, mock_cleanup, mock_command): + @patch('os.path.exists') + def test_intermediate_config_raises_error( + self, mock_exists, mock_cleanup, mock_command + ): + mock_exists.return_value = True mock_command.side_effect = KiwiSetupIntermediateConfigError( 'config-error' ) @@ -71,31 +79,29 @@ class TestRootBind(object): @patch('kiwi.command.Command.run') def test_mount_shared_directory(self, mock_command): self.bind_root.mount_shared_directory() - call = mock_command.call_args_list[0] - assert mock_command.call_args_list[0] == \ + assert mock_command.call_args_list == [ call([ 'mkdir', '-p', 'root-dir/var/cache/kiwi' - ]) - call = mock_command.call_args_list[1] - assert mock_command.call_args_list[1] == \ + ]), call([ 'mount', '-n', '--bind', '/var/cache/kiwi', 'root-dir/var/cache/kiwi' ]) + ] @patch('kiwi.command.Command.run') - def test_intermediate_config(self, mock_command): + @patch('os.path.exists') + def test_intermediate_config(self, mock_exists, mock_command): + mock_exists.return_value = True self.bind_root.setup_intermediate_config() - call = mock_command.call_args_list[0] - assert mock_command.call_args_list[0] == \ + assert mock_command.call_args_list == [ call([ 'cp', '/foo', 'root-dir/foo.kiwi' - ]) - call = mock_command.call_args_list[1] - assert mock_command.call_args_list[1] == \ + ]), call([ 'ln', '-s', '-f', 'foo.kiwi', 'root-dir/foo' ]) + ] @patch('kiwi.command.Command.run') @patch('os.path.islink') @@ -103,27 +109,21 @@ class TestRootBind(object): mock_islink.return_value = True self.bind_root.cleanup() - call = mock_command.call_args_list[0] - assert mock_command.call_args_list[0] == \ + assert mock_command.call_args_list == [ call([ 'mountpoint', '-q', 'root-dir/mountpoint' - ]) - call = mock_command.call_args_list[1] - assert mock_command.call_args_list[1] == \ + ]), call([ 'umount', '-l', 'root-dir/mountpoint' - ]) - call = mock_command.call_args_list[2] - assert mock_command.call_args_list[2] == \ + ]), call([ 'rmdir', '-p', '--ignore-fail-on-non-empty', 'root-dir/mountpoint' - ]) - call = mock_command.call_args_list[3] - assert mock_command.call_args_list[3] == \ + ]), call([ 'rm', '-f', 'root-dir/foo.kiwi', 'root-dir/foo' ]) + ] @patch('kiwi.command.Command.run') @patch('os.path.islink') @@ -131,9 +131,39 @@ class TestRootBind(object): def test_cleanup_continue_on_raise( self, mock_warn, mock_islink, mock_command ): + + def side_effect(arg): + if arg[0] == 'mountpoint': + return + else: + raise Exception + + mock_command.side_effect = side_effect + mock_islink.return_value = True + self.bind_root.cleanup() + assert mock_warn.called + + @patch('kiwi.command.Command.run') + @patch('os.path.islink') + @patch('kiwi.logger.log.warning') + def test_cleanup_mountpoint_invalid( + self, mock_warn, mock_islink, mock_command + ): mock_islink.return_value = True mock_command.side_effect = Exception self.bind_root.cleanup() + assert mock_command.call_args_list == [ + call([ + 'mountpoint', '-q', 'root-dir/mountpoint' + ]), + call([ + 'rmdir', '-p', '--ignore-fail-on-non-empty', + 'root-dir/mountpoint' + ]), + call([ + 'rm', '-f', 'root-dir/foo.kiwi', 'root-dir/foo' + ]) + ] def test_move_to_root(self): assert self.bind_root.move_to_root(