diff --git a/kiwi/bootloader_config_grub2.py b/kiwi/bootloader_config_grub2.py
index 0584903f..29fe6349 100644
--- a/kiwi/bootloader_config_grub2.py
+++ b/kiwi/bootloader_config_grub2.py
@@ -53,6 +53,7 @@ class BootLoaderConfigGrub2(BootLoaderConfigBase):
'host architecture %s not supported for grub2 setup' % arch
)
+ self.gfxmode = '800x600'
self.terminal = 'gfxterm'
self.bootpath = self.get_boot_path()
self.gfxmode = self.__get_gfxmode()
@@ -260,8 +261,8 @@ class BootLoaderConfigGrub2(BootLoaderConfigBase):
self.__setup_secure_boot_efi_image(lookup_path)
else:
log.info('--> Creating unsigned efi image')
+ self.__create_efi_image(mbrid=mbrid, lookup_path=lookup_path)
self.__copy_efi_modules_to_boot_directory(lookup_path)
- self.__create_efi_image(mbrid=mbrid)
self.__create_embedded_fat_efi_image()
@@ -271,8 +272,9 @@ class BootLoaderConfigGrub2(BootLoaderConfigBase):
def setup_disk_boot_images(self, boot_uuid, lookup_path=None):
"""
- EFI and bios images needs to be build or used if provided
- by the distribution
+ EFI images needs to be build or used if provided
+ by the distribution. The bios core image is created
+ when grub2-install is called
"""
log.info('Creating grub bootloader images')
@@ -283,15 +285,14 @@ class BootLoaderConfigGrub2(BootLoaderConfigBase):
if self.firmware.efi_mode() == 'efi':
log.info('--> Creating unsigned efi image')
+ self.__create_efi_image(uuid=boot_uuid, lookup_path=lookup_path)
self.__copy_efi_modules_to_boot_directory(lookup_path)
- self.__create_efi_image(uuid=boot_uuid)
elif self.firmware.efi_mode() == 'uefi':
log.info('--> Using signed secure boot efi image')
self.__setup_secure_boot_efi_image(lookup_path)
log.info('--> Creating bios core image')
self.__copy_bios_modules_to_boot_directory(lookup_path)
- self.__create_bios_boot_image(boot_uuid)
def __setup_secure_boot_efi_image(self, lookup_path):
"""
@@ -335,7 +336,7 @@ class BootLoaderConfigGrub2(BootLoaderConfigBase):
]
)
- def __create_efi_image(self, uuid=None, mbrid=None):
+ def __create_efi_image(self, uuid=None, mbrid=None, lookup_path=None):
"""
create efi image
"""
@@ -355,28 +356,8 @@ class BootLoaderConfigGrub2(BootLoaderConfigBase):
'-o', self.__get_efi_image_name(),
'-c', early_boot_script,
'-p', self.get_boot_path() + '/' + self.boot_directory_name,
- '-d',
- self.__get_grub_boot_path() + '/' + self.__get_efi_format()
- ] + self.__get_efi_modules()
- )
-
- def __create_bios_boot_image(self, uuid):
- """
- create bios image
- """
- early_boot_script = self.__get_grub_boot_path() + '/earlyboot.cfg'
- self.__create_early_boot_script_for_uuid_search(
- early_boot_script, uuid
- )
- Command.run(
- [
- 'grub2-mkimage', '-O', self.__get_bios_format(),
- '-o', self.__get_bios_image_name(),
- '-c', early_boot_script,
- '-p', self.get_boot_path() + '/' + self.boot_directory_name,
- '-d',
- self.__get_grub_boot_path() + '/' + self.__get_bios_format()
- ] + self.__get_bios_modules()
+ '-d', self.__get_efi_modules_path(lookup_path)
+ ] + Defaults.get_grub_efi_modules()
)
def __create_early_boot_script_for_uuid_search(self, filename, uuid):
@@ -402,73 +383,8 @@ class BootLoaderConfigGrub2(BootLoaderConfigBase):
def __get_grub_boot_path(self):
return self.root_dir + '/boot/' + self.boot_directory_name
- def __get_basic_modules(self):
- modules = [
- 'ext2',
- 'iso9660',
- 'linux',
- 'echo',
- 'configfile',
- 'search_label',
- 'search_fs_file',
- 'search',
- 'search_fs_uuid',
- 'ls',
- 'normal',
- 'gzio',
- 'png',
- 'fat',
- 'gettext',
- 'font',
- 'minicmd',
- 'gfxterm',
- 'gfxmenu',
- 'video',
- 'video_fb',
- 'xfs',
- 'btrfs',
- 'lvm',
- 'multiboot'
- ]
- return modules
-
- def __get_efi_modules(self):
- modules = self.__get_basic_modules() + [
- 'part_gpt',
- 'efi_gop',
- 'efi_uga',
- 'linuxefi'
- ]
- return modules
-
- def __get_bios_modules(self):
- modules = self.__get_basic_modules() + [
- 'part_gpt',
- 'part_msdos',
- 'biosdisk',
- 'vga',
- 'vbe',
- 'chain',
- 'boot'
- ]
- return modules
-
def __get_efi_image_name(self):
- efi_image_name = None
- if self.arch == 'x86_64':
- efi_image_name = 'bootx64.efi'
- if efi_image_name:
- return ''.join(
- [self.efi_boot_path, '/', efi_image_name]
- )
-
- def __get_bios_image_name(self):
- return ''.join(
- [
- self.__get_grub_boot_path(), '/',
- self.__get_bios_format(), '/core.img'
- ]
- )
+ return self.efi_boot_path + '/bootx64.efi'
def __get_efi_format(self):
return 'x86_64-efi'
@@ -499,29 +415,11 @@ class BootLoaderConfigGrub2(BootLoaderConfigBase):
)
def __get_gfxmode(self):
- selected_gfxmode = '800x600'
- gfxmode = {
- '0x301': '640x480',
- '0x310': '640x480',
- '0x311': '640x480',
- '0x312': '640x480',
- '0x303': '800x600',
- '0x313': '800x600',
- '0x314': '800x600',
- '0x315': '800x600',
- '0x305': '1024x768',
- '0x316': '1024x768',
- '0x317': '1024x768',
- '0x318': '1024x768',
- '0x307': '1280x1024',
- '0x319': '1280x1024',
- '0x31a': '1280x1024',
- '0x31b': '1280x1024',
- }
+ gfxmode = Defaults.get_video_mode_map()
requested_gfxmode = self.xml_state.build_type.get_vga()
if requested_gfxmode in gfxmode:
- selected_gfxmode = gfxmode[requested_gfxmode]
- return selected_gfxmode
+ self.gfxmode = gfxmode[requested_gfxmode].grub2
+ return self.gfxmode
def __copy_theme_data_to_boot_directory(self, lookup_path):
if not lookup_path:
@@ -547,7 +445,7 @@ class BootLoaderConfigGrub2(BootLoaderConfigBase):
'/themes/' + self.theme
if os.path.exists(theme_dir):
Command.run(
- ['rsync', '-zav', theme_dir, boot_theme_dir],
+ ['rsync', '-za', theme_dir, boot_theme_dir],
)
else:
log.warning('Theme %s not found', theme_dir)
@@ -569,15 +467,14 @@ class BootLoaderConfigGrub2(BootLoaderConfigBase):
def __copy_modules_to_boot_directory_from(self, module_path):
boot_module_path = \
self.__get_grub_boot_path() + '/' + os.path.basename(module_path)
- if not os.path.exists(boot_module_path):
- try:
- Command.run(
- ['cp', '-a', module_path, boot_module_path]
- )
- except Exception:
- raise KiwiBootLoaderGrubModulesError(
- 'grub2 modules %s not found' % module_path
- )
+ try:
+ Command.run(
+ ['rsync', '-za', module_path + '/', boot_module_path]
+ )
+ except Exception as e:
+ raise KiwiBootLoaderGrubModulesError(
+ 'Module synchronisation failed with: %s' % format(e)
+ )
def __find_grub_data(self, lookup_path):
"""
diff --git a/kiwi/bootloader_install_grub2.py b/kiwi/bootloader_install_grub2.py
index f99dbe88..7924ead2 100644
--- a/kiwi/bootloader_install_grub2.py
+++ b/kiwi/bootloader_install_grub2.py
@@ -15,55 +15,114 @@
# You should have received a copy of the GNU General Public License
# along with kiwi. If not, see
#
-from tempfile import NamedTemporaryFile
from tempfile import mkdtemp
+import time
# project
from .bootloader_install_base import BootLoaderInstallBase
from .command import Command
from .logger import log
from .path import Path
+from .defaults import Defaults
+
+from .exceptions import(
+ KiwiBootLoaderGrubInstallError
+)
class BootLoaderInstallGrub2(BootLoaderInstallBase):
"""
- grub2 bootloader installation
+ grub2 bootloader installation for x86 bios platform
"""
def post_init(self, custom_args):
self.custom_args = custom_args
- self.temporary_boot_dir = None
+ if not custom_args or 'boot_device' not in custom_args:
+ raise KiwiBootLoaderGrubInstallError(
+ 'boot device node name required for grub2 installation'
+ )
+ if not custom_args or 'root_device' not in custom_args:
+ raise KiwiBootLoaderGrubInstallError(
+ 'root device node name required for grub2 installation'
+ )
+
+ self.mountpoint_root = mkdtemp()
+ self.mountpoint_boot = mkdtemp()
+ self.grub2_boot_device = custom_args['boot_device']
+ self.grub2_root_device = custom_args['root_device']
+
+ self.extra_boot_partition = False
+ if not self.grub2_boot_device == self.grub2_root_device:
+ self.extra_boot_partition = True
def install(self):
"""
install bootloader on self.device
"""
log.info('Installing grub2 on disk %s', self.device)
- device_map_file = NamedTemporaryFile()
- with open(device_map_file.name, 'w') as device_map:
- device_map.write('(hd0) %s\n' % self.device)
- # The following copy action is only needed because grub2-probe
- # is not able to resolve the canonical path of the boot directory
- # if it lives on e.g a tmpfs. However building an image in a tmpfs
- # is done pretty often to increase the build performance. In order
- # to make grub happy we have to copy out the boot data with the
- # hope that /boot of the build host system is not on a filesystem
- # which causes grub2-probe to fail again
- self.temporary_boot_dir = mkdtemp(prefix='kiwi_bootloader.')
- Command.run(
- ['cp', '-a', self.root_dir + '/boot/', self.temporary_boot_dir]
- )
+ if self.extra_boot_partition:
+ self.__mount_boot_partition()
+ self.__mount_root_partition()
+ module_directory = self.mountpoint_root + '/usr/lib/grub2/i386-pc'
+ boot_directory = self.mountpoint_boot
+ else:
+ self.__mount_root_partition()
+ module_directory = self.mountpoint_root + '/usr/lib/grub2/i386-pc'
+ boot_directory = self.mountpoint_root + '/boot'
Command.run(
[
- 'grub2-bios-setup', '-f',
- '-d', self.temporary_boot_dir + '/boot/grub2/i386-pc',
- '-m', device_map_file.name,
+ 'grub2-install',
+ '--skip-fs-probe',
+ '--directory', module_directory,
+ '--boot-directory', boot_directory,
+ '--target', 'i386-pc',
+ '--modules', ' '.join(Defaults.get_grub_bios_modules()),
self.device
]
)
+ def __mount_boot_partition(self):
+ self.__mount(self.grub2_boot_device, self.mountpoint_boot)
+
+ def __mount_root_partition(self):
+ self.__mount(self.grub2_root_device, self.mountpoint_root)
+
+ def __is_mounted(self, mountpoint):
+ try:
+ Command.run(['mountpoint', mountpoint])
+ return True
+ except Exception:
+ return False
+
+ def __mount(self, device, mountpoint):
+ Command.run(['mount', device, mountpoint])
+ return True
+
+ def __umount(self, mountpoint):
+ if self.__is_mounted(mountpoint):
+ umounted_successfully = False
+ for busy in [1, 2, 3]:
+ try:
+ Command.run(['umount', mountpoint])
+ umounted_successfully = True
+ break
+ except Exception:
+ log.warning(
+ '%d umount of %s failed, try again in 1sec',
+ busy, mountpoint
+ )
+ time.sleep(1)
+ if not umounted_successfully:
+ log.warning(
+ '%s still busy at %s', mountpoint, type(self).__name__
+ )
+ # skip removing the mountpoint directory
+ return
+
+ Path.remove(mountpoint)
+
def __del__(self):
- if self.temporary_boot_dir:
- log.info('Cleaning up %s instance', type(self).__name__)
- Path.wipe(self.temporary_boot_dir)
+ log.info('Cleaning up %s instance', type(self).__name__)
+ self.__umount(self.mountpoint_root)
+ self.__umount(self.mountpoint_boot)
diff --git a/kiwi/defaults.py b/kiwi/defaults.py
index 85eabb20..fd311ebb 100644
--- a/kiwi/defaults.py
+++ b/kiwi/defaults.py
@@ -15,6 +15,7 @@
# You should have received a copy of the GNU General Public License
# along with kiwi. If not, see
#
+from collections import namedtuple
import platform
import re
from pkg_resources import resource_filename
@@ -49,6 +50,83 @@ class Defaults(object):
'kiwi_revision'
]
+ @classmethod
+ def get_video_mode_map(self):
+ video_type = namedtuple(
+ 'video_type', ['grub2']
+ )
+ return {
+ '0x301': video_type(grub2='640x480'),
+ '0x310': video_type(grub2='640x480'),
+ '0x311': video_type(grub2='640x480'),
+ '0x312': video_type(grub2='640x480'),
+ '0x303': video_type(grub2='800x600'),
+ '0x313': video_type(grub2='800x600'),
+ '0x314': video_type(grub2='800x600'),
+ '0x315': video_type(grub2='800x600'),
+ '0x305': video_type(grub2='1024x768'),
+ '0x316': video_type(grub2='1024x768'),
+ '0x317': video_type(grub2='1024x768'),
+ '0x318': video_type(grub2='1024x768'),
+ '0x307': video_type(grub2='1280x1024'),
+ '0x319': video_type(grub2='1280x1024'),
+ '0x31a': video_type(grub2='1280x1024'),
+ '0x31b': video_type(grub2='1280x1024'),
+ }
+
+ @classmethod
+ def get_grub_basic_modules(self):
+ return [
+ 'ext2',
+ 'iso9660',
+ 'linux',
+ 'echo',
+ 'configfile',
+ 'search_label',
+ 'search_fs_file',
+ 'search',
+ 'search_fs_uuid',
+ 'ls',
+ 'normal',
+ 'gzio',
+ 'png',
+ 'fat',
+ 'gettext',
+ 'font',
+ 'minicmd',
+ 'gfxterm',
+ 'gfxmenu',
+ 'video',
+ 'video_fb',
+ 'xfs',
+ 'btrfs',
+ 'lvm',
+ 'multiboot'
+ ]
+
+ @classmethod
+ def get_grub_efi_modules(self):
+ modules = Defaults.get_grub_basic_modules() + [
+ 'part_gpt',
+ 'efi_gop',
+ 'efi_uga',
+ 'linuxefi'
+ ]
+ return modules
+
+ @classmethod
+ def get_grub_bios_modules(self):
+ modules = Defaults.get_grub_basic_modules() + [
+ 'part_gpt',
+ 'part_msdos',
+ 'biosdisk',
+ 'vga',
+ 'vbe',
+ 'chain',
+ 'boot'
+ ]
+ return modules
+
@classmethod
def get_preparer(self):
return 'KIWI - http://suse.github.com/kiwi'
diff --git a/kiwi/disk_builder.py b/kiwi/disk_builder.py
index c24d02f5..950aa6ef 100644
--- a/kiwi/disk_builder.py
+++ b/kiwi/disk_builder.py
@@ -485,11 +485,15 @@ class DiskBuilder(object):
)
def __install_bootloader(self, device_map):
- boot_device = device_map['root']
- custom_install_arguments = {}
+ root_device = device_map['root']
+ boot_device = root_device
if 'boot' in device_map:
boot_device = device_map['boot']
- custom_install_arguments['boot_device'] = boot_device.get_device()
+
+ custom_install_arguments = {
+ 'boot_device': boot_device.get_device(),
+ 'root_device': root_device.get_device()
+ }
bootloader = BootLoaderInstall(
self.bootloader, self.root_dir, self.disk.storage_provider,
diff --git a/kiwi/exceptions.py b/kiwi/exceptions.py
index 4c83e22c..578cb1bb 100644
--- a/kiwi/exceptions.py
+++ b/kiwi/exceptions.py
@@ -49,6 +49,10 @@ class KiwiBootLoaderGrubFontError(KiwiError):
pass
+class KiwiBootLoaderGrubInstallError(KiwiError):
+ pass
+
+
class KiwiBootLoaderGrubModulesError(KiwiError):
pass
diff --git a/test/unit/bootloader_config_grub2_test.py b/test/unit/bootloader_config_grub2_test.py
index 0788299d..b547df68 100644
--- a/test/unit/bootloader_config_grub2_test.py
+++ b/test/unit/bootloader_config_grub2_test.py
@@ -316,13 +316,10 @@ class TestBootLoaderConfigGrub2(object):
setattr(context_manager_mock, '__exit__', exit_mock)
self.bootloader.setup_disk_boot_images('0815')
- assert mock_open.call_args_list == [
- call('root_dir/boot/efi/EFI/BOOT/earlyboot.cfg', 'w'),
- call('root_dir/boot/grub2/earlyboot.cfg', 'w')
- ]
+ mock_open.assert_called_once_with(
+ 'root_dir/boot/efi/EFI/BOOT/earlyboot.cfg', 'w'
+ )
assert file_mock.write.call_args_list == [
- call('search --fs-uuid --set=root 0815\n'),
- call('set prefix=($root)//grub2\n'),
call('search --fs-uuid --set=root 0815\n'),
call('set prefix=($root)//grub2\n')
]
@@ -331,16 +328,12 @@ class TestBootLoaderConfigGrub2(object):
'cp', 'root_dir/usr/share/grub2/unicode.pf2',
'root_dir/boot/unicode.pf2'
]),
- call([
- 'cp', '-a', 'root_dir/usr/lib/grub2/x86_64-efi',
- 'root_dir/boot/grub2/x86_64-efi'
- ]),
call([
'grub2-mkimage', '-O', 'x86_64-efi',
'-o', 'root_dir/boot/efi/EFI/BOOT/bootx64.efi',
'-c', 'root_dir/boot/efi/EFI/BOOT/earlyboot.cfg',
'-p', '//grub2',
- '-d', 'root_dir/boot/grub2/x86_64-efi',
+ '-d', 'root_dir/usr/lib/grub2/x86_64-efi',
'ext2', 'iso9660', 'linux', 'echo', 'configfile',
'search_label', 'search_fs_file', 'search', 'search_fs_uuid',
'ls', 'normal', 'gzio', 'png', 'fat', 'gettext', 'font',
@@ -349,31 +342,21 @@ class TestBootLoaderConfigGrub2(object):
'efi_uga', 'linuxefi'
]),
call([
- 'cp', '-a', 'root_dir/usr/lib/grub2/i386-pc',
- 'root_dir/boot/grub2/i386-pc'
+ 'rsync', '-za', 'root_dir/usr/lib/grub2/x86_64-efi/',
+ 'root_dir/boot/grub2/x86_64-efi'
]),
call([
- 'grub2-mkimage', '-O', 'i386-pc',
- '-o', 'root_dir/boot/grub2/i386-pc/core.img',
- '-c', 'root_dir/boot/grub2/earlyboot.cfg',
- '-p', '//grub2',
- '-d', 'root_dir/boot/grub2/i386-pc',
- 'ext2', 'iso9660', 'linux', 'echo', 'configfile',
- 'search_label', 'search_fs_file', 'search', 'search_fs_uuid',
- 'ls', 'normal', 'gzio', 'png', 'fat', 'gettext', 'font',
- 'minicmd', 'gfxterm', 'gfxmenu', 'video', 'video_fb',
- 'xfs', 'btrfs', 'lvm', 'multiboot', 'part_gpt',
- 'part_msdos', 'biosdisk', 'vga', 'vbe', 'chain',
- 'boot'
+ 'rsync', '-za', 'root_dir/usr/lib/grub2/i386-pc/',
+ 'root_dir/boot/grub2/i386-pc'
])
]
@patch('kiwi.bootloader_config_grub2.Command.run')
- @patch('builtins.open')
+ #@patch('builtins.open')
@patch('os.path.exists')
@patch('platform.machine')
def test_setup_disk_boot_images_xen_guest(
- self, mock_machine, mock_exists, mock_open, mock_command
+ self, mock_machine, mock_exists, mock_command
):
mock_machine.return_value = 'x86_64'
self.firmware.efi_mode = mock.Mock(
@@ -386,49 +369,22 @@ class TestBootLoaderConfigGrub2(object):
return self.os_exists[arg]
mock_exists.side_effect = side_effect
- context_manager_mock = mock.Mock()
- mock_open.return_value = context_manager_mock
- file_mock = mock.Mock()
- enter_mock = mock.Mock()
- exit_mock = mock.Mock()
- enter_mock.return_value = file_mock
- setattr(context_manager_mock, '__enter__', enter_mock)
- setattr(context_manager_mock, '__exit__', exit_mock)
+
self.bootloader.setup_disk_boot_images('0815')
- mock_open.assert_called_once_with(
- 'root_dir/boot/grub2/earlyboot.cfg', 'w'
- )
- assert file_mock.write.call_args_list == [
- call('search --fs-uuid --set=root 0815\n'),
- call('set prefix=($root)//grub2\n'),
- ]
assert mock_command.call_args_list == [
call([
'cp', 'root_dir/usr/share/grub2/unicode.pf2',
'root_dir/boot/unicode.pf2'
]),
call([
- 'cp', '-a', 'root_dir/usr/lib/grub2/i386-pc',
+ 'rsync', '-za', 'root_dir/usr/lib/grub2/i386-pc/',
'root_dir/boot/grub2/i386-pc'
]),
call([
- 'cp', '-a', 'root_dir/usr/lib/grub2/x86_64-xen',
- 'root_dir/boot/grub2/x86_64-xen'
- ]),
- call([
- 'grub2-mkimage', '-O', 'i386-pc',
- '-o', 'root_dir/boot/grub2/i386-pc/core.img',
- '-c', 'root_dir/boot/grub2/earlyboot.cfg',
- '-p', '//grub2',
- '-d', 'root_dir/boot/grub2/i386-pc',
- 'ext2', 'iso9660', 'linux', 'echo', 'configfile',
- 'search_label', 'search_fs_file', 'search', 'search_fs_uuid',
- 'ls', 'normal', 'gzio', 'png', 'fat', 'gettext', 'font',
- 'minicmd', 'gfxterm', 'gfxmenu', 'video', 'video_fb', 'xfs',
- 'btrfs', 'lvm', 'multiboot', 'part_gpt', 'part_msdos',
- 'biosdisk', 'vga', 'vbe', 'chain', 'boot'
- ])
+ 'rsync', '-za', 'root_dir/usr/lib/grub2/x86_64-xen/',
+ 'root_dir/boot/grub2/x86_64-xen']
+ )
]
@patch('kiwi.bootloader_config_grub2.Command.run')
@@ -496,16 +452,12 @@ class TestBootLoaderConfigGrub2(object):
'cp', 'root_dir/usr/share/grub2/unicode.pf2',
'root_dir/boot/unicode.pf2'
]),
- call([
- 'cp', '-a', 'root_dir/usr/lib/grub2/x86_64-efi',
- 'root_dir/boot/grub2/x86_64-efi'
- ]),
call([
'grub2-mkimage', '-O', 'x86_64-efi',
'-o', 'root_dir//EFI/BOOT/bootx64.efi',
'-c', 'root_dir//EFI/BOOT/earlyboot.cfg',
'-p', '//grub2',
- '-d', 'root_dir/boot/grub2/x86_64-efi',
+ '-d', 'root_dir/usr/lib/grub2/x86_64-efi',
'ext2', 'iso9660', 'linux', 'echo', 'configfile',
'search_label', 'search_fs_file', 'search', 'search_fs_uuid',
'ls', 'normal', 'gzio', 'png', 'fat', 'gettext', 'font',
@@ -513,6 +465,10 @@ class TestBootLoaderConfigGrub2(object):
'btrfs', 'lvm', 'multiboot', 'part_gpt', 'efi_gop',
'efi_uga', 'linuxefi'
]),
+ call([
+ 'rsync', '-za', 'root_dir/usr/lib/grub2/x86_64-efi/',
+ 'root_dir/boot/grub2/x86_64-efi'
+ ]),
call([
'qemu-img', 'create', 'root_dir/boot/x86_64/efi', '4M'
]),
@@ -574,7 +530,7 @@ class TestBootLoaderConfigGrub2(object):
mock_exists.side_effect = side_effect
self.bootloader.setup_install_boot_images(self.mbrid)
assert mock_command.call_args_list[0] == call([
- 'rsync', '-zav',
+ 'rsync', '-za',
'root_dir/usr/share/grub2/themes/some-theme',
'root_dir/boot/grub2/themes'
])
diff --git a/test/unit/bootloader_install_grub2_test.py b/test/unit/bootloader_install_grub2_test.py
index 8a4e2249..95d0ccf3 100644
--- a/test/unit/bootloader_install_grub2_test.py
+++ b/test/unit/bootloader_install_grub2_test.py
@@ -3,64 +3,106 @@ from mock import patch
from mock import call
import mock
-
+import kiwi
from . import nose_helper
from kiwi.exceptions import *
from kiwi.bootloader_install_grub2 import BootLoaderInstallGrub2
+from kiwi.defaults import Defaults
class TestBootLoaderInstallGrub2(object):
- def setup(self):
+ @patch('kiwi.bootloader_install_grub2.mkdtemp')
+ def setup(self, mock_mkdtemp):
+ tmpdirs = ['tmp_boot', 'tmp_root']
+
+ def side_effect():
+ return tmpdirs.pop()
+
+ mock_mkdtemp.side_effect = side_effect
device_provider = mock.Mock()
device_provider.get_device = mock.Mock(
return_value='/dev/some-device'
)
+ self.path = mock.Mock()
+ kiwi.bootloader_install_grub2.Path = self.path
self.bootloader = BootLoaderInstallGrub2(
- 'root_dir', device_provider
+ 'root_dir', device_provider, {
+ 'boot_device': '/dev/mapper/loop0p2',
+ 'root_device': '/dev/mapper/loop0p1'
+ }
)
+ assert self.bootloader.mountpoint_root == 'tmp_root'
+ assert self.bootloader.mountpoint_boot == 'tmp_boot'
+ assert self.bootloader.extra_boot_partition is True
- def test_post_init(self):
- self.bootloader.post_init(None)
- assert self.bootloader.temporary_boot_dir is None
+ @raises(KiwiBootLoaderGrubInstallError)
+ def test_post_init_no_boot_device(self):
+ self.bootloader.post_init({})
+
+ @raises(KiwiBootLoaderGrubInstallError)
+ def test_post_init_no_root_device(self):
+ self.bootloader.post_init({'boot_device': 'a'})
- @patch('builtins.open')
@patch('kiwi.bootloader_install_grub2.Command.run')
- @patch('kiwi.bootloader_install_grub2.mkdtemp')
- @patch('kiwi.bootloader_install_grub2.NamedTemporaryFile')
- def test_install(self, mock_tmpfile, mock_mkdtemp, mock_command, mock_open):
- mock_mkdtemp.return_value = 'tmpdir'
- tmpfile = mock.Mock()
- tmpfile.name = 'tmpfile'
- mock_tmpfile.return_value = tmpfile
- context_manager_mock = mock.Mock()
- mock_open.return_value = context_manager_mock
- file_mock = mock.Mock()
- enter_mock = mock.Mock()
- exit_mock = mock.Mock()
- enter_mock.return_value = file_mock
- setattr(context_manager_mock, '__enter__', enter_mock)
- setattr(context_manager_mock, '__exit__', exit_mock)
-
+ def test_install_with_extra_boot_partition(self, mock_command):
self.bootloader.install()
-
- mock_open.assert_called_once_with('tmpfile', 'w')
- file_mock.write.assert_called_once_with(
- '(hd0) /dev/some-device\n'
- )
assert mock_command.call_args_list == [
- call(['cp', '-a', 'root_dir/boot/', 'tmpdir']),
+ call(['mount', '/dev/mapper/loop0p2', 'tmp_boot']),
+ call(['mount', '/dev/mapper/loop0p1', 'tmp_root']),
call([
- 'grub2-bios-setup', '-f',
- '-d', 'tmpdir/boot/grub2/i386-pc',
- '-m', 'tmpfile',
+ 'grub2-install', '--skip-fs-probe',
+ '--directory', 'tmp_root/usr/lib/grub2/i386-pc',
+ '--boot-directory', 'tmp_boot',
+ '--target', 'i386-pc',
+ '--modules', ' '.join(Defaults.get_grub_bios_modules()),
'/dev/some-device'
])
]
- @patch('kiwi.bootloader_install_grub2.Path.wipe')
- def test_desstructor(self, mock_wipe):
- self.bootloader.temporary_boot_dir = 'tmpdir'
+ @patch('kiwi.bootloader_install_grub2.Command.run')
+ def test_install(self, mock_command):
+ self.bootloader.extra_boot_partition = False
+ self.bootloader.install()
+ assert mock_command.call_args_list == [
+ call(['mount', '/dev/mapper/loop0p1', 'tmp_root']),
+ call([
+ 'grub2-install', '--skip-fs-probe',
+ '--directory', 'tmp_root/usr/lib/grub2/i386-pc',
+ '--boot-directory', 'tmp_root/boot',
+ '--target', 'i386-pc',
+ '--modules', ' '.join(Defaults.get_grub_bios_modules()),
+ '/dev/some-device'
+ ])
+ ]
+
+ @patch('kiwi.bootloader_install_grub2.Command.run')
+ @patch('kiwi.logger.log.warning')
+ @patch('time.sleep')
+ def test_desstructor(self, mock_sleep, mock_warn, mock_command):
+ command_return_values = [False, False, False, True, True, True]
+
+ def side_effect(arg):
+ if not command_return_values.pop():
+ raise Exception
+
+ mock_command.side_effect = side_effect
self.bootloader.__del__()
- mock_wipe.assert_called_once_with('tmpdir')
- self.bootloader.temporary_boot_dir = None
+ self.path.remove.assert_called_once_with('tmp_root')
+ assert mock_command.call_args_list == [
+ call(['mountpoint', 'tmp_root']),
+ call(['umount', 'tmp_root']),
+ call(['mountpoint', 'tmp_boot']),
+ call(['umount', 'tmp_boot']),
+ call(['umount', 'tmp_boot']),
+ call(['umount', 'tmp_boot'])
+ ]
+
+ @patch('kiwi.bootloader_install_grub2.Command.run')
+ def test_desstructor_nothing_mounted(self, mock_command):
+ mock_command.side_effect = Exception
+ self.bootloader.__del__()
+ assert mock_command.call_args_list == [
+ call(['mountpoint', 'tmp_root']),
+ call(['mountpoint', 'tmp_boot'])
+ ]
diff --git a/test/unit/disk_builder_test.py b/test/unit/disk_builder_test.py
index 98ad4567..6841451f 100644
--- a/test/unit/disk_builder_test.py
+++ b/test/unit/disk_builder_test.py
@@ -354,12 +354,16 @@ class TestDiskBuilder(object):
@patch('kiwi.disk_builder.VolumeManager')
@patch('builtins.open')
@patch('kiwi.disk_builder.Command.run')
+ @patch('os.path.exists')
def test_create_volume_managed_root(
- self, mock_command, mock_open, mock_volume_manager, mock_fs
+ self, mock_exists, mock_command, mock_open, mock_volume_manager, mock_fs
):
+ mock_exists.return_value = True
volume_manager = mock.Mock()
volume_manager.get_device = mock.Mock(
- return_value={'root': '/dev/systemVG/LVRoot'}
+ return_value={
+ 'root': MappedDevice('/dev/systemVG/LVRoot', mock.Mock())
+ }
)
mock_volume_manager.return_value = volume_manager
filesystem = mock.Mock()