kiwi uses e.g etc/hosts from the host system for proper name resolution during the build. The temporary variant of that file will be deleted by kiwi at the end of the installation process. However depending on the package manager and the distribution it could happen that the intermediate config file added by kiwi is treated as existing config variant. In case of rpm a .rpmnew file variant of the config file is created and that needs to be handled by kiwi. Therefore this patch adds a private restore method for the .rpmnew case. It might be needed to add other restore methods to deal with this issue depending on how other (non rpm) based package managers handles the situation. Fixes #104
180 lines
6.2 KiB
Python
180 lines
6.2 KiB
Python
|
|
from mock import patch
|
|
from mock import call
|
|
import mock
|
|
|
|
from .test_helper import *
|
|
|
|
from kiwi.exceptions import (
|
|
KiwiMountKernelFileSystemsError,
|
|
KiwiMountSharedDirectoryError,
|
|
KiwiSetupIntermediateConfigError
|
|
)
|
|
|
|
from kiwi.system.root_bind import RootBind
|
|
|
|
from kiwi.exceptions import *
|
|
|
|
|
|
class TestRootBind(object):
|
|
def setup(self):
|
|
root = mock.Mock()
|
|
root.root_dir = 'root-dir'
|
|
self.bind_root = RootBind(root)
|
|
|
|
# stub config files and bind locations
|
|
self.bind_root.config_files = ['/foo']
|
|
self.bind_root.bind_locations = ['/proc']
|
|
|
|
# stub files/dirs and mountpoints to cleanup
|
|
self.mount_manager = mock.Mock()
|
|
self.bind_root.cleanup_files = ['/foo.kiwi']
|
|
self.bind_root.mount_stack = [self.mount_manager]
|
|
self.bind_root.dir_stack = ['/mountpoint']
|
|
|
|
@raises(KiwiMountKernelFileSystemsError)
|
|
@patch('kiwi.system.root_bind.MountManager.bind_mount')
|
|
@patch('kiwi.system.root_bind.RootBind.cleanup')
|
|
@patch('os.path.exists')
|
|
def test_kernel_file_systems_raises_error(
|
|
self, mock_exists, mock_cleanup, mock_mount
|
|
):
|
|
mock_exists.return_value = True
|
|
mock_mount.side_effect = KiwiMountKernelFileSystemsError(
|
|
'mount-error'
|
|
)
|
|
self.bind_root.mount_kernel_file_systems()
|
|
mock.cleanup.assert_called_once_with()
|
|
|
|
@raises(KiwiMountSharedDirectoryError)
|
|
@patch('kiwi.system.root_bind.MountManager.bind_mount')
|
|
@patch('kiwi.system.root_bind.Path.create')
|
|
@patch('kiwi.system.root_bind.RootBind.cleanup')
|
|
def test_shared_directory_raises_error(
|
|
self, mock_cleanup, mock_path, mock_mount
|
|
):
|
|
mock_mount.side_effect = KiwiMountSharedDirectoryError(
|
|
'mount-error'
|
|
)
|
|
self.bind_root.mount_shared_directory()
|
|
mock.cleanup.assert_called_once_with()
|
|
|
|
@raises(KiwiSetupIntermediateConfigError)
|
|
@patch('kiwi.command.Command.run')
|
|
@patch('kiwi.system.root_bind.RootBind.cleanup')
|
|
@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'
|
|
)
|
|
self.bind_root.setup_intermediate_config()
|
|
mock.cleanup.assert_called_once_with()
|
|
|
|
@patch('kiwi.system.root_bind.MountManager')
|
|
def test_mount_kernel_file_systems(self, mock_mount):
|
|
shared_mount = mock.Mock()
|
|
mock_mount.return_value = shared_mount
|
|
self.bind_root.mount_kernel_file_systems()
|
|
mock_mount.assert_called_once_with(
|
|
device='/proc', mountpoint='root-dir/proc'
|
|
)
|
|
shared_mount.bind_mount.assert_called_once_with()
|
|
|
|
@patch('kiwi.system.root_bind.MountManager')
|
|
@patch('kiwi.system.root_bind.Path.create')
|
|
def test_mount_shared_directory(self, mock_path, mock_mount):
|
|
shared_mount = mock.Mock()
|
|
mock_mount.return_value = shared_mount
|
|
self.bind_root.mount_shared_directory()
|
|
mock_path.call_args_list = [
|
|
call('root-dir/var/cache/kiwi'),
|
|
call('/var/cache/kiwi')
|
|
]
|
|
mock_mount.assert_called_once_with(
|
|
device='/var/cache/kiwi', mountpoint='root-dir/var/cache/kiwi'
|
|
)
|
|
shared_mount.bind_mount.assert_called_once_with()
|
|
|
|
@patch('kiwi.command.Command.run')
|
|
@patch('os.path.exists')
|
|
def test_intermediate_config(self, mock_exists, mock_command):
|
|
mock_exists.return_value = True
|
|
self.bind_root.setup_intermediate_config()
|
|
assert mock_command.call_args_list == [
|
|
call([
|
|
'cp', '/foo', 'root-dir/foo.kiwi'
|
|
]),
|
|
call([
|
|
'ln', '-s', '-f', 'foo.kiwi', 'root-dir/foo'
|
|
])
|
|
]
|
|
|
|
@patch('kiwi.system.root_bind.MountManager.is_mounted')
|
|
@patch('kiwi.system.root_bind.Command.run')
|
|
@patch('kiwi.system.root_bind.Path.remove_hierarchy')
|
|
@patch('os.path.islink')
|
|
@patch('os.path.exists')
|
|
@patch('shutil.move')
|
|
def test_cleanup(
|
|
self, mock_move, mock_exists, mock_islink, mock_remove_hierarchy,
|
|
mock_command, mock_is_mounted
|
|
):
|
|
mock_is_mounted.return_value = False
|
|
mock_exists.return_value = True
|
|
mock_islink.return_value = True
|
|
self.bind_root.cleanup()
|
|
self.mount_manager.umount_lazy.assert_called_once_with()
|
|
mock_remove_hierarchy.assert_called_once_with('root-dir/mountpoint')
|
|
mock_command.assert_called_once_with(
|
|
['rm', '-f', 'root-dir/foo.kiwi', 'root-dir/foo']
|
|
)
|
|
mock_move.assert_called_once_with(
|
|
'root-dir/foo.rpmnew', 'root-dir/foo'
|
|
)
|
|
|
|
@patch('os.path.islink')
|
|
@patch('kiwi.logger.log.warning')
|
|
@patch('kiwi.command.Command.run')
|
|
@patch('kiwi.system.root_bind.Path.remove_hierarchy')
|
|
def test_cleanup_continue_on_error(
|
|
self, mock_remove_hierarchy, mock_command, mock_warn, mock_islink
|
|
):
|
|
mock_islink.return_value = True
|
|
mock_remove_hierarchy.side_effect = Exception
|
|
mock_command.side_effect = Exception
|
|
self.mount_manager.umount_lazy.side_effect = Exception
|
|
self.bind_root.cleanup()
|
|
assert mock_warn.call_args_list == [
|
|
call(
|
|
'Image root directory %s not cleanly umounted: %s',
|
|
'root-dir', ''
|
|
),
|
|
call(
|
|
'Failed to remove directory %s: %s', '/mountpoint', ''
|
|
),
|
|
call(
|
|
'Failed to remove intermediate config files: %s', ''
|
|
)
|
|
]
|
|
|
|
@patch('kiwi.logger.log.warning')
|
|
@patch('kiwi.command.Command.run')
|
|
@patch('kiwi.system.root_bind.Path.remove_hierarchy')
|
|
def test_cleanup_nothing_mounted(
|
|
self, mock_remove_hierarchy, mock_command, mock_warn
|
|
):
|
|
self.mount_manager.is_mounted.return_value = False
|
|
self.mount_manager.mountpoint = '/mountpoint'
|
|
self.bind_root.cleanup()
|
|
mock_warn.assert_called_once_with(
|
|
'Path %s not a mountpoint', '/mountpoint'
|
|
)
|
|
|
|
def test_move_to_root(self):
|
|
assert self.bind_root.move_to_root(
|
|
[self.bind_root.root_dir + '/argument']
|
|
) == ['//argument']
|