Refactor grub2 bootloader installation
Make use of grub2-install to install the bootloader
This commit is contained in:
parent
f43546fd59
commit
147c0706eb
@ -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):
|
||||
"""
|
||||
|
||||
@ -15,55 +15,114 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with kiwi. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
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)
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with kiwi. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
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'
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -49,6 +49,10 @@ class KiwiBootLoaderGrubFontError(KiwiError):
|
||||
pass
|
||||
|
||||
|
||||
class KiwiBootLoaderGrubInstallError(KiwiError):
|
||||
pass
|
||||
|
||||
|
||||
class KiwiBootLoaderGrubModulesError(KiwiError):
|
||||
pass
|
||||
|
||||
|
||||
@ -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'
|
||||
])
|
||||
|
||||
@ -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'])
|
||||
]
|
||||
|
||||
@ -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()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user