Added isolinux bootloader support
This commit is contained in:
parent
48a96d6528
commit
61ea327a4c
@ -17,6 +17,7 @@
|
||||
#
|
||||
# project
|
||||
from bootloader_config_grub2 import BootLoaderConfigGrub2
|
||||
from bootloader_config_isolinux import BootLoaderConfigIsoLinux
|
||||
|
||||
from exceptions import (
|
||||
KiwiBootLoaderConfigSetupError
|
||||
@ -33,6 +34,10 @@ class BootLoaderConfig(object):
|
||||
return BootLoaderConfigGrub2(
|
||||
xml_state, source_dir
|
||||
)
|
||||
elif name == 'isolinux':
|
||||
return BootLoaderConfigIsoLinux(
|
||||
xml_state, source_dir
|
||||
)
|
||||
else:
|
||||
raise KiwiBootLoaderConfigSetupError(
|
||||
'Support for %s bootloader config not implemented' % name
|
||||
|
||||
@ -200,7 +200,7 @@ class BootLoaderConfigGrub2(BootLoaderConfigBase):
|
||||
self.source_dir + '/boot/mbrid'
|
||||
)
|
||||
|
||||
self.__copy_unicode_font_to_boot_directory(lookup_path)
|
||||
self.__copy_theme_data_to_boot_directory(lookup_path)
|
||||
|
||||
if self.firmware.efi_mode() == 'uefi':
|
||||
log.info('--> Using signed secure boot efi image')
|
||||
@ -226,7 +226,7 @@ class BootLoaderConfigGrub2(BootLoaderConfigBase):
|
||||
if self.firmware.efi_mode():
|
||||
self.efi_boot_path = self.create_efi_path()
|
||||
|
||||
self.__copy_unicode_font_to_boot_directory(lookup_path)
|
||||
self.__copy_theme_data_to_boot_directory(lookup_path)
|
||||
|
||||
if self.firmware.efi_mode() == 'efi':
|
||||
log.info('--> Creating unsigned efi image')
|
||||
@ -468,11 +468,11 @@ class BootLoaderConfigGrub2(BootLoaderConfigBase):
|
||||
selected_gfxmode = gfxmode[requested_gfxmode]
|
||||
return selected_gfxmode
|
||||
|
||||
def __copy_unicode_font_to_boot_directory(self, lookup_path):
|
||||
def __copy_theme_data_to_boot_directory(self, lookup_path):
|
||||
if not lookup_path:
|
||||
lookup_path = self.source_dir
|
||||
boot_unicode_font = self.source_dir + '/boot/unicode.pf2'
|
||||
if not os.path.exists(boot_unicode_font):
|
||||
if not lookup_path:
|
||||
lookup_path = self.source_dir
|
||||
unicode_font = lookup_path + '/usr/share/grub2/unicode.pf2'
|
||||
try:
|
||||
Command.run(
|
||||
@ -483,6 +483,18 @@ class BootLoaderConfigGrub2(BootLoaderConfigBase):
|
||||
'Unicode font %s not found' % unicode_font
|
||||
)
|
||||
|
||||
boot_theme_dir = self.source_dir + '/boot/grub2/themes'
|
||||
if self.theme and not os.path.exists(boot_theme_dir):
|
||||
Path.create(boot_theme_dir)
|
||||
theme_dir = \
|
||||
lookup_path + '/usr/share/grub2/themes/' + self.theme
|
||||
if os.path.exists(theme_dir):
|
||||
Command.run(
|
||||
['rsync', '-zav', theme_dir, boot_theme_dir],
|
||||
)
|
||||
else:
|
||||
log.warning('Theme %s not found', theme_dir)
|
||||
|
||||
def __copy_efi_modules_to_boot_directory(self, lookup_path):
|
||||
self.__copy_modules_to_boot_directory_from(
|
||||
self.__get_efi_modules_path(lookup_path)
|
||||
|
||||
155
kiwi/bootloader_config_isolinux.py
Normal file
155
kiwi/bootloader_config_isolinux.py
Normal file
@ -0,0 +1,155 @@
|
||||
# Copyright (c) 2015 SUSE Linux GmbH. All rights reserved.
|
||||
#
|
||||
# This file is part of kiwi.
|
||||
#
|
||||
# kiwi is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# kiwi is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with kiwi. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
import os
|
||||
import platform
|
||||
|
||||
# project
|
||||
from logger import log
|
||||
from bootloader_config_base import BootLoaderConfigBase
|
||||
from bootloader_template_isolinux import BootLoaderTemplateIsoLinux
|
||||
from command import Command
|
||||
from path import Path
|
||||
|
||||
from exceptions import (
|
||||
KiwiTemplateError,
|
||||
KiwiBootLoaderIsoLinuxPlatformError
|
||||
)
|
||||
|
||||
|
||||
class BootLoaderConfigIsoLinux(BootLoaderConfigBase):
|
||||
"""
|
||||
isolinux bootloader configuration.
|
||||
"""
|
||||
def post_init(self):
|
||||
arch = platform.machine()
|
||||
if arch == 'x86_64':
|
||||
self.arch = arch
|
||||
else:
|
||||
raise KiwiBootLoaderIsoLinuxPlatformError(
|
||||
'host architecture %s not supported for isolinux setup' % arch
|
||||
)
|
||||
|
||||
self.gfxmode = self.xml_state.build_type.get_vga()
|
||||
self.timeout = self.get_boot_timeout_seconds()
|
||||
self.cmdline = self.get_boot_cmdline()
|
||||
self.cmdline_failsafe = self.get_failsafe_boot_cmdline()
|
||||
self.failsafe_boot = self.failsafe_boot_entry_requested()
|
||||
self.hypervisor_domain = self.get_hypervisor_domain()
|
||||
|
||||
self.multiboot = False
|
||||
if self.hypervisor_domain:
|
||||
if self.hypervisor_domain == 'dom0':
|
||||
self.multiboot = True
|
||||
elif self.hypervisor_domain == 'domU':
|
||||
self.multiboot = False
|
||||
|
||||
self.isolinux = BootLoaderTemplateIsoLinux()
|
||||
self.config = None
|
||||
self.config_message = None
|
||||
|
||||
def write(self):
|
||||
"""
|
||||
Write isolinux.cfg and isolinux.msg file
|
||||
"""
|
||||
log.info('Writing isolinux.cfg file')
|
||||
config_dir = self.__get_iso_boot_path()
|
||||
config_file = config_dir + '/isolinux.cfg'
|
||||
if self.config:
|
||||
Path.create(config_dir)
|
||||
with open(config_file, 'w') as config:
|
||||
config.write(self.config)
|
||||
|
||||
config_file_message = config_dir + '/isolinux.msg'
|
||||
if self.config_message:
|
||||
with open(config_file_message, 'w') as config:
|
||||
config.write(self.config_message)
|
||||
|
||||
def setup_install_image_config(
|
||||
self, mbrid, hypervisor='xen.gz', kernel='linux', initrd='initrd'
|
||||
):
|
||||
"""
|
||||
Create isolinux.cfg in memory from a template suitable to boot
|
||||
from an ISO image in BIOS boot mode
|
||||
"""
|
||||
# mbrid parameter is not used, the information is placed as the
|
||||
# application id when creating the iso filesystem. Thus not part
|
||||
# of the configuration file
|
||||
log.info('Creating install config file from template')
|
||||
parameters = {
|
||||
'default_boot': 'Boot_from_Hard_Disk',
|
||||
'kernel_file': kernel,
|
||||
'initrd_file': initrd,
|
||||
'boot_options': self.cmdline,
|
||||
'failsafe_boot_options': self.cmdline_failsafe,
|
||||
'gfxmode': self.gfxmode,
|
||||
'boot_timeout': self.timeout,
|
||||
'title': self.get_menu_entry_install_title()
|
||||
}
|
||||
if self.multiboot:
|
||||
log.info('--> Using multiboot install template')
|
||||
parameters['hypervisor'] = hypervisor
|
||||
template = self.isolinux.get_multiboot_install_template(
|
||||
self.failsafe_boot, self.__have_theme()
|
||||
)
|
||||
else:
|
||||
log.info('--> Using install template')
|
||||
template = self.isolinux.get_install_template(
|
||||
self.failsafe_boot, self.__have_theme()
|
||||
)
|
||||
try:
|
||||
self.config = template.substitute(parameters)
|
||||
template = self.isolinux.get_install_message_template()
|
||||
self.config_message = template.substitute(parameters)
|
||||
except Exception as e:
|
||||
raise KiwiTemplateError(
|
||||
'%s: %s' % (type(e).__name__, format(e))
|
||||
)
|
||||
|
||||
def setup_live_image_config(
|
||||
self, mbrid, hypervisor='xen.gz', kernel='linux', initrd='initrd'
|
||||
):
|
||||
# TODO
|
||||
pass
|
||||
|
||||
def setup_install_boot_images(self, mbrid, lookup_path=None):
|
||||
# mbrid parameter is not used, because only isolinux loader
|
||||
# binary and possible theming files are copied
|
||||
self.__copy_loader_data_to_boot_directory(lookup_path)
|
||||
|
||||
def setup_live_boot_images(self, mbrid, lookup_path=None):
|
||||
# same action as for install media
|
||||
self.setup_install_boot_images(None, lookup_path)
|
||||
|
||||
def __copy_loader_data_to_boot_directory(self, lookup_path):
|
||||
if not lookup_path:
|
||||
lookup_path = self.source_dir
|
||||
loader_data = lookup_path + '/image/loader/'
|
||||
Path.create(self.__get_iso_boot_path())
|
||||
Command.run(
|
||||
[
|
||||
'rsync', '-zav', loader_data, self.__get_iso_boot_path()
|
||||
]
|
||||
)
|
||||
|
||||
def __get_iso_boot_path(self):
|
||||
return self.source_dir + '/boot/' + self.arch + '/loader'
|
||||
|
||||
def __have_theme(self):
|
||||
if os.path.exists(self.__get_iso_boot_path() + '/bootlogo'):
|
||||
return True
|
||||
return False
|
||||
@ -45,25 +45,20 @@ class BootLoaderTemplateGrub2(object):
|
||||
''').strip() + self.cr
|
||||
|
||||
self.header_gfxterm = dedent('''
|
||||
set font=($$root)${bootpath}/unicode.pf2
|
||||
if loadfont $$font ;then
|
||||
set gfxmode=${gfxmode}
|
||||
insmod all_video
|
||||
insmod gfxterm
|
||||
terminal_output gfxterm
|
||||
fi
|
||||
set gfxmode=${gfxmode}
|
||||
insmod all_video
|
||||
insmod gfxterm
|
||||
terminal_output gfxterm
|
||||
''').strip() + self.cr
|
||||
|
||||
self.header_serial = dedent('''
|
||||
set font=${bootpath}/unicode.pf2
|
||||
if loadfont $$font ;then
|
||||
serial --speed=9600 --unit=0 --word=8 --parity=no --stop=1
|
||||
terminal_input serial
|
||||
terminal_output serial
|
||||
fi
|
||||
serial --speed=9600 --unit=0 --word=8 --parity=no --stop=1
|
||||
terminal_input serial
|
||||
terminal_output serial
|
||||
''').strip() + self.cr
|
||||
|
||||
self.header_theme = dedent('''
|
||||
set font=($$root)${bootpath}/unicode.pf2
|
||||
if loadfont ($$root)${bootpath}/grub2/themes/${theme}/ascii.pf2;then
|
||||
loadfont ($$root)${bootpath}/grub2/themes/${theme}/DejaVuSans-Bold14.pf2
|
||||
loadfont ($$root)${bootpath}/grub2/themes/${theme}/DejaVuSans10.pf2
|
||||
@ -73,6 +68,17 @@ class BootLoaderTemplateGrub2(object):
|
||||
fi
|
||||
''').strip() + self.cr
|
||||
|
||||
self.header_theme_iso = dedent('''
|
||||
set font=($$root)/boot/unicode.pf2
|
||||
if loadfont ($$root)/boot/grub2/themes/${theme}/ascii.pf2;then
|
||||
loadfont ($$root)/boot/grub2/themes/${theme}/DejaVuSans-Bold14.pf2
|
||||
loadfont ($$root)/boot/grub2/themes/${theme}/DejaVuSans10.pf2
|
||||
loadfont ($$root)/boot/grub2/themes/${theme}/DejaVuSans12.pf2
|
||||
loadfont ($$root)/boot/grub2/themes/${theme}/ascii.pf2
|
||||
set theme=($$root)/boot/grub2/themes/${theme}/theme.txt
|
||||
fi
|
||||
''').strip() + self.cr
|
||||
|
||||
self.menu_entry_hybrid = dedent('''
|
||||
menuentry "${title}" --class os {
|
||||
echo Loading kernel...
|
||||
@ -263,7 +269,7 @@ class BootLoaderTemplateGrub2(object):
|
||||
template_data += self.header_gfxterm
|
||||
else:
|
||||
template_data += self.header_serial
|
||||
template_data += self.header_theme
|
||||
template_data += self.header_theme_iso
|
||||
template_data += self.menu_install_harddisk_entry
|
||||
if hybrid:
|
||||
template_data += self.menu_install_entry_hybrid
|
||||
@ -287,7 +293,7 @@ class BootLoaderTemplateGrub2(object):
|
||||
template_data += self.header_gfxterm
|
||||
else:
|
||||
template_data += self.header_serial
|
||||
template_data += self.header_theme
|
||||
template_data += self.header_theme_iso
|
||||
template_data += self.menu_install_harddisk_entry
|
||||
template_data += self.menu_install_entry_multiboot
|
||||
if failsafe:
|
||||
|
||||
165
kiwi/bootloader_template_isolinux.py
Normal file
165
kiwi/bootloader_template_isolinux.py
Normal file
@ -0,0 +1,165 @@
|
||||
# Copyright (c) 2015 SUSE Linux GmbH. All rights reserved.
|
||||
#
|
||||
# This file is part of kiwi.
|
||||
#
|
||||
# kiwi is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# kiwi is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with kiwi. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
from string import Template
|
||||
from textwrap import dedent
|
||||
|
||||
|
||||
class BootLoaderTemplateIsoLinux(object):
|
||||
"""
|
||||
isolinux configuraton file templates
|
||||
"""
|
||||
def __init__(self):
|
||||
self.cr = '\n'
|
||||
|
||||
self.install_message = dedent('''
|
||||
Welcome !
|
||||
|
||||
Boot_from_Hard_Disk
|
||||
Install_${title}
|
||||
Failsafe_--_Install_${title}
|
||||
|
||||
|
||||
Have a lot of fun...
|
||||
''').strip() + self.cr
|
||||
|
||||
self.message = dedent('''
|
||||
Welcome !
|
||||
|
||||
${title}
|
||||
Failsafe_${title}
|
||||
|
||||
|
||||
Have a lot of fun...
|
||||
''').strip() + self.cr
|
||||
|
||||
self.header = dedent('''
|
||||
# kiwi generated isolinux config file
|
||||
implicit 1
|
||||
prompt 1
|
||||
timeout ${boot_timeout}
|
||||
display isolinux.msg
|
||||
default ${default_boot}
|
||||
ui gfxboot bootlogo isolinux.msg
|
||||
''').strip() + self.cr
|
||||
|
||||
self.ui_theme = dedent('''
|
||||
ui gfxboot bootlogo isolinux.msg
|
||||
''').strip() + self.cr
|
||||
|
||||
self.ui_plain = dedent('''
|
||||
ui menu.c32
|
||||
''').strip() + self.cr
|
||||
|
||||
self.menu_install_harddisk_entry = dedent('''
|
||||
label Boot_from_Hard_Disk
|
||||
localboot 0x80
|
||||
''').strip() + self.cr
|
||||
|
||||
self.menu_install_entry_multiboot = dedent('''
|
||||
label Install_${title}
|
||||
kernel mboot.c32
|
||||
append ${hypervisor} --- ${kernel_file} vga=${gfxmode} ${boot_options} cdinst=1 kiwi_hybrid=1 showopts --- ${initrd_file} showopts
|
||||
''').strip() + self.cr
|
||||
|
||||
self.menu_install_entry_failsafe_multiboot = dedent('''
|
||||
label Failsafe_--_Install_${title}
|
||||
kernel mboot.c32
|
||||
append ${hypervisor} --- ${kernel_file} vga=${gfxmode} ${failsafe_boot_options} cdinst=1 kiwi_hybrid=1 showopts --- ${initrd_file} showopts
|
||||
''').strip() + self.cr
|
||||
|
||||
self.menu_entry_multiboot = dedent('''
|
||||
label ${title}
|
||||
kernel mboot.c32
|
||||
append ${hypervisor} --- ${kernel_file} vga=${gfxmode} ${boot_options} cdinst=1 kiwi_hybrid=1 showopts --- ${initrd_file} showopts
|
||||
''').strip() + self.cr
|
||||
|
||||
self.menu_entry_failsafe_multiboot = dedent('''
|
||||
label Failsafe_--_${title}
|
||||
kernel mboot.c32
|
||||
append ${hypervisor} --- ${kernel_file} vga=${gfxmode} ${failsafe_boot_options} cdinst=1 kiwi_hybrid=1 showopts --- ${initrd_file} showopts
|
||||
''').strip() + self.cr
|
||||
|
||||
self.menu_install_entry = dedent('''
|
||||
label Install_${title}
|
||||
kernel ${kernel_file}
|
||||
append initrd=${initrd_file} vga=${gfxmode} ${boot_options} cdinst=1 kiwi_hybrid=1 showopts
|
||||
''').strip() + self.cr
|
||||
|
||||
self.menu_install_entry_failsafe = dedent('''
|
||||
label Failsafe_--_Install_${title}
|
||||
kernel ${kernel_file}
|
||||
append initrd=${initrd_file} vga=${gfxmode} ${failsafe_boot_options} cdinst=1 kiwi_hybrid=1 showopts
|
||||
''').strip() + self.cr
|
||||
|
||||
self.menu_entry = dedent('''
|
||||
label ${title}
|
||||
kernel ${kernel_file}
|
||||
append initrd=${initrd_file} vga=${gfxmode} ${boot_options} cdinst=1 kiwi_hybrid=1 showopts
|
||||
''').strip() + self.cr
|
||||
|
||||
self.menu_entry_failsafe = dedent('''
|
||||
label Failsafe_--_${title}
|
||||
kernel ${kernel_file}
|
||||
append initrd=${initrd_file} vga=${gfxmode} ${failsafe_boot_options} cdinst=1 kiwi_hybrid=1 showopts
|
||||
''').strip() + self.cr
|
||||
|
||||
def get_install_message_template(self):
|
||||
"""
|
||||
bootloader template for text message file in install mode.
|
||||
isolinux displays this as menu if no graphics mode can be
|
||||
initialized
|
||||
"""
|
||||
return Template(self.install_message)
|
||||
|
||||
def get_message_template(self):
|
||||
"""
|
||||
bootloader template for text message file. isolinux
|
||||
displays this as menu if no graphics mode can be initialized
|
||||
"""
|
||||
return Template(self.message)
|
||||
|
||||
def get_install_template(self, failsafe=True, with_theme=True):
|
||||
"""
|
||||
bootloader configuration template for install media
|
||||
"""
|
||||
template_data = self.header
|
||||
if with_theme:
|
||||
self.ui_theme
|
||||
else:
|
||||
self.ui_plain
|
||||
template_data += self.menu_install_harddisk_entry
|
||||
template_data += self.menu_install_entry
|
||||
if failsafe:
|
||||
template_data += self.menu_install_entry_failsafe
|
||||
return Template(template_data)
|
||||
|
||||
def get_multiboot_install_template(self, failsafe=True, with_theme=True):
|
||||
"""
|
||||
bootloader configuration template for install media with
|
||||
hypervisor, e.g Xen dom0
|
||||
"""
|
||||
template_data = self.header
|
||||
if with_theme:
|
||||
self.ui_theme
|
||||
else:
|
||||
self.ui_plain
|
||||
template_data += self.menu_install_harddisk_entry
|
||||
template_data += self.menu_install_entry_multiboot
|
||||
if failsafe:
|
||||
template_data += self.menu_install_entry_failsafe_multiboot
|
||||
return Template(template_data)
|
||||
@ -121,6 +121,10 @@ class CommandProcess(object):
|
||||
result = namedtuple(
|
||||
'result', ['stderr', 'returncode']
|
||||
)
|
||||
if watch:
|
||||
log.debug(command_error_output)
|
||||
else:
|
||||
log.debug('%s: %s', self.log_topic, command_error_output)
|
||||
return result(
|
||||
stderr=command_error_output,
|
||||
returncode=self.command.process.returncode
|
||||
|
||||
@ -29,10 +29,6 @@ class KiwiError(Exception):
|
||||
return format(self.message)
|
||||
|
||||
|
||||
class KiwiBootLoaderTargetError(KiwiError):
|
||||
pass
|
||||
|
||||
|
||||
class KiwiBootLoaderConfigSetupError(KiwiError):
|
||||
pass
|
||||
|
||||
@ -57,6 +53,14 @@ class KiwiBootLoaderInstallSetupError(KiwiError):
|
||||
pass
|
||||
|
||||
|
||||
class KiwiBootLoaderIsoLinuxPlatformError(KiwiError):
|
||||
pass
|
||||
|
||||
|
||||
class KiwiBootLoaderTargetError(KiwiError):
|
||||
pass
|
||||
|
||||
|
||||
class KiwiBootStrapPhaseFailed(KiwiError):
|
||||
pass
|
||||
|
||||
@ -129,6 +133,10 @@ class KiwiInvalidVolumeName(KiwiError):
|
||||
pass
|
||||
|
||||
|
||||
class KiwiIsoLoaderError(KiwiError):
|
||||
pass
|
||||
|
||||
|
||||
class KiwiLoadCommandUndefined(KiwiError):
|
||||
pass
|
||||
|
||||
|
||||
41
kiwi/filesystem_isofs.py
Normal file
41
kiwi/filesystem_isofs.py
Normal file
@ -0,0 +1,41 @@
|
||||
# Copyright (c) 2015 SUSE Linux GmbH. All rights reserved.
|
||||
#
|
||||
# This file is part of kiwi.
|
||||
#
|
||||
# kiwi is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# kiwi is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with kiwi. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
# project
|
||||
from iso import Iso
|
||||
from command import Command
|
||||
from filesystem_base import FileSystemBase
|
||||
|
||||
|
||||
class FileSystemIsoFs(FileSystemBase):
|
||||
"""
|
||||
Implements creation of iso filesystem
|
||||
"""
|
||||
def post_init(self, custom_args):
|
||||
self.custom_args = custom_args
|
||||
|
||||
def create_on_file(self, filename, label=None):
|
||||
# there is no label which could be set for an iso filesystem
|
||||
# thus this parameter is not used
|
||||
iso = Iso(self.source_dir)
|
||||
iso.init_iso_creation_parameters(self.custom_args)
|
||||
iso.add_efi_loader_parameters()
|
||||
Command.run(
|
||||
['genisoimage'] + iso.get_iso_creation_parameters() + [
|
||||
'-o', filename, self.source_dir
|
||||
]
|
||||
)
|
||||
@ -22,6 +22,7 @@ import os
|
||||
from command import Command
|
||||
from bootloader_config import BootLoaderConfig
|
||||
from filesystem_squashfs import FileSystemSquashFs
|
||||
from filesystem_isofs import FileSystemIsoFs
|
||||
from image_identifier import ImageIdentifier
|
||||
from path import Path
|
||||
from checksum import Checksum
|
||||
@ -42,11 +43,21 @@ class InstallImageBuilder(object):
|
||||
):
|
||||
self.target_dir = target_dir
|
||||
self.disk_image = disk_image
|
||||
self.machine = xml_state.get_build_type_machine_section()
|
||||
self.boot_image_task = boot_image_task
|
||||
self.xml_state = xml_state
|
||||
self.isoname = ''.join(
|
||||
[
|
||||
target_dir, '/',
|
||||
xml_state.xml_data.get_name(), '.install.iso'
|
||||
]
|
||||
)
|
||||
|
||||
self.mbrid = ImageIdentifier()
|
||||
self.mbrid.calculate_id()
|
||||
|
||||
self.media_dir = None
|
||||
self.custom_iso_args = None
|
||||
|
||||
def create_install_iso(self):
|
||||
"""
|
||||
@ -56,6 +67,12 @@ class InstallImageBuilder(object):
|
||||
self.media_dir = mkdtemp(
|
||||
prefix='install-media.', dir=self.target_dir
|
||||
)
|
||||
# custom iso metadata
|
||||
self.custom_iso_args = [
|
||||
'-V', '"KIWI Installation System"',
|
||||
'-A', self.mbrid.get_id()
|
||||
]
|
||||
|
||||
# the install image transfer is checked against a checksum
|
||||
log.info('Creating disk image checksum')
|
||||
checksum = Checksum(self.disk_image)
|
||||
@ -77,26 +94,43 @@ class InstallImageBuilder(object):
|
||||
['mv', squashed_image_file, self.media_dir]
|
||||
)
|
||||
|
||||
# setup bootloader config to boot the ISO via isolinux
|
||||
bootloader_config_isolinux = BootLoaderConfig.new(
|
||||
'isolinux', self.xml_state, self.media_dir
|
||||
)
|
||||
bootloader_config_isolinux.setup_install_boot_images(
|
||||
mbrid=None,
|
||||
lookup_path=self.boot_image_task.boot_root_directory
|
||||
)
|
||||
bootloader_config_isolinux.setup_install_image_config(
|
||||
mbrid=None
|
||||
)
|
||||
bootloader_config_isolinux.write()
|
||||
|
||||
# setup bootloader config to boot the ISO via EFI
|
||||
self.bootloader_config_grub = BootLoaderConfig.new(
|
||||
bootloader_config_grub = BootLoaderConfig.new(
|
||||
'grub2', self.xml_state, self.media_dir
|
||||
)
|
||||
self.bootloader_config_grub.setup_install_boot_images(
|
||||
bootloader_config_grub.setup_install_boot_images(
|
||||
mbrid=self.mbrid,
|
||||
lookup_path=self.boot_image_task.boot_root_directory
|
||||
)
|
||||
self.bootloader_config_grub.setup_install_image_config(
|
||||
self.mbrid
|
||||
bootloader_config_grub.setup_install_image_config(
|
||||
mbrid=self.mbrid
|
||||
)
|
||||
self.bootloader_config_grub.write()
|
||||
|
||||
# setup bootloader config to boot the ISO via isolinux
|
||||
# TODO
|
||||
bootloader_config_grub.write()
|
||||
|
||||
# create initrd for install image
|
||||
self.__create_iso_install_kernel_and_initrd()
|
||||
|
||||
# TODO
|
||||
# create iso filesystem from self.media_dir and make it hybrid
|
||||
iso_image = FileSystemIsoFs(
|
||||
device_provider=None,
|
||||
source_dir=self.media_dir,
|
||||
custom_args=self.custom_iso_args
|
||||
)
|
||||
iso_image.create_on_file(self.isoname)
|
||||
|
||||
def create_install_pxe_archive(self):
|
||||
# TODO
|
||||
@ -113,7 +147,14 @@ class InstallImageBuilder(object):
|
||||
'No kernel in boot image tree %s found' %
|
||||
self.boot_image_task.boot_root_directory
|
||||
)
|
||||
# TODO: for xen dom0 boot the hypervisor needs to be copied too
|
||||
if self.machine and self.machine.get_domain() == 'dom0':
|
||||
if kernel.get_xen_hypervisor():
|
||||
kernel.copy_xen_hypervisor(boot_path, '/xen.gz')
|
||||
else:
|
||||
raise KiwiInstallBootImageError(
|
||||
'No hypervisor in boot image tree %s found' %
|
||||
self.boot_image_task.boot_root_directory
|
||||
)
|
||||
self.boot_image_task.create_initrd(self.mbrid)
|
||||
Command.run(
|
||||
[
|
||||
@ -133,6 +174,6 @@ class InstallImageBuilder(object):
|
||||
iso_system.write('IMAGE="%s"\n' % diskname)
|
||||
|
||||
def __del__(self):
|
||||
# if self.media_dir:
|
||||
# Path.wipe(self.media_dir)
|
||||
pass
|
||||
if self.media_dir:
|
||||
log.info('Cleaning up %s instance', type(self).__name__)
|
||||
Path.wipe(self.media_dir)
|
||||
|
||||
@ -157,9 +157,6 @@ class BootImageTask(object):
|
||||
compress = Compress(initrd_file_name)
|
||||
compress.xz()
|
||||
self.initrd_filename = compress.compressed_filename
|
||||
log.info(
|
||||
'--> created %s', self.initrd_filename
|
||||
)
|
||||
|
||||
def __import_system_description_elements(self):
|
||||
self.xml_state.copy_displayname(
|
||||
|
||||
114
kiwi/iso.py
Normal file
114
kiwi/iso.py
Normal file
@ -0,0 +1,114 @@
|
||||
# Copyright (c) 2015 SUSE Linux GmbH. All rights reserved.
|
||||
#
|
||||
# This file is part of kiwi.
|
||||
#
|
||||
# kiwi is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# kiwi is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with kiwi. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
import os
|
||||
import platform
|
||||
from tempfile import NamedTemporaryFile
|
||||
|
||||
# project
|
||||
from command import Command
|
||||
from exceptions import (
|
||||
KiwiIsoLoaderError
|
||||
)
|
||||
|
||||
|
||||
class Iso(object):
|
||||
"""
|
||||
Implements helper methods around the creation of an iso filesystem
|
||||
"""
|
||||
def __init__(self, source_dir):
|
||||
self.header_id = '7984fc91-a43f-4e45-bf27-6d3aa08b24cf'
|
||||
self.header_end_name = 'header_end'
|
||||
self.arch = platform.machine()
|
||||
self.source_dir = source_dir
|
||||
self.boot_path = 'boot/' + self.arch
|
||||
self.iso_sortfile = NamedTemporaryFile()
|
||||
self.iso_parameters = []
|
||||
self.iso_loaders = []
|
||||
|
||||
def init_iso_creation_parameters(self, custom_args=None):
|
||||
loader_file = self.boot_path + '/loader/isolinux.bin'
|
||||
catalog_file = self.boot_path + '/boot.catalog'
|
||||
with open(self.source_dir + '/' + self.header_end_name, 'w') as marker:
|
||||
marker.write('%s\n' % self.header_id)
|
||||
if not os.path.exists(self.source_dir + '/' + loader_file):
|
||||
raise KiwiIsoLoaderError(
|
||||
'No isolinux loader found in %s' %
|
||||
self.source_dir + '/loader'
|
||||
)
|
||||
if custom_args:
|
||||
self.iso_parameters = custom_args
|
||||
self.iso_parameters += [
|
||||
'-R', '-J', '-f', '-pad', '-joliet-long',
|
||||
'-sort', self.iso_sortfile.name,
|
||||
'-no-emul-boot', '-boot-load-size', '4', '-boot-info-table',
|
||||
'-hide', catalog_file,
|
||||
'-hide-joliet', catalog_file,
|
||||
]
|
||||
self.iso_loaders += [
|
||||
'-b', loader_file, '-c', catalog_file
|
||||
]
|
||||
Command.run(
|
||||
[
|
||||
'isolinux-config', '--base', self.boot_path + '/loader',
|
||||
self.source_dir + '/' + loader_file
|
||||
]
|
||||
)
|
||||
self.__create_sortfile()
|
||||
|
||||
def add_efi_loader_parameters(self):
|
||||
loader_file = self.boot_path + '/efi'
|
||||
if os.path.exists(self.source_dir + '/' + loader_file):
|
||||
self.iso_loaders += [
|
||||
'-eltorito-alt-boot', '-b', loader_file,
|
||||
'-no-emul-boot', '-joliet-long'
|
||||
]
|
||||
|
||||
def get_iso_creation_parameters(self):
|
||||
return self.iso_parameters + self.iso_loaders
|
||||
|
||||
def add_iso_header_end_marker(self):
|
||||
# TODO: see the glump file creation in the old kiwi
|
||||
pass
|
||||
|
||||
def relocate_boot_catalog(self, isofile):
|
||||
# TODO
|
||||
pass
|
||||
|
||||
def fix_boot_catalog(self, isofile):
|
||||
# TODO
|
||||
pass
|
||||
|
||||
def __create_sortfile(self):
|
||||
catalog_file = \
|
||||
self.source_dir + '/' + self.boot_path + '/boot.catalog'
|
||||
loader_file = \
|
||||
self.source_dir + '/' + self.boot_path + '/loader/isolinux.bin'
|
||||
with open(self.iso_sortfile.name, 'w') as sortfile:
|
||||
sortfile.write('%s 3\n' % catalog_file)
|
||||
sortfile.write('%s 2\n' % loader_file)
|
||||
|
||||
for basedir, dirnames, filenames in os.walk(self.source_dir):
|
||||
for filename in filenames:
|
||||
if filename == 'efi':
|
||||
sortfile.write('%s/%s 1000001\n' % (basedir, filename))
|
||||
elif filename == self.header_end_name:
|
||||
sortfile.write('%s/%s 1000000\n' % (basedir, filename))
|
||||
else:
|
||||
sortfile.write('%s/%s 1\n' % (basedir, filename))
|
||||
for dirname in dirnames:
|
||||
sortfile.write('%s/%s 1\n' % (basedir, dirname))
|
||||
@ -300,15 +300,15 @@ class System(object):
|
||||
self, manager, packages, collections=None, products=None
|
||||
):
|
||||
if packages:
|
||||
for package in packages:
|
||||
for package in sorted(packages):
|
||||
log.info('--> package: %s', package)
|
||||
manager.request_package(package)
|
||||
if collections:
|
||||
for collection in collections:
|
||||
for collection in sorted(collections):
|
||||
log.info('--> collection: %s', collection)
|
||||
manager.request_collection(collection)
|
||||
if products:
|
||||
for product in products:
|
||||
for product in sorted(products):
|
||||
log.info('--> product: %s', product)
|
||||
manager.request_product(product)
|
||||
return \
|
||||
|
||||
@ -90,6 +90,10 @@ class SystemCreateTask(CliTask):
|
||||
result.add(
|
||||
'disk_image', disk.diskname
|
||||
)
|
||||
if disk.install_image.media_dir:
|
||||
result.add(
|
||||
'installation_image', disk.install_image.isoname
|
||||
)
|
||||
elif requested_image_type in Defaults.get_live_image_types():
|
||||
# TODO
|
||||
raise KiwiNotImplementedError(
|
||||
|
||||
@ -49,6 +49,10 @@ class TestBootLoaderConfigGrub2(object):
|
||||
self.bootloader = BootLoaderConfigGrub2(
|
||||
self.state, 'source_dir'
|
||||
)
|
||||
self.bootloader.get_hypervisor_domain = mock.Mock(
|
||||
return_value='domU'
|
||||
)
|
||||
self.bootloader.theme = None
|
||||
|
||||
@raises(KiwiBootLoaderGrubPlatformError)
|
||||
@patch('platform.machine')
|
||||
@ -56,13 +60,12 @@ class TestBootLoaderConfigGrub2(object):
|
||||
mock_machine.return_value = 'unsupported-arch'
|
||||
BootLoaderConfigGrub2(mock.Mock(), 'source_dir')
|
||||
|
||||
@patch('kiwi.bootloader_config_base.BootLoaderConfigBase.get_hypervisor_domain')
|
||||
@patch('os.path.exists')
|
||||
def test_post_init_dom0(self, mock_exists, mock_domain):
|
||||
mock_domain.return_value = 'dom0'
|
||||
def test_post_init_dom0(self, mock_exists):
|
||||
self.bootloader.get_hypervisor_domain.return_value = 'dom0'
|
||||
mock_exists.return_value = True
|
||||
self.bootloader.post_init()
|
||||
assert self.bootloader.hypervisor_domain == 'dom0'
|
||||
assert self.bootloader.multiboot is True
|
||||
|
||||
@patch('__builtin__.open')
|
||||
@patch('os.path.exists')
|
||||
@ -423,6 +426,39 @@ class TestBootLoaderConfigGrub2(object):
|
||||
'source_dir//EFI/BOOT'
|
||||
])
|
||||
|
||||
@patch('kiwi.bootloader_config_grub2.Command.run')
|
||||
@patch('__builtin__.open')
|
||||
@patch('os.path.exists')
|
||||
@patch('kiwi.logger.log.warning')
|
||||
def test_setup_install_boot_images_with_theme(
|
||||
self, mock_warn, mock_exists, mock_open, mock_command
|
||||
):
|
||||
self.bootloader.theme = 'some-theme'
|
||||
exists_results = [False, True, False, False]
|
||||
|
||||
def side_effect(arg):
|
||||
return exists_results.pop()
|
||||
|
||||
mock_exists.side_effect = side_effect
|
||||
self.bootloader.setup_install_boot_images(self.mbrid)
|
||||
assert mock_command.call_args_list[1] == call([
|
||||
'rsync', '-zav',
|
||||
'source_dir/usr/share/grub2/themes/some-theme',
|
||||
'source_dir/boot/grub2/themes'
|
||||
])
|
||||
|
||||
@patch('kiwi.bootloader_config_grub2.Command.run')
|
||||
@patch('__builtin__.open')
|
||||
@patch('os.path.exists')
|
||||
@patch('kiwi.logger.log.warning')
|
||||
def test_setup_install_boot_images_with_theme_not_existing(
|
||||
self, mock_warn, mock_exists, mock_open, mock_command
|
||||
):
|
||||
self.bootloader.theme = 'some-theme'
|
||||
mock_exists.return_value = False
|
||||
self.bootloader.setup_install_boot_images(self.mbrid)
|
||||
assert mock_warn.called
|
||||
|
||||
def test_setup_live_image_config(self):
|
||||
# TODO
|
||||
self.bootloader.setup_live_image_config('mbrid')
|
||||
|
||||
139
test/unit/bootloader_config_isolinux_test.py
Normal file
139
test/unit/bootloader_config_isolinux_test.py
Normal file
@ -0,0 +1,139 @@
|
||||
from nose.tools import *
|
||||
from mock import patch
|
||||
from mock import call
|
||||
|
||||
import mock
|
||||
|
||||
import kiwi
|
||||
|
||||
import nose_helper
|
||||
|
||||
from kiwi.xml_state import XMLState
|
||||
from kiwi.xml_description import XMLDescription
|
||||
from kiwi.exceptions import *
|
||||
from kiwi.bootloader_config_isolinux import BootLoaderConfigIsoLinux
|
||||
|
||||
|
||||
class TestBootLoaderConfigIsoLinux(object):
|
||||
@patch('os.path.exists')
|
||||
@patch('platform.machine')
|
||||
def setup(self, mock_machine, mock_exists):
|
||||
mock_machine.return_value = 'x86_64'
|
||||
mock_exists.return_value = True
|
||||
description = XMLDescription(
|
||||
'../data/example_config.xml'
|
||||
)
|
||||
self.state = XMLState(
|
||||
description.load()
|
||||
)
|
||||
kiwi.bootloader_config_isolinux.Path = mock.Mock()
|
||||
kiwi.bootloader_config_base.Path = mock.Mock()
|
||||
self.isolinux = mock.Mock()
|
||||
kiwi.bootloader_config_isolinux.BootLoaderTemplateIsoLinux = mock.Mock(
|
||||
return_value=self.isolinux
|
||||
)
|
||||
self.bootloader = BootLoaderConfigIsoLinux(
|
||||
self.state, 'source_dir'
|
||||
)
|
||||
self.bootloader.get_hypervisor_domain = mock.Mock(
|
||||
return_value='domU'
|
||||
)
|
||||
|
||||
@raises(KiwiBootLoaderIsoLinuxPlatformError)
|
||||
@patch('platform.machine')
|
||||
def test_post_init_invalid_platform(self, mock_machine):
|
||||
mock_machine.return_value = 'unsupported-arch'
|
||||
BootLoaderConfigIsoLinux(mock.Mock(), 'source_dir')
|
||||
|
||||
@patch('os.path.exists')
|
||||
def test_post_init_dom0(self, mock_exists):
|
||||
self.bootloader.get_hypervisor_domain.return_value = 'dom0'
|
||||
mock_exists.return_value = True
|
||||
|
||||
self.bootloader.post_init()
|
||||
assert self.bootloader.multiboot is True
|
||||
|
||||
@patch('__builtin__.open')
|
||||
@patch('os.path.exists')
|
||||
def test_write(self, mock_exists, mock_open):
|
||||
mock_exists.return_value = True
|
||||
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.config = 'some-data'
|
||||
self.bootloader.config_message = 'some-message-data'
|
||||
|
||||
self.bootloader.write()
|
||||
assert mock_open.call_args_list == [
|
||||
call('source_dir/boot/x86_64/loader/isolinux.cfg', 'w'),
|
||||
call('source_dir/boot/x86_64/loader/isolinux.msg', 'w')
|
||||
]
|
||||
assert file_mock.write.call_args_list == [
|
||||
call('some-data'),
|
||||
call('some-message-data')
|
||||
]
|
||||
|
||||
def test_setup_install_image_config(self):
|
||||
template_cfg = mock.Mock()
|
||||
template_msg = mock.Mock()
|
||||
self.isolinux.get_install_template.return_value = template_cfg
|
||||
self.isolinux.get_install_message_template.return_value = template_msg
|
||||
|
||||
self.bootloader.setup_install_image_config(mbrid=None)
|
||||
self.isolinux.get_install_template.assert_called_once_with(True, False)
|
||||
self.isolinux.get_install_message_template.assert_called_once_with()
|
||||
assert template_cfg.substitute.called
|
||||
assert template_msg.substitute.called
|
||||
|
||||
def test_setup_install_image_config_multiboot(self):
|
||||
self.bootloader.multiboot = True
|
||||
|
||||
self.bootloader.setup_install_image_config(mbrid=None)
|
||||
self.isolinux.get_multiboot_install_template.assert_called_once_with(
|
||||
True, False
|
||||
)
|
||||
|
||||
@patch('os.path.exists')
|
||||
def test_setup_install_image_config_with_theme(self, mock_exists):
|
||||
mock_exists.return_value = True
|
||||
|
||||
self.bootloader.setup_install_image_config(mbrid=None)
|
||||
self.isolinux.get_install_template.assert_called_once_with(True, True)
|
||||
|
||||
@raises(KiwiTemplateError)
|
||||
def test_setup_install_image_config_invalid_template(self):
|
||||
self.isolinux.get_install_message_template.side_effect = Exception
|
||||
self.bootloader.setup_install_image_config(mbrid=None)
|
||||
|
||||
@patch('kiwi.bootloader_config_isolinux.Command.run')
|
||||
def test_setup_install_boot_images(self, mock_command):
|
||||
self.bootloader.setup_install_boot_images(
|
||||
mbrid=None, lookup_path='lookup_dir'
|
||||
)
|
||||
mock_command.assert_called_once_with(
|
||||
[
|
||||
'rsync', '-zav', 'lookup_dir/image/loader/',
|
||||
'source_dir/boot/x86_64/loader'
|
||||
]
|
||||
)
|
||||
|
||||
@patch('kiwi.bootloader_config_isolinux.Command.run')
|
||||
def test_setup_live_boot_images(self, mock_command):
|
||||
self.bootloader.setup_live_boot_images(
|
||||
mbrid=None
|
||||
)
|
||||
mock_command.assert_called_once_with(
|
||||
[
|
||||
'rsync', '-zav', 'source_dir/image/loader/',
|
||||
'source_dir/boot/x86_64/loader'
|
||||
]
|
||||
)
|
||||
|
||||
def test_setup_live_image_config(self):
|
||||
# TODO
|
||||
self.bootloader.setup_live_image_config(mbrid=None)
|
||||
@ -19,3 +19,9 @@ class TestBootLoaderConfig(object):
|
||||
xml_state = mock.Mock()
|
||||
BootLoaderConfig.new('grub2', xml_state, 'source_dir')
|
||||
mock_grub2.assert_called_once_with(xml_state, 'source_dir')
|
||||
|
||||
@patch('kiwi.bootloader_config.BootLoaderConfigIsoLinux')
|
||||
def test_bootloader_config_isolinux(self, mock_isolinux):
|
||||
xml_state = mock.Mock()
|
||||
BootLoaderConfig.new('isolinux', xml_state, 'source_dir')
|
||||
mock_isolinux.assert_called_once_with(xml_state, 'source_dir')
|
||||
|
||||
83
test/unit/bootloader_template_isolinux_test.py
Normal file
83
test/unit/bootloader_template_isolinux_test.py
Normal file
@ -0,0 +1,83 @@
|
||||
from nose.tools import *
|
||||
from mock import patch
|
||||
|
||||
import mock
|
||||
|
||||
import nose_helper
|
||||
|
||||
from kiwi.bootloader_template_isolinux import BootLoaderTemplateIsoLinux
|
||||
|
||||
|
||||
class TestBootLoaderTemplateIsoLinux(object):
|
||||
def setup(self):
|
||||
self.isolinux = BootLoaderTemplateIsoLinux()
|
||||
|
||||
def test_get_multiboot_install_template(self):
|
||||
assert self.isolinux.get_multiboot_install_template().substitute(
|
||||
default_boot='0',
|
||||
kernel_file='linux.vmx',
|
||||
initrd_file='initrd.vmx',
|
||||
boot_options='splash',
|
||||
failsafe_boot_options='splash',
|
||||
gfxmode='800x600',
|
||||
theme='SLE',
|
||||
boot_timeout='10',
|
||||
title='LimeJeOS-SLE12-Community [ VMX ]',
|
||||
bootpath='/boot',
|
||||
hypervisor='xen.gz'
|
||||
)
|
||||
|
||||
def test_get_install_template(self):
|
||||
assert self.isolinux.get_install_template().substitute(
|
||||
default_boot='0',
|
||||
kernel_file='boot/linux.vmx',
|
||||
initrd_file='boot/initrd.vmx',
|
||||
boot_options='cdinst=1 splash',
|
||||
failsafe_boot_options='cdinst=1 splash',
|
||||
gfxmode='800x600',
|
||||
theme='SLE',
|
||||
boot_timeout='10',
|
||||
title='LimeJeOS-SLE12-Community [ VMX ]',
|
||||
bootpath='/boot'
|
||||
)
|
||||
|
||||
def test_get_multiboot_install_template_plain_ui(self):
|
||||
assert self.isolinux.get_multiboot_install_template(
|
||||
with_theme=False
|
||||
).substitute(
|
||||
default_boot='0',
|
||||
kernel_file='linux.vmx',
|
||||
initrd_file='initrd.vmx',
|
||||
boot_options='splash',
|
||||
failsafe_boot_options='splash',
|
||||
gfxmode='800x600',
|
||||
theme='SLE',
|
||||
boot_timeout='10',
|
||||
title='LimeJeOS-SLE12-Community [ VMX ]',
|
||||
bootpath='/boot',
|
||||
hypervisor='xen.gz'
|
||||
)
|
||||
|
||||
def test_get_install_template_plan_ui(self):
|
||||
assert self.isolinux.get_install_template(with_theme=False).substitute(
|
||||
default_boot='0',
|
||||
kernel_file='boot/linux.vmx',
|
||||
initrd_file='boot/initrd.vmx',
|
||||
boot_options='cdinst=1 splash',
|
||||
failsafe_boot_options='cdinst=1 splash',
|
||||
gfxmode='800x600',
|
||||
theme='SLE',
|
||||
boot_timeout='10',
|
||||
title='LimeJeOS-SLE12-Community [ VMX ]',
|
||||
bootpath='/boot'
|
||||
)
|
||||
|
||||
def test_get_message_template(self):
|
||||
assert self.isolinux.get_message_template().substitute(
|
||||
title='LimeJeOS-SLE12-Community [ VMX ]'
|
||||
)
|
||||
|
||||
def test_get_install_message_template(self):
|
||||
assert self.isolinux.get_install_message_template().substitute(
|
||||
title='LimeJeOS-SLE12-Community [ VMX ]'
|
||||
)
|
||||
@ -1,5 +1,6 @@
|
||||
from nose.tools import *
|
||||
from mock import patch
|
||||
from mock import call
|
||||
from collections import namedtuple
|
||||
|
||||
import mock
|
||||
@ -60,9 +61,10 @@ class TestCommandProcess(object):
|
||||
process.command.error.read = self.flow_err
|
||||
process.command.process.returncode = 0
|
||||
process.poll_show_progress(['a', 'b'], match_method)
|
||||
mock_log_debug.assert_called_once_with(
|
||||
'%s: %s', 'system', 'data'
|
||||
)
|
||||
assert mock_log_debug.call_args_list == [
|
||||
call('%s: %s', 'system', 'data'),
|
||||
call('%s: %s', 'system', 'error')
|
||||
]
|
||||
|
||||
@raises(KiwiCommandError)
|
||||
@patch('kiwi.command.Command')
|
||||
@ -90,9 +92,10 @@ class TestCommandProcess(object):
|
||||
process.command.error.read = self.flow_err
|
||||
process.command.process.returncode = 0
|
||||
process.poll()
|
||||
mock_log_debug.assert_called_once_with(
|
||||
'%s: %s', 'system', 'data'
|
||||
)
|
||||
assert mock_log_debug.call_args_list == [
|
||||
call('%s: %s', 'system', 'data'),
|
||||
call('%s: %s', 'system', 'error')
|
||||
]
|
||||
|
||||
@raises(KiwiCommandError)
|
||||
@patch('kiwi.command.Command')
|
||||
|
||||
35
test/unit/filesystem_isofs_test.py
Normal file
35
test/unit/filesystem_isofs_test.py
Normal file
@ -0,0 +1,35 @@
|
||||
from nose.tools import *
|
||||
from mock import patch
|
||||
|
||||
import mock
|
||||
|
||||
import nose_helper
|
||||
|
||||
from kiwi.exceptions import *
|
||||
from kiwi.filesystem_isofs import FileSystemIsoFs
|
||||
|
||||
|
||||
class TestFileSystemIsoFs(object):
|
||||
@patch('os.path.exists')
|
||||
def setup(self, mock_exists):
|
||||
mock_exists.return_value = True
|
||||
self.isofs = FileSystemIsoFs(mock.Mock(), 'source_dir')
|
||||
|
||||
def test_post_init(self):
|
||||
self.isofs.post_init(['args'])
|
||||
assert self.isofs.custom_args == ['args']
|
||||
|
||||
@patch('kiwi.filesystem_isofs.Command.run')
|
||||
@patch('kiwi.filesystem_isofs.Iso')
|
||||
def test_create_on_file(self, mock_iso, mock_command):
|
||||
iso = mock.Mock()
|
||||
iso.get_iso_creation_parameters = mock.Mock(
|
||||
return_value=['args']
|
||||
)
|
||||
mock_iso.return_value = iso
|
||||
self.isofs.create_on_file('myimage', None)
|
||||
iso.init_iso_creation_parameters.assert_called_once_with(None)
|
||||
iso.add_efi_loader_parameters.assert_called_once_with()
|
||||
mock_command.assert_called_once_with(
|
||||
['genisoimage', 'args', '-o', 'myimage', 'source_dir']
|
||||
)
|
||||
@ -20,6 +20,10 @@ class TestInstallImageBuilder(object):
|
||||
kiwi.install_image_builder.FileSystemSquashFs = mock.Mock(
|
||||
return_value=self.squashed_image
|
||||
)
|
||||
self.iso_image = mock.Mock()
|
||||
kiwi.install_image_builder.FileSystemIsoFs = mock.Mock(
|
||||
return_value=self.iso_image
|
||||
)
|
||||
self.mbrid = mock.Mock()
|
||||
self.mbrid.get_id = mock.Mock(
|
||||
return_value='0xffffffff'
|
||||
@ -34,17 +38,26 @@ class TestInstallImageBuilder(object):
|
||||
)
|
||||
self.kernel = mock.Mock()
|
||||
self.kernel.get_kernel = mock.Mock()
|
||||
self.kernel.get_xen_hypervisor = mock.Mock()
|
||||
self.kernel.copy_kernel = mock.Mock()
|
||||
self.kernel.copy_xen_hypervisor = mock.Mock()
|
||||
kiwi.install_image_builder.Kernel = mock.Mock(
|
||||
return_value=self.kernel
|
||||
)
|
||||
self.xml_state = mock.Mock()
|
||||
self.xml_state.xml_data.get_name = mock.Mock(
|
||||
return_value='result-image'
|
||||
)
|
||||
self.boot_image_task = mock.Mock()
|
||||
self.boot_image_task.boot_root_directory = 'initrd_dir'
|
||||
self.boot_image_task.initrd_filename = 'initrd'
|
||||
self.install_image = InstallImageBuilder(
|
||||
self.xml_state, 'target_dir', 'some-diskimage', self.boot_image_task
|
||||
)
|
||||
self.install_image.machine = mock.Mock()
|
||||
self.install_image.machine.get_domain = mock.Mock(
|
||||
return_value='dom0'
|
||||
)
|
||||
|
||||
@patch('kiwi.install_image_builder.mkdtemp')
|
||||
@patch('__builtin__.open')
|
||||
@ -76,23 +89,37 @@ class TestInstallImageBuilder(object):
|
||||
self.squashed_image.create_on_file.assert_called_once_with(
|
||||
'some-diskimage.squashfs'
|
||||
)
|
||||
self.bootloader.setup_install_boot_images.assert_called_once_with(
|
||||
lookup_path='initrd_dir', mbrid=self.mbrid
|
||||
)
|
||||
self.bootloader.setup_install_image_config.assert_called_once_with(
|
||||
self.mbrid
|
||||
)
|
||||
self.bootloader.write.assert_called_once_with()
|
||||
assert self.bootloader.setup_install_boot_images.call_args_list == [
|
||||
call(lookup_path='initrd_dir', mbrid=None),
|
||||
call(lookup_path='initrd_dir', mbrid=self.mbrid)
|
||||
]
|
||||
assert self.bootloader.setup_install_boot_images.call_args_list == [
|
||||
call(lookup_path='initrd_dir', mbrid=None),
|
||||
call(lookup_path='initrd_dir', mbrid=self.mbrid)
|
||||
]
|
||||
assert self.bootloader.setup_install_image_config.call_args_list == [
|
||||
call(mbrid=None),
|
||||
call(mbrid=self.mbrid)
|
||||
]
|
||||
assert self.bootloader.write.call_args_list == [
|
||||
call(), call()
|
||||
]
|
||||
self.boot_image_task.create_initrd.assert_called_once_with(
|
||||
self.mbrid
|
||||
)
|
||||
self.kernel.copy_kernel.assert_called_once_with(
|
||||
'tmpdir/boot/x86_64/loader', '/linux'
|
||||
)
|
||||
self.kernel.copy_xen_hypervisor.assert_called_once_with(
|
||||
'tmpdir/boot/x86_64/loader', '/xen.gz'
|
||||
)
|
||||
assert mock_command.call_args_list == [
|
||||
call(['mv', 'some-diskimage.squashfs', 'tmpdir']),
|
||||
call(['mv', 'initrd', 'tmpdir/boot/x86_64/loader/initrd'])
|
||||
]
|
||||
self.iso_image.create_on_file.assert_called_once_with(
|
||||
'target_dir/result-image.install.iso'
|
||||
)
|
||||
|
||||
@patch('kiwi.install_image_builder.mkdtemp')
|
||||
@patch('__builtin__.open')
|
||||
@ -104,10 +131,23 @@ class TestInstallImageBuilder(object):
|
||||
self.kernel.get_kernel.return_value = False
|
||||
self.install_image.create_install_iso()
|
||||
|
||||
@patch('kiwi.install_image_builder.mkdtemp')
|
||||
@patch('__builtin__.open')
|
||||
@patch('kiwi.install_image_builder.Command.run')
|
||||
@raises(KiwiInstallBootImageError)
|
||||
def test_create_install_iso_no_hypervisor_found(
|
||||
self, mock_command, mock_open, mock_dtemp
|
||||
):
|
||||
self.kernel.get_xen_hypervisor.return_value = False
|
||||
self.install_image.create_install_iso()
|
||||
|
||||
def test_create_install_pxe_archive(self):
|
||||
# TODO
|
||||
self.install_image.create_install_pxe_archive()
|
||||
|
||||
def test_destructor(self):
|
||||
# TODO
|
||||
@patch('kiwi.install_image_builder.Path.wipe')
|
||||
def test_destructor(self, mock_wipe):
|
||||
self.install_image.media_dir = 'media-dir'
|
||||
self.install_image.__del__()
|
||||
mock_wipe.assert_called_once_with('media-dir')
|
||||
self.install_image.media_dir = None
|
||||
|
||||
110
test/unit/iso_test.py
Normal file
110
test/unit/iso_test.py
Normal file
@ -0,0 +1,110 @@
|
||||
from nose.tools import *
|
||||
from mock import patch
|
||||
from mock import call
|
||||
import mock
|
||||
|
||||
import nose_helper
|
||||
|
||||
from kiwi.exceptions import *
|
||||
|
||||
from kiwi.iso import Iso
|
||||
from collections import namedtuple
|
||||
|
||||
|
||||
class TestIso(object):
|
||||
@patch('kiwi.iso.NamedTemporaryFile')
|
||||
@patch('platform.machine')
|
||||
def setup(self, mock_machine, mock_tempfile):
|
||||
temp_type = namedtuple(
|
||||
'temp_type', ['name']
|
||||
)
|
||||
mock_machine.return_value = 'x86_64'
|
||||
mock_tempfile.return_value = temp_type(
|
||||
name='sortfile'
|
||||
)
|
||||
self.iso = Iso('source-dir')
|
||||
|
||||
@patch('__builtin__.open')
|
||||
@patch('os.path.exists')
|
||||
@raises(KiwiIsoLoaderError)
|
||||
def test_init_iso_creation_parameters_no_loader(
|
||||
self, mock_exists, mock_open
|
||||
):
|
||||
mock_exists.return_value = False
|
||||
self.iso.init_iso_creation_parameters()
|
||||
|
||||
@patch('__builtin__.open')
|
||||
@patch('kiwi.iso.Command.run')
|
||||
@patch('os.path.exists')
|
||||
@patch('os.walk')
|
||||
def test_init_iso_creation_parameters(
|
||||
self, mock_walk, mock_exists, mock_command, mock_open
|
||||
):
|
||||
mock_walk.return_value = [
|
||||
('source-dir', ('bar', 'baz'), ('efi', 'eggs', 'header_end'))
|
||||
]
|
||||
mock_exists.return_value = True
|
||||
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.iso.init_iso_creation_parameters(['custom_arg'])
|
||||
|
||||
assert file_mock.write.call_args_list == [
|
||||
call('7984fc91-a43f-4e45-bf27-6d3aa08b24cf\n'),
|
||||
call('source-dir/boot/x86_64/boot.catalog 3\n'),
|
||||
call('source-dir/boot/x86_64/loader/isolinux.bin 2\n'),
|
||||
call('source-dir/efi 1000001\n'),
|
||||
call('source-dir/eggs 1\n'),
|
||||
call('source-dir/header_end 1000000\n'),
|
||||
call('source-dir/bar 1\n'),
|
||||
call('source-dir/baz 1\n')
|
||||
]
|
||||
assert self.iso.iso_parameters == [
|
||||
'custom_arg', '-R', '-J', '-f', '-pad', '-joliet-long',
|
||||
'-sort', 'sortfile', '-no-emul-boot', '-boot-load-size', '4',
|
||||
'-boot-info-table',
|
||||
'-hide', 'boot/x86_64/boot.catalog',
|
||||
'-hide-joliet', 'boot/x86_64/boot.catalog',
|
||||
]
|
||||
assert self.iso.iso_loaders == [
|
||||
'-b', 'boot/x86_64/loader/isolinux.bin',
|
||||
'-c', 'boot/x86_64/boot.catalog'
|
||||
]
|
||||
mock_command.assert_called_once_with(
|
||||
[
|
||||
'isolinux-config', '--base', 'boot/x86_64/loader',
|
||||
'source-dir/boot/x86_64/loader/isolinux.bin'
|
||||
]
|
||||
)
|
||||
|
||||
@patch('os.path.exists')
|
||||
def test_add_efi_loader_parameters(self, mock_exists):
|
||||
mock_exists.return_value = True
|
||||
self.iso.add_efi_loader_parameters()
|
||||
assert self.iso.iso_loaders == [
|
||||
'-eltorito-alt-boot', '-b', 'boot/x86_64/efi',
|
||||
'-no-emul-boot', '-joliet-long'
|
||||
]
|
||||
|
||||
def test_get_iso_creation_parameters(self):
|
||||
self.iso.iso_parameters = ['a']
|
||||
self.iso.iso_loaders = ['b']
|
||||
assert self.iso.get_iso_creation_parameters() == ['a', 'b']
|
||||
|
||||
def test_add_iso_header_end_marker(self):
|
||||
# TODO
|
||||
self.iso.add_iso_header_end_marker()
|
||||
|
||||
def test_relocate_boot_catalog(self):
|
||||
# TODO
|
||||
self.iso.relocate_boot_catalog('isofile')
|
||||
|
||||
def test_fix_boot_catalog(self):
|
||||
# TODO
|
||||
self.iso.fix_boot_catalog('isofile')
|
||||
Loading…
Reference in New Issue
Block a user