Exemple #1
0
    def __init__(self, xml_state, root_dir):
        self.root_filesystem_is_overlay = xml_state.build_type.get_overlayroot()
        self.swap_mbytes = xml_state.get_oemconfig_swap_mbytes()
        self.configured_size = xml_state.get_build_type_size()
        self.build_type_name = xml_state.get_build_type_name()
        self.filesystem = xml_state.build_type.get_filesystem()
        self.bootpart_requested = xml_state.build_type.get_bootpartition()
        self.bootpart_mbytes = xml_state.build_type.get_bootpartsize()
        self.spare_part_mbytes = xml_state.get_build_type_spare_part_size()
        self.mdraid = xml_state.build_type.get_mdraid()
        self.luks = xml_state.build_type.get_luks()
        self.volume_manager = xml_state.get_volume_management()
        self.bootloader = xml_state.build_type.get_bootloader()
        self.oemconfig = xml_state.get_build_type_oemconfig_section()
        self.volumes = xml_state.get_volumes()

        self.firmware = FirmWare(
            xml_state
        )
        self.rootsize = SystemSize(
            root_dir
        )

        self.root_dir = root_dir
        self.xml_state = xml_state
Exemple #2
0
    def get_volume_mbsize(self,
                          volume,
                          all_volumes,
                          filesystem_name,
                          resize_on_boot=False):
        """
        Implements size lookup for the given path and desired
        filesystem according to the specified size type

        :param tuple volume: volume to check size for
        :param list all_volumes: list of all volume tuples
        :param str filesystem_name: filesystem name
        :param resize_on_boot:
            specify the time of the resize. If the resize happens at
            boot time the volume size is only the minimum size to
            just store the data. If the volume size is fixed and
            does not change at boot time the returned size is the
            requested size which can be greater than the minimum
            needed size.

        :return: mbsize

        :rtype: int
        """
        [size_type, mbsize] = volume.size.split(':')
        lookup_path = volume.realpath
        lookup_abspath = os.path.normpath(
            os.sep.join([self.root_dir, lookup_path]))
        mbsize = int(mbsize)

        if resize_on_boot:
            # If resize_on_boot is true, the disk is self expandable and
            # will resize to the configured sizes on first boot
            # Therefore the requested size is set to null and we add
            # the required minimum size for just storing the data
            size_type = 'freespace'
            mbsize = Defaults.get_min_volume_mbytes()

        if size_type == 'freespace' and os.path.exists(lookup_abspath):
            exclude_paths = []
            for volume in all_volumes:
                volume_path = volume.realpath
                if lookup_path == volume_path:
                    continue
                if lookup_path == os.sep:
                    # exclude any sub volume path if lookup_path is /
                    exclude_paths.append(
                        os.path.normpath(self.root_dir + os.sep + volume_path))
                elif volume_path.startswith(lookup_path):
                    # exclude any sub volume path below lookup_path
                    exclude_paths.append(
                        os.path.normpath(self.root_dir + os.sep + volume_path))

            volume_size = SystemSize(lookup_abspath)
            if mbsize != Defaults.get_min_volume_mbytes():
                mbsize += Defaults.get_min_volume_mbytes()
            mbsize += volume_size.customize(
                volume_size.accumulate_mbyte_file_sizes(exclude_paths),
                filesystem_name)
        return mbsize
Exemple #3
0
    def _calculate_volume_mbytes(self):
        """
        Calculate the number of mbytes each volume path currently
        consumes and also provide a total number of these values.
        """
        volume_mbytes_type = namedtuple(
            'volume_mbytes_type', ['volume', 'total']
        )
        volume_mbytes = {}
        volume_total = 0
        for volume in self.volumes:
            if volume.realpath and not volume.realpath == '/':
                path_to_volume = self.root_dir + '/' + volume.realpath
                if os.path.exists(path_to_volume):
                    volume_size = SystemSize(path_to_volume)
                    volume_mbytes[volume.realpath] = volume_size.customize(
                        volume_size.accumulate_mbyte_file_sizes(),
                        self.filesystem
                    )
                else:
                    volume_mbytes[volume.realpath] = 0
                volume_total += volume_mbytes[volume.realpath]

        return volume_mbytes_type(
            volume=volume_mbytes,
            total=volume_total
        )
Exemple #4
0
 def _calculate_partition_mbytes(self):
     """
     Calculate the number of mbytes each partition path consumes
     """
     partition_mbytes_type = namedtuple(
         'partition_mbytes_type', ['partition']
     )
     partition_mbytes = {}
     for map_name in sorted(self.custom_partitions.keys()):
         partition_mount_path = self.custom_partitions[map_name].mountpoint
         if partition_mount_path:
             partition_filesystem = self.custom_partitions[map_name].filesystem
             path_to_partition = os.path.normpath(
                 os.sep.join([self.root_dir, partition_mount_path])
             )
             if os.path.exists(path_to_partition):
                 partition_size = SystemSize(path_to_partition)
                 partition_mbytes[partition_mount_path] = partition_size.customize(
                     partition_size.accumulate_mbyte_file_sizes(),
                     partition_filesystem
                 )
             else:
                 partition_mbytes[partition_mount_path] = 0
     return partition_mbytes_type(
         partition=partition_mbytes
     )
Exemple #5
0
	def __init__(self, path, state, offset=None):
		self._device = None
		self._offset = offset
		self._path = path
		self._state = state

		sz = SystemSize(path)
		self._size = sz.customize(size=sz.accumulate_mbyte_file_sizes(), requested_filesystem='ext4') * 1024 * 1024
Exemple #6
0
 def __init__(self, xml_state, root_dir):
     self.configured_size = xml_state.get_build_type_size()
     self.size = SystemSize(root_dir)
     self.requested_image_type = xml_state.get_build_type_name()
     if self.requested_image_type in Defaults.get_filesystem_image_types():
         self.requested_filesystem = self.requested_image_type
     else:
         self.requested_filesystem = xml_state.build_type.get_filesystem()
Exemple #7
0
    def get_volume_mbsize(self,
                          volume,
                          all_volumes,
                          filesystem_name,
                          image_type=None):
        """
        Implements size lookup for the given path and desired
        filesystem according to the specified size type

        :param tuple volume: volume to check size for
        :param list all_volumes: list of all volume tuples
        :param str filesystem_name: filesystem name
        :param image_type: build type name

        :return: mbsize

        :rtype: int
        """
        [size_type, mbsize] = volume.size.split(':')
        lookup_path = volume.realpath
        lookup_abspath = os.path.normpath(
            os.sep.join([self.root_dir, lookup_path]))
        mbsize = int(mbsize)

        if image_type and image_type == 'oem':
            # only for vmx types we need to create the volumes in the
            # configured size. oem disks are self expandable and will
            # resize to the configured sizes on first boot of the disk
            # image. Therefore the requested size is set to null
            # and we add the required minimum size to hold the data
            size_type = 'freespace'
            mbsize = Defaults.get_min_volume_mbytes()

        if size_type == 'freespace' and os.path.exists(lookup_abspath):
            exclude_paths = []
            for volume in all_volumes:
                volume_path = volume.realpath
                if lookup_path == volume_path:
                    continue
                if lookup_path == os.sep:
                    # exclude any sub volume path if lookup_path is / [LVRoot]
                    exclude_paths.append(
                        os.path.normpath(self.root_dir + os.sep + volume_path))
                elif volume_path.startswith(lookup_path):
                    # exclude any sub volume path below lookup_path
                    exclude_paths.append(
                        os.path.normpath(self.root_dir + os.sep + volume_path))

            volume_size = SystemSize(lookup_abspath)
            if mbsize != Defaults.get_min_volume_mbytes():
                mbsize += Defaults.get_min_volume_mbytes()
            mbsize += volume_size.customize(
                volume_size.accumulate_mbyte_file_sizes(exclude_paths),
                filesystem_name)
        return mbsize
Exemple #8
0
 def __init__(self, xml_state, root_dir):
     self.configured_size = xml_state.get_build_type_size(
         include_unpartitioned=True)
     if xml_state.get_build_type_unpartitioned_bytes() > 0:
         log.warning(
             'Unpartitoned size attribute is ignored for filesystem images')
     self.size = SystemSize(root_dir)
     self.requested_image_type = xml_state.get_build_type_name()
     if self.requested_image_type in Defaults.get_filesystem_image_types():
         self.requested_filesystem = self.requested_image_type
     else:
         self.requested_filesystem = xml_state.build_type.get_filesystem()
Exemple #9
0
    def get_volume_mbsize(self,
                          mbsize,
                          size_type,
                          realpath,
                          filesystem_name,
                          image_type=None):
        """
        Implements size lookup for the given path and desired
        filesystem according to the specified size type

        :param int mbsize: configured volume size
        :param string size_type: relative or absolute size setup
        :param string realpath: volume real path name
        :param string filesystem_name: filesystem name
        :param image_type: build type name

        :return: mbsize
        :rtype: int
        """
        if image_type and image_type == 'oem':
            # only for vmx types we need to create the volumes in the
            # configured size. oem disks are self expandable and will
            # resize to the configured sizes on first boot of the disk
            # image. Therefore the requested size is set to null
            # and we add the required minimum size to hold the data
            size_type = 'freespace'
            mbsize = 0

        if size_type == 'freespace':
            # Please note for nested volumes which contains other volumes
            # the freespace calculation is not correct. Example:
            # /usr is a volume and /usr/lib is a volume. If freespace is
            # set for the /usr volume the data size calculated also
            # contains the data of the /usr/lib path which will live in
            # an extra volume later. The result will be more freespace
            # than expected ! Especially for the root volume this matters
            # most because it always nests all other volumes. Thus it is
            # better to use a fixed size for the root volume if it is not
            # configured to use all rest space
            #
            # You are invited to fix it :)
            volume_size = SystemSize(self.root_dir + '/' + realpath)
            mbsize = int(mbsize) + \
                Defaults.get_min_volume_mbytes()
            mbsize += volume_size.customize(
                volume_size.accumulate_mbyte_file_sizes(), filesystem_name)
        return mbsize
Exemple #10
0
    def create(self):
        """
        Build a bootable hybrid live ISO image

        Image types which triggers this builder are:

        * image="iso"
        """
        # media dir to store CD contents
        self.media_dir = mkdtemp(
            prefix='live-media.', dir=self.target_dir
        )
        rootsize = SystemSize(self.media_dir)

        # custom iso metadata
        log.info('Using following live ISO metadata:')
        log.info('--> Application id: {0}'.format(self.mbrid.get_id()))
        log.info('--> Publisher: {0}'.format(Defaults.get_publisher()))
        log.info('--> Volume id: {0}'.format(self.volume_id))
        custom_iso_args = {
            'create_options': [
                '-A', self.mbrid.get_id(),
                '-p', Defaults.get_preparer(),
                '-publisher', Defaults.get_publisher(),
                '-V', self.volume_id
            ]
        }

        # pack system into live boot structure as expected by dracut
        log.info(
            'Packing system into dracut live ISO type: {0}'.format(
                self.live_type
            )
        )
        root_filesystem = Defaults.get_default_live_iso_root_filesystem()
        filesystem_custom_parameters = {
            'mount_options': self.xml_state.get_fs_mount_option_list()
        }
        filesystem_setup = FileSystemSetup(
            self.xml_state, self.root_dir
        )
        root_image = NamedTemporaryFile()
        loop_provider = LoopDevice(
            root_image.name,
            filesystem_setup.get_size_mbytes(root_filesystem),
            self.xml_state.build_type.get_target_blocksize()
        )
        loop_provider.create()
        live_filesystem = FileSystem(
            name=root_filesystem,
            device_provider=loop_provider,
            root_dir=self.root_dir + os.sep,
            custom_args=filesystem_custom_parameters
        )
        live_filesystem.create_on_device()
        log.info(
            '--> Syncing data to {0} root image'.format(root_filesystem)
        )
        live_filesystem.sync_data(
            Defaults.get_exclude_list_for_root_data_sync()
        )
        log.info('--> Creating squashfs container for root image')
        self.live_container_dir = mkdtemp(
            prefix='live-container.', dir=self.target_dir
        )
        Path.create(self.live_container_dir + '/LiveOS')
        shutil.copy(
            root_image.name, self.live_container_dir + '/LiveOS/rootfs.img'
        )
        live_container_image = FileSystem(
            name='squashfs',
            device_provider=None,
            root_dir=self.live_container_dir
        )
        container_image = NamedTemporaryFile()
        live_container_image.create_on_file(
            container_image.name
        )
        Path.create(self.media_dir + '/LiveOS')
        shutil.copy(
            container_image.name, self.media_dir + '/LiveOS/squashfs.img'
        )

        # setup bootloader config to boot the ISO via isolinux
        log.info('Setting up isolinux bootloader configuration')
        bootloader_config_isolinux = BootLoaderConfig(
            'isolinux', self.xml_state, self.media_dir
        )
        bootloader_config_isolinux.setup_live_boot_images(
            mbrid=None,
            lookup_path=self.boot_image.boot_root_directory
        )
        bootloader_config_isolinux.setup_live_image_config(
            mbrid=None
        )
        bootloader_config_isolinux.write()

        # setup bootloader config to boot the ISO via EFI
        if self.firmware.efi_mode():
            log.info('Setting up EFI grub bootloader configuration')
            bootloader_config_grub = BootLoaderConfig(
                'grub2', self.xml_state, self.media_dir, {
                    'grub_directory_name':
                        Defaults.get_grub_boot_directory_name(self.root_dir)
                }
            )
            bootloader_config_grub.setup_live_boot_images(
                mbrid=self.mbrid, lookup_path=self.root_dir
            )
            bootloader_config_grub.setup_live_image_config(
                mbrid=self.mbrid
            )
            bootloader_config_grub.write()

        # call custom editbootconfig script if present
        self.system_setup.call_edit_boot_config_script(
            filesystem='iso:{0}'.format(self.media_dir), boot_part_id=1,
            working_directory=self.root_dir
        )

        # create dracut initrd for live image
        log.info('Creating live ISO boot image')
        self._create_dracut_live_iso_config()
        self.boot_image.create_initrd(self.mbrid)

        # setup kernel file(s) and initrd in ISO boot layout
        log.info('Setting up kernel file(s) and boot image in ISO boot layout')
        self._setup_live_iso_kernel_and_initrd()

        # calculate size and decide if we need UDF
        if rootsize.accumulate_mbyte_file_sizes() > 4096:
            log.info('ISO exceeds 4G size, using UDF filesystem')
            custom_iso_args['create_options'].append('-iso-level')
            custom_iso_args['create_options'].append('3')
            custom_iso_args['create_options'].append('-udf')

        # create iso filesystem from media_dir
        log.info('Creating live ISO image')
        iso_image = FileSystemIsoFs(
            device_provider=None,
            root_dir=self.media_dir,
            custom_args=custom_iso_args
        )
        iso_header_offset = iso_image.create_on_file(self.isoname)

        # make it hybrid
        if self.hybrid:
            Iso.create_hybrid(
                iso_header_offset, self.mbrid, self.isoname,
                self.firmware.efi_mode()
            )

        # include metadata for checkmedia tool
        if self.xml_state.build_type.get_mediacheck() is True:
            Iso.set_media_tag(self.isoname)

        self.result.verify_image_size(
            self.runtime_config.get_max_size_constraint(),
            self.isoname
        )
        self.result.add(
            key='live_image',
            filename=self.isoname,
            use_for_bundle=True,
            compress=False,
            shasum=True
        )
        self.result.add(
            key='image_packages',
            filename=self.system_setup.export_package_list(
                self.target_dir
            ),
            use_for_bundle=True,
            compress=False,
            shasum=False
        )
        self.result.add(
            key='image_verified',
            filename=self.system_setup.export_package_verification(
                self.target_dir
            ),
            use_for_bundle=True,
            compress=False,
            shasum=False
        )
        return self.result
Exemple #11
0
 def _get_container_filesystem_size_mbytes(self):
     size = SystemSize(self.root_dir)
     root_dir_mbytes = size.accumulate_mbyte_file_sizes()
     return size.customize(root_dir_mbytes, 'ext4')
Exemple #12
0
 def setup(self):
     self.size = SystemSize('directory')
Exemple #13
0
    def create(self):
        """
        Build a bootable hybrid live ISO image

        Image types which triggers this builder are:

        * image="iso"

        :raises KiwiLiveBootImageError: if no kernel or hipervisor is found
            in boot image tree
        :return: result

        :rtype: instance of :class:`Result`
        """
        # media dir to store CD contents
        self.media_dir = mkdtemp(prefix='live-media.', dir=self.target_dir)

        # unpack cdroot user files to media dir
        self.system_setup.import_cdroot_files(self.media_dir)

        rootsize = SystemSize(self.media_dir)

        # custom iso metadata
        log.info('Using following live ISO metadata:')
        log.info('--> Application id: {0}'.format(self.mbrid.get_id()))
        log.info('--> Publisher: {0}'.format(Defaults.get_publisher()))
        log.info('--> Volume id: {0}'.format(self.volume_id))
        custom_iso_args = {
            'meta_data': {
                'publisher': self.publisher,
                'preparer': Defaults.get_preparer(),
                'volume_id': self.volume_id,
                'mbr_id': self.mbrid.get_id(),
                'efi_mode': self.firmware.efi_mode()
            }
        }

        log.info('Setting up live image bootloader configuration')
        if self.firmware.efi_mode():
            # setup bootloader config to boot the ISO via EFI
            # This also embedds an MBR and the respective BIOS modules
            # for compat boot. The complete bootloader setup will be
            # based on grub
            bootloader_config = BootLoaderConfig(
                'grub2',
                self.xml_state,
                root_dir=self.root_dir,
                boot_dir=self.media_dir,
                custom_args={
                    'grub_directory_name':
                    Defaults.get_grub_boot_directory_name(self.root_dir)
                })
            bootloader_config.setup_live_boot_images(mbrid=self.mbrid,
                                                     lookup_path=self.root_dir)
        else:
            # setup bootloader config to boot the ISO via isolinux.
            # This allows for booting on x86 platforms in BIOS mode
            # only.
            bootloader_config = BootLoaderConfig('isolinux',
                                                 self.xml_state,
                                                 root_dir=self.root_dir,
                                                 boot_dir=self.media_dir)
        IsoToolsBase.setup_media_loader_directory(
            self.boot_image.boot_root_directory, self.media_dir,
            bootloader_config.get_boot_theme())
        bootloader_config.write_meta_data()
        bootloader_config.setup_live_image_config(mbrid=self.mbrid)
        bootloader_config.write()

        # call custom editbootconfig script if present
        self.system_setup.call_edit_boot_config_script(
            filesystem='iso:{0}'.format(self.media_dir),
            boot_part_id=1,
            working_directory=self.root_dir)

        # prepare dracut initrd call
        self.boot_image.prepare()

        # create dracut initrd for live image
        log.info('Creating live ISO boot image')
        live_dracut_modules = Defaults.get_live_dracut_modules_from_flag(
            self.live_type)
        live_dracut_modules.append('pollcdrom')
        for dracut_module in live_dracut_modules:
            self.boot_image.include_module(dracut_module)
        self.boot_image.omit_module('multipath')
        self.boot_image.write_system_config_file(
            config={
                'modules': live_dracut_modules,
                'omit_modules': ['multipath']
            },
            config_file=self.root_dir + '/etc/dracut.conf.d/02-livecd.conf')
        self.boot_image.create_initrd(self.mbrid)

        # setup kernel file(s) and initrd in ISO boot layout
        log.info('Setting up kernel file(s) and boot image in ISO boot layout')
        self._setup_live_iso_kernel_and_initrd()

        # calculate size and decide if we need UDF
        if rootsize.accumulate_mbyte_file_sizes() > 4096:
            log.info('ISO exceeds 4G size, using UDF filesystem')
            custom_iso_args['meta_data']['udf'] = True

        # pack system into live boot structure as expected by dracut
        log.info('Packing system into dracut live ISO type: {0}'.format(
            self.live_type))
        root_filesystem = Defaults.get_default_live_iso_root_filesystem()
        filesystem_custom_parameters = {
            'mount_options': self.xml_state.get_fs_mount_option_list(),
            'create_options': self.xml_state.get_fs_create_option_list()
        }
        filesystem_setup = FileSystemSetup(self.xml_state, self.root_dir)
        root_image = NamedTemporaryFile()
        loop_provider = LoopDevice(
            root_image.name, filesystem_setup.get_size_mbytes(root_filesystem),
            self.xml_state.build_type.get_target_blocksize())
        loop_provider.create()
        live_filesystem = FileSystem(name=root_filesystem,
                                     device_provider=loop_provider,
                                     root_dir=self.root_dir + os.sep,
                                     custom_args=filesystem_custom_parameters)
        live_filesystem.create_on_device()
        log.info('--> Syncing data to {0} root image'.format(root_filesystem))
        live_filesystem.sync_data(
            Defaults.get_exclude_list_for_root_data_sync())
        log.info('--> Creating squashfs container for root image')
        self.live_container_dir = mkdtemp(prefix='live-container.',
                                          dir=self.target_dir)
        Path.create(self.live_container_dir + '/LiveOS')
        shutil.copy(root_image.name,
                    self.live_container_dir + '/LiveOS/rootfs.img')
        live_container_image = FileSystem(
            name='squashfs',
            device_provider=None,
            root_dir=self.live_container_dir,
            custom_args={
                'compression':
                self.xml_state.build_type.get_squashfscompression()
            })
        container_image = NamedTemporaryFile()
        live_container_image.create_on_file(container_image.name)
        Path.create(self.media_dir + '/LiveOS')
        shutil.copy(container_image.name,
                    self.media_dir + '/LiveOS/squashfs.img')

        # create iso filesystem from media_dir
        log.info('Creating live ISO image')
        iso_image = FileSystemIsoFs(device_provider=None,
                                    root_dir=self.media_dir,
                                    custom_args=custom_iso_args)
        iso_image.create_on_file(self.isoname)

        # include metadata for checkmedia tool
        if self.xml_state.build_type.get_mediacheck() is True:
            Iso.set_media_tag(self.isoname)

        self.result.verify_image_size(
            self.runtime_config.get_max_size_constraint(), self.isoname)
        self.result.add(key='live_image',
                        filename=self.isoname,
                        use_for_bundle=True,
                        compress=False,
                        shasum=True)
        self.result.add(key='image_packages',
                        filename=self.system_setup.export_package_list(
                            self.target_dir),
                        use_for_bundle=True,
                        compress=False,
                        shasum=False)
        self.result.add(key='image_verified',
                        filename=self.system_setup.export_package_verification(
                            self.target_dir),
                        use_for_bundle=True,
                        compress=False,
                        shasum=False)
        return self.result
Exemple #14
0
    def create(self):
        """
        Build a bootable hybrid live ISO image

        Image types which triggers this builder are:

        * image="iso"
        """
        # media dir to store CD contents
        self.media_dir = mkdtemp(prefix='live-media.', dir=self.target_dir)
        rootsize = SystemSize(self.media_dir)

        # custom iso metadata
        log.info('Using following live ISO metadata:')
        log.info('--> Application id: %s', self.mbrid.get_id())
        log.info('--> Publisher: %s', Defaults.get_publisher())
        custom_iso_args = {
            'create_options': [
                '-A',
                self.mbrid.get_id(), '-p', '"' + Defaults.get_preparer() + '"',
                '-publisher', '"' + Defaults.get_publisher() + '"'
            ]
        }
        if self.volume_id:
            log.info('--> Volume id: %s', self.volume_id)
            custom_iso_args['create_options'].append('-V')
            custom_iso_args['create_options'].append('"' + self.volume_id +
                                                     '"')

        # prepare boot(initrd) root system
        log.info('Preparing live ISO boot system')
        self.boot_image_task.prepare()

        # export modprobe configuration to boot image
        self.system_setup.export_modprobe_setup(
            self.boot_image_task.boot_root_directory)

        # pack system into live boot structure
        log.info('Packing system into live ISO type: %s', self.live_type)
        if self.live_type in self.types:
            live_type_image = FileSystem(
                name=self.types[self.live_type],
                device_provider=None,
                root_dir=self.root_dir,
                custom_args=self.filesystem_custom_parameters)
            live_type_image.create_on_file(
                self.live_image_file,
                exclude=Defaults.get_exclude_list_for_root_data_sync())
            Command.run(['mv', self.live_image_file, self.media_dir])
            self._create_live_iso_client_config(self.live_type)
        else:
            raise KiwiLiveBootImageError('live ISO type "%s" not supported' %
                                         self.live_type)

        # setup bootloader config to boot the ISO via isolinux
        log.info('Setting up isolinux bootloader configuration')
        bootloader_config_isolinux = BootLoaderConfig('isolinux',
                                                      self.xml_state,
                                                      self.media_dir)
        bootloader_config_isolinux.setup_live_boot_images(
            mbrid=None, lookup_path=self.boot_image_task.boot_root_directory)
        bootloader_config_isolinux.setup_live_image_config(mbrid=None)
        bootloader_config_isolinux.write()
        self.system_setup.call_edit_boot_config_script(
            filesystem=self.types[self.live_type],
            boot_part_id=1,
            working_directory=self.media_dir)

        # setup bootloader config to boot the ISO via EFI
        if self.firmware.efi_mode():
            log.info('Setting up EFI grub bootloader configuration')
            bootloader_config_grub = BootLoaderConfig(
                'grub2', self.xml_state, self.media_dir, {
                    'grub_directory_name':
                    Defaults.get_grub_boot_directory_name(self.root_dir)
                })
            bootloader_config_grub.setup_live_boot_images(
                mbrid=self.mbrid, lookup_path=self.root_dir)
            bootloader_config_grub.setup_live_image_config(mbrid=self.mbrid)
            bootloader_config_grub.write()

        # create initrd for live image
        log.info('Creating live ISO boot image')
        self._create_live_iso_kernel_and_initrd()

        # calculate size and decide if we need UDF
        if rootsize.accumulate_mbyte_file_sizes() > 4096:
            log.info('ISO exceeds 4G size, using UDF filesystem')
            custom_iso_args['create_options'].append('-iso-level')
            custom_iso_args['create_options'].append('3')
            custom_iso_args['create_options'].append('-udf')

        # create iso filesystem from media_dir
        log.info('Creating live ISO image')
        iso_image = FileSystemIsoFs(device_provider=None,
                                    root_dir=self.media_dir,
                                    custom_args=custom_iso_args)
        iso_header_offset = iso_image.create_on_file(self.isoname)

        # make it hybrid
        if self.hybrid:
            Iso.create_hybrid(iso_header_offset, self.mbrid, self.isoname)

        # include metadata for checkmedia tool
        if self.xml_state.build_type.get_mediacheck() is True:
            Iso.set_media_tag(self.isoname)

        self.result.add(key='live_image',
                        filename=self.isoname,
                        use_for_bundle=True,
                        compress=False,
                        shasum=True)
        self.result.add(key='image_packages',
                        filename=self.system_setup.export_package_list(
                            self.target_dir),
                        use_for_bundle=True,
                        compress=False,
                        shasum=False)
        self.result.add(key='image_verified',
                        filename=self.system_setup.export_package_verification(
                            self.target_dir),
                        use_for_bundle=True,
                        compress=False,
                        shasum=False)
        return self.result