def __init__(self, xml_state, target_dir, root_dir): self.label = None self.root_uuid = None self.root_dir = root_dir self.target_dir = target_dir self.requested_image_type = xml_state.get_build_type_name() if self.requested_image_type == 'pxe': self.requested_filesystem = xml_state.build_type.get_filesystem() else: self.requested_filesystem = self.requested_image_type if not self.requested_filesystem: raise KiwiFileSystemSetupError( 'No filesystem configured in %s type' % self.requested_image_type) self.filesystem_custom_parameters = { 'mount_options': xml_state.get_fs_mount_option_list(), 'create_options': xml_state.get_fs_create_option_list() } self.system_setup = SystemSetup(xml_state=xml_state, root_dir=self.root_dir) self.filename = ''.join([ target_dir, '/', xml_state.xml_data.get_name(), '.' + platform.machine(), '-' + xml_state.get_image_version(), '.', self.requested_filesystem ]) self.blocksize = xml_state.build_type.get_target_blocksize() self.filesystem_setup = FileSystemSetup(xml_state, root_dir) self.filesystems_no_device_node = ['squashfs'] self.result = Result(xml_state) self.runtime_config = RuntimeConfig()
def setup(self, mock_size): size = mock.Mock() size.accumulate_mbyte_file_sizes = mock.Mock(return_value=42) size.customize = mock.Mock(return_value=42) mock_size.return_value = size self.xml_state = mock.Mock() self.xml_state.get_build_type_name = mock.Mock(return_value='ext4') self.setup = FileSystemSetup(self.xml_state, 'root_dir')
def test_setup_with_pxe_type(self): self.xml_state.get_build_type_name = mock.Mock( return_value='pxe' ) self.xml_state.build_type.get_filesystem = mock.Mock( return_value='xfs' ) setup = FileSystemSetup( self.xml_state, 'root_dir' ) assert setup.requested_filesystem == 'xfs'
def __init__( self, xml_state: XMLState, target_dir: str, root_dir: str, custom_args: Dict = None ): self.label = None self.root_uuid = '' self.root_dir = root_dir self.target_dir = target_dir self.bundle_format = xml_state.get_build_type_bundle_format() self.requested_image_type = xml_state.get_build_type_name() if self.requested_image_type in Defaults.get_kis_image_types(): self.requested_filesystem = xml_state.build_type.get_filesystem() else: self.requested_filesystem = self.requested_image_type if not self.requested_filesystem: raise KiwiFileSystemSetupError( 'No filesystem configured in %s type' % self.requested_image_type ) self.filesystem_custom_parameters = { 'mount_options': xml_state.get_fs_mount_option_list(), 'create_options': xml_state.get_fs_create_option_list() } if self.requested_filesystem == 'squashfs': self.filesystem_custom_parameters['compression'] = \ xml_state.build_type.get_squashfscompression() self.system_setup = SystemSetup( xml_state=xml_state, root_dir=self.root_dir ) self.filename = ''.join( [ target_dir, '/', xml_state.xml_data.get_name(), '.' + Defaults.get_platform_name(), '-' + xml_state.get_image_version(), '.', self.requested_filesystem ] ) self.blocksize = xml_state.build_type.get_target_blocksize() self.filesystem_setup = FileSystemSetup(xml_state, root_dir) self.filesystems_no_device_node = [ 'squashfs' ] self.result = Result(xml_state) self.runtime_config = RuntimeConfig()
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
def test_init_with_unpartitioned(self, mock_warn): self.xml_state.get_build_type_unpartitioned_bytes = mock.Mock( return_value=1024) FileSystemSetup(self.xml_state, 'root_dir')
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