def test_relocate_boot_catalog(self, mock_open): mock_open.return_value = self.context_manager_mock volume_descriptor = \ bytes(b'CD001') + bytes(b'_') * (0x08c - 0x5) + bytes(b'0x1d5f23a') eltorito_descriptor = \ bytes(b'EL TORITO SPECIFICATION') + \ bytes(b'_') * (0x47 - 0x17) + bytes(b'0x1d5f23a') new_volume_descriptor = \ bytes(b'bogus') next_new_volume_descriptor = \ bytes(b'TEA01') new_boot_catalog = bytes(b'\x00') * 0x800 read_results = [ new_boot_catalog, next_new_volume_descriptor, new_volume_descriptor, bytes(b'catalog'), eltorito_descriptor, volume_descriptor ] def side_effect(arg): return read_results.pop() self.file_mock.read.side_effect = side_effect Iso.relocate_boot_catalog('isofile') assert self.file_mock.write.call_args_list == [ call(bytes(b'catalog')), call( bytes(b'EL TORITO SPECIFICATION') + bytes(b'_') * (0x47 - 0x17) + bytes(b'\x13\x00\x00\x005f23a') ) ]
def test_create_hybrid_with_multiple_errors(self, mock_command): command = mock.Mock() command.error = \ 'isohybrid: Warning: more than 1024 cylinders: 1817\n' + \ 'isohybrid: Not all BIOSes will be able to boot this device\n' + \ 'isohybrid: some other error we do not ignore' mock_command.return_value = command Iso.create_hybrid(42, '0x0815', 'some-iso', 'efi')
def test_create_hybrid_with_multiple_errors(self, mock_command): command = mock.Mock() command.error = \ 'isohybrid: Warning: more than 1024 cylinders: 1817\n' + \ 'isohybrid: Not all BIOSes will be able to boot this device\n' + \ 'isohybrid: some other error we do not ignore' mock_command.return_value = command with raises(KiwiCommandError): Iso.create_hybrid(42, '0x0815', 'some-iso', 'efi')
def test_create_hybrid(self, mock_command): command = mock.Mock() command.error = None mock_command.return_value = command Iso.create_hybrid(42, '0x0815', 'some-iso', 'efi') mock_command.assert_called_once_with([ 'isohybrid', '--offset', '42', '--id', '0x0815', '--type', '0x83', '--uefi', 'some-iso' ])
def test_iso_metadata_path_table_sector_invalid(self, mock_open): mock_open.return_value = self.context_manager_mock read_results = [bytes(b'EL TORITO SPECIFICATION'), bytes(b'CD001')] def side_effect(arg): return read_results.pop() self.file_mock.read.side_effect = side_effect Iso.fix_boot_catalog('isofile')
def test_create_hybrid_with_cylinders_warning(self, mock_command): command = mock.Mock() command.error = \ 'isohybrid: Warning: more than 1024 cylinders: 1817\n' + \ 'isohybrid: Not all BIOSes will be able to boot this device\n' mock_command.return_value = command Iso.create_hybrid(42, '0x0815', 'some-iso', 'efi') mock_command.assert_called_once_with([ 'isohybrid', '--offset', '42', '--id', '0x0815', '--type', '0x83', '--uefi', 'some-iso' ])
def test_iso_metadata_path_table_sector_invalid(self): read_results = [bytes(b'EL TORITO SPECIFICATION'), bytes(b'CD001')] def side_effect(arg): return read_results.pop() m_open = mock_open() with patch('builtins.open', m_open, create=True): m_open.return_value.read.side_effect = side_effect with raises(KiwiIsoMetaDataError): Iso.fix_boot_catalog('isofile')
def setup(self, mock_machine): mock_machine.return_value = 'x86_64' self.context_manager_mock = mock.Mock() self.file_mock = mock.Mock() self.enter_mock = mock.Mock() self.exit_mock = mock.Mock() self.enter_mock.return_value = self.file_mock setattr(self.context_manager_mock, '__enter__', self.enter_mock) setattr(self.context_manager_mock, '__exit__', self.exit_mock) self.iso = Iso('source-dir')
def test_iso_metadata_catalog_sector_invalid(self, mock_open): mock_open.return_value = self.context_manager_mock volume_descriptor = \ bytes(b'CD001') + bytes(b'_') * (0x08c - 0x5) + bytes(b'0x1d5f23a') read_results = [bytes(b'EL TORITO SPECIFICATION'), volume_descriptor] def side_effect(arg): return read_results.pop() self.file_mock.read.side_effect = side_effect Iso.fix_boot_catalog('isofile')
def test_create_hybrid(self, mock_command): command = mock.Mock() command.error = None mock_command.return_value = command Iso.create_hybrid(42, '0x0815', 'some-iso', 'efi') mock_command.assert_called_once_with( [ 'isohybrid', '--offset', '42', '--id', '0x0815', '--type', '0x83', '--uefi', 'some-iso' ] )
def test_iso_metadata_catalog_sector_invalid(self): volume_descriptor = \ bytes(b'CD001') + bytes(b'_') * (0x08c - 0x5) + bytes(b'0x1d5f23a') read_results = [bytes(b'EL TORITO SPECIFICATION'), volume_descriptor] def side_effect(arg): return read_results.pop() m_open = mock_open() with patch('builtins.open', m_open, create=True): m_open.return_value.read.side_effect = side_effect with raises(KiwiIsoMetaDataError): Iso.fix_boot_catalog('isofile')
def test_fix_boot_catalog(self, mock_open): mock_open.return_value = self.context_manager_mock volume_descriptor = \ bytes(b'CD001') + bytes(b'_') * (0x08c - 0x5) + bytes(b'0x1d5f23a') eltorito_descriptor = \ bytes(b'EL TORITO SPECIFICATION') + \ bytes(b'_') * (0x47 - 0x17) + bytes(b'0x1d5f23a') boot_catalog = bytes(b'_') * 64 + struct.pack('B', 0x88) + \ bytes(b'_') * 32 read_results = [ boot_catalog, eltorito_descriptor, volume_descriptor ] def side_effect(arg): return read_results.pop() self.file_mock.read.side_effect = side_effect Iso.fix_boot_catalog('isofile') if sys.byteorder == 'big': assert self.file_mock.write.call_args_list == [ call( bytes( b'_' ) * 44 + bytes( b'\x01Legacy (isolinux)\x00\x00\x91\xef\x00\x01' ) + bytes( b'\x00' ) * 28 + bytes( b'\x88___________\x01UEFI (grub)' ) + bytes(b'\x00') * 8 ) ] else: assert self.file_mock.write.call_args_list == [ call( bytes( b'_' ) * 44 + bytes( b'\x01Legacy (isolinux)\x00\x00\x91\xef\x01' ) + bytes( b'\x00' ) * 29 + bytes( b'\x88___________\x01UEFI (grub)' ) + bytes(b'\x00') * 8 ) ]
def test_create_hybrid_with_cylinders_warning(self, mock_command): command = mock.Mock() command.error = \ 'isohybrid: Warning: more than 1024 cylinders: 1817\n' + \ 'isohybrid: Not all BIOSes will be able to boot this device\n' mock_command.return_value = command Iso.create_hybrid(42, '0x0815', 'some-iso', 'efi') mock_command.assert_called_once_with( [ 'isohybrid', '--offset', '42', '--id', '0x0815', '--type', '0x83', '--uefi', 'some-iso' ] )
def test_fix_boot_catalog(self, mock_open): mock_open.return_value = self.context_manager_mock volume_descriptor = \ bytes(b'CD001') + bytes(b'_') * (0x08c - 0x5) + bytes(b'0x1d5f23a') eltorito_descriptor = \ bytes(b'EL TORITO SPECIFICATION') + \ bytes(b'_') * (0x47 - 0x17) + bytes(b'0x1d5f23a') boot_catalog = bytes(b'_') * 64 + struct.pack('B', 0x88) + \ bytes(b'_') * 32 read_results = [ boot_catalog, eltorito_descriptor, volume_descriptor ] def side_effect(arg): return read_results.pop() self.file_mock.read.side_effect = side_effect Iso.fix_boot_catalog('isofile') if sys.byteorder == 'big': assert self.file_mock.write.call_args_list == [ call( bytes(b'_') * 44 + bytes(b'\x01Legacy (isolinux)\x00\x00\x91\xef\x00\x01') + bytes(b'\x00') * 28 + bytes(b'\x88___________\x01UEFI (grub)') + bytes(b'\x00') * 8 ) ] else: assert self.file_mock.write.call_args_list == [ call( bytes(b'_') * 44 + bytes(b'\x01Legacy (isolinux)\x00\x00\x91\xef\x01') + bytes(b'\x00') * 29 + bytes(b'\x88___________\x01UEFI (grub)') + bytes(b'\x00') * 8 ) ]
def test_relocate_boot_catalog(self, mock_open): mock_open.return_value = self.context_manager_mock volume_descriptor = \ bytes(b'CD001') + bytes(b'_') * (0x08c - 0x5) + bytes(b'0x1d5f23a') eltorito_descriptor = \ bytes(b'EL TORITO SPECIFICATION') + \ bytes(b'_') * (0x47 - 0x17) + bytes(b'0x1d5f23a') new_volume_descriptor = \ bytes(b'bogus') next_new_volume_descriptor = \ bytes(b'TEA01') new_boot_catalog = bytes(b'\x00') * 0x800 read_results = [ new_boot_catalog, next_new_volume_descriptor, new_volume_descriptor, bytes(b'catalog'), eltorito_descriptor, volume_descriptor ] def side_effect(arg): return read_results.pop() self.file_mock.read.side_effect = side_effect Iso.relocate_boot_catalog('isofile') assert self.file_mock.write.call_args_list == [ call(bytes(b'catalog')), call( bytes( b'EL TORITO SPECIFICATION' ) + bytes( b'_' ) * (0x47 - 0x17) + bytes(b'\x13\x00\x00\x005f23a') ) ]
class TestIso: def setup(self): Defaults.set_platform_name('x86_64') self.iso = Iso('source-dir') @patch('os.path.exists') def test_setup_isolinux_boot_path_raises(self, mock_exists): mock_exists.return_value = False with raises(KiwiIsoLoaderError): self.iso.setup_isolinux_boot_path() @patch('os.path.exists') @patch('kiwi.iso_tools.iso.Command.run') def test_setup_isolinux_boot_path(self, mock_command, mock_exists): mock_exists.return_value = True self.iso.setup_isolinux_boot_path() mock_command.assert_called_once_with( [ 'isolinux-config', '--base', 'boot/x86_64/loader', 'source-dir/boot/x86_64/loader/isolinux.bin' ] ) @patch('kiwi.iso_tools.iso.Command.run') @patch('os.path.exists') def test_setup_isolinux_boot_path_failed_isolinux_config( self, mock_exists, mock_command ): mock_exists.return_value = True command_raises = [False, True] def side_effect(arg): if command_raises.pop(): raise Exception mock_command.side_effect = side_effect self.iso.setup_isolinux_boot_path() assert mock_command.call_args_list[1] == call( [ 'cp', '-a', '-l', 'source-dir/boot/x86_64/loader/', 'source-dir/isolinux/' ] ) @patch('kiwi.iso_tools.iso.Command.run') def test_set_media_tag(self, mock_command): Iso.set_media_tag('foo') mock_command.assert_called_once_with( ['tagmedia', '--md5', '--check', '--pad', '150', 'foo'] )
class TestIso: def setup(self): Defaults.set_platform_name('x86_64') self.iso = Iso('source-dir') def test_create_header_end_marker(self): m_open = mock_open() with patch('builtins.open', m_open, create=True): self.iso.create_header_end_marker() assert m_open.return_value.write.called_once_with( 'source-dir/header_end 1000000\n') @patch('os.path.exists') def test_setup_isolinux_boot_path_raises(self, mock_exists): mock_exists.return_value = False with raises(KiwiIsoLoaderError): self.iso.setup_isolinux_boot_path() @patch('os.path.exists') @patch('kiwi.iso_tools.iso.Command.run') def test_setup_isolinux_boot_path(self, mock_command, mock_exists): mock_exists.return_value = True self.iso.setup_isolinux_boot_path() mock_command.assert_called_once_with([ 'isolinux-config', '--base', 'boot/x86_64/loader', 'source-dir/boot/x86_64/loader/isolinux.bin' ]) @patch('kiwi.iso_tools.iso.Command.run') @patch('os.path.exists') def test_setup_isolinux_boot_path_failed_isolinux_config( self, mock_exists, mock_command): mock_exists.return_value = True command_raises = [False, True] def side_effect(arg): if command_raises.pop(): raise Exception mock_command.side_effect = side_effect self.iso.setup_isolinux_boot_path() assert mock_command.call_args_list[1] == call([ 'cp', '-a', '-l', 'source-dir/boot/x86_64/loader/', 'source-dir/isolinux/' ]) @pytest.mark.skipif(Path.which('isoinfo') is None, reason='requires cdrtools') def test_create_header_end_block_on_test_iso(self): temp_file = Temporary().new_file() self.iso.header_end_file = temp_file.name assert self.iso.create_header_end_block( '../data/iso_with_marker.iso') == 96 @patch('kiwi.iso_tools.iso.IsoToolsCdrTools') def test_create_header_end_block(self, mock_IsoToolsCdrTools): iso_tool = mock.Mock() iso_tool.list_iso.return_value = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] mock_IsoToolsCdrTools.return_value = iso_tool m_open = mock_open(read_data=b'7984fc91-a43f-4e45-bf27-6d3aa08b24cf') with patch('builtins.open', m_open, create=True): self.iso.create_header_end_block('some-iso-file') assert m_open.call_args_list == [ call('some-iso-file', 'rb'), call('source-dir/header_end', 'wb') ] @pytest.mark.skipif(Path.which('isoinfo') is None, reason='requires cdrtools') def test_create_header_end_block_raises_on_test_iso(self): temp_file = Temporary().new_file() self.iso.header_end_file = temp_file.name with raises(KiwiIsoLoaderError): self.iso.create_header_end_block('../data/iso_no_marker.iso') @patch('kiwi.iso_tools.iso.IsoToolsCdrTools') def test_create_header_end_block_raises(self, mock_IsoToolsCdrTools): with patch('builtins.open'): with raises(KiwiIsoLoaderError): self.iso.create_header_end_block('some-iso-file') @patch('kiwi.iso_tools.iso.Command.run') def test_create_hybrid(self, mock_command): command = mock.Mock() command.error = None mock_command.return_value = command Iso.create_hybrid(42, '0x0815', 'some-iso', 'efi') mock_command.assert_called_once_with([ 'isohybrid', '--offset', '42', '--id', '0x0815', '--type', '0x83', '--uefi', 'some-iso' ]) @patch('kiwi.iso_tools.iso.Command.run') def test_create_hybrid_with_error(self, mock_command): command = mock.Mock() command.error = 'some error message' mock_command.return_value = command with raises(KiwiCommandError): Iso.create_hybrid(42, '0x0815', 'some-iso', 'efi') @patch('kiwi.iso_tools.iso.Command.run') def test_create_hybrid_with_multiple_errors(self, mock_command): command = mock.Mock() command.error = \ 'isohybrid: Warning: more than 1024 cylinders: 1817\n' + \ 'isohybrid: Not all BIOSes will be able to boot this device\n' + \ 'isohybrid: some other error we do not ignore' mock_command.return_value = command with raises(KiwiCommandError): Iso.create_hybrid(42, '0x0815', 'some-iso', 'efi') @patch('kiwi.iso_tools.iso.Command.run') def test_create_hybrid_with_cylinders_warning(self, mock_command): command = mock.Mock() command.error = \ 'isohybrid: Warning: more than 1024 cylinders: 1817\n' + \ 'isohybrid: Not all BIOSes will be able to boot this device\n' mock_command.return_value = command Iso.create_hybrid(42, '0x0815', 'some-iso', 'efi') mock_command.assert_called_once_with([ 'isohybrid', '--offset', '42', '--id', '0x0815', '--type', '0x83', '--uefi', 'some-iso' ]) @patch('kiwi.iso_tools.iso.Command.run') def test_set_media_tag(self, mock_command): Iso.set_media_tag('foo') mock_command.assert_called_once_with( ['tagmedia', '--md5', '--check', '--pad', '150', 'foo']) def test_iso_metadata_iso9660_invalid(self): m_open = mock_open(read_data=b'bogus') with patch('builtins.open', m_open, create=True): with raises(KiwiIsoMetaDataError): Iso.fix_boot_catalog('isofile') def test_iso_metadata_not_bootable(self): m_open = mock_open(read_data=b'CD001') with patch('builtins.open', m_open, create=True): with raises(KiwiIsoMetaDataError): Iso.fix_boot_catalog('isofile') def test_iso_metadata_path_table_sector_invalid(self): read_results = [bytes(b'EL TORITO SPECIFICATION'), bytes(b'CD001')] def side_effect(arg): return read_results.pop() m_open = mock_open() with patch('builtins.open', m_open, create=True): m_open.return_value.read.side_effect = side_effect with raises(KiwiIsoMetaDataError): Iso.fix_boot_catalog('isofile') def test_iso_metadata_catalog_sector_invalid(self): volume_descriptor = \ bytes(b'CD001') + bytes(b'_') * (0x08c - 0x5) + bytes(b'0x1d5f23a') read_results = [bytes(b'EL TORITO SPECIFICATION'), volume_descriptor] def side_effect(arg): return read_results.pop() m_open = mock_open() with patch('builtins.open', m_open, create=True): m_open.return_value.read.side_effect = side_effect with raises(KiwiIsoMetaDataError): Iso.fix_boot_catalog('isofile') def test_iso_metadata_catalog_invalid(self): volume_descriptor = \ bytes(b'CD001') + bytes(b'_') * (0x08c - 0x5) + bytes(b'0x1d5f23a') eltorito_descriptor = \ bytes(b'EL TORITO SPECIFICATION') + \ bytes(b'_') * (0x47 - 0x17) + bytes(b'0x1d5f23a') read_results = [eltorito_descriptor, volume_descriptor] def side_effect(arg): return read_results.pop() m_open = mock_open() with patch('builtins.open', m_open, create=True): m_open.return_value.read.side_effect = side_effect with raises(KiwiIsoMetaDataError): Iso.fix_boot_catalog('isofile') def test_relocate_boot_catalog(self): volume_descriptor = \ bytes(b'CD001') + bytes(b'_') * (0x08c - 0x5) + bytes(b'0x1d5f23a') eltorito_descriptor = \ bytes(b'EL TORITO SPECIFICATION') + \ bytes(b'_') * (0x47 - 0x17) + bytes(b'0x1d5f23a') new_volume_descriptor = \ bytes(b'bogus') next_new_volume_descriptor = \ bytes(b'TEA01') new_boot_catalog = bytes(b'\x00') * 0x800 read_results = [ new_boot_catalog, next_new_volume_descriptor, new_volume_descriptor, bytes(b'catalog'), eltorito_descriptor, volume_descriptor ] def side_effect(arg): return read_results.pop() m_open = mock_open() with patch('builtins.open', m_open, create=True): m_open.return_value.read.side_effect = side_effect Iso.relocate_boot_catalog('isofile') assert m_open.return_value.write.call_args_list == [ call(bytes(b'catalog')), call( bytes(b'EL TORITO SPECIFICATION') + bytes(b'_') * (0x47 - 0x17) + bytes(b'\x13\x00\x00\x005f23a')) ] def test_fix_boot_catalog(self): volume_descriptor = \ bytes(b'CD001') + bytes(b'_') * (0x08c - 0x5) + bytes(b'0x1d5f23a') eltorito_descriptor = \ bytes(b'EL TORITO SPECIFICATION') + \ bytes(b'_') * (0x47 - 0x17) + bytes(b'0x1d5f23a') boot_catalog = bytes(b'_') * 64 + struct.pack('B', 0x88) + \ bytes(b'_') * 32 read_results = [boot_catalog, eltorito_descriptor, volume_descriptor] def side_effect(arg): return read_results.pop() m_open = mock_open() with patch('builtins.open', m_open, create=True): m_open.return_value.read.side_effect = side_effect Iso.fix_boot_catalog('isofile') if sys.byteorder == 'big': assert self.file_mock.write.call_args_list == [ call( bytes(b'_') * 44 + bytes(b'\x01Legacy (isolinux)\x00\x00\x91\xef\x00\x01') + bytes(b'\x00') * 28 + bytes(b'\x88___________\x01UEFI (grub)') + bytes(b'\x00') * 8) ] else: assert m_open.return_value.write.call_args_list == [ call( bytes(b'_') * 44 + bytes(b'\x01Legacy (isolinux)\x00\x00\x91\xef\x01') + bytes(b'\x00') * 29 + bytes(b'\x88___________\x01UEFI (grub)') + bytes(b'\x00') * 8) ]
def test_set_media_tag(self, mock_command): Iso.set_media_tag('foo') mock_command.assert_called_once_with( ['tagmedia', '--md5', '--check', '--pad', '150', 'foo'] )
def test_iso_metadata_not_bootable(self): m_open = mock_open(read_data=b'CD001') with patch('builtins.open', m_open, create=True): with raises(KiwiIsoMetaDataError): Iso.fix_boot_catalog('isofile')
def test_iso_metadata_iso9660_invalid(self): m_open = mock_open(read_data=b'bogus') with patch('builtins.open', m_open, create=True): with raises(KiwiIsoMetaDataError): Iso.fix_boot_catalog('isofile')
class TestIso(object): @patch('platform.machine') def setup(self, mock_machine): mock_machine.return_value = 'x86_64' self.context_manager_mock = mock.Mock() self.file_mock = mock.Mock() self.enter_mock = mock.Mock() self.exit_mock = mock.Mock() self.enter_mock.return_value = self.file_mock setattr(self.context_manager_mock, '__enter__', self.enter_mock) setattr(self.context_manager_mock, '__exit__', self.exit_mock) self.iso = Iso('source-dir') @patch_open def test_create_header_end_marker(self, mock_open): mock_open.return_value = self.context_manager_mock self.iso.create_header_end_marker() assert self.file_mock.write.called_once_with( 'source-dir/header_end 1000000\n') @raises(KiwiIsoLoaderError) @patch('os.path.exists') def test_setup_isolinux_boot_path_raises(self, mock_exists): mock_exists.return_value = False self.iso.setup_isolinux_boot_path() @patch('os.path.exists') @patch('kiwi.iso_tools.iso.Command.run') def test_setup_isolinux_boot_path(self, mock_command, mock_exists): mock_exists.return_value = True self.iso.setup_isolinux_boot_path() mock_command.assert_called_once_with([ 'isolinux-config', '--base', 'boot/x86_64/loader', 'source-dir/boot/x86_64/loader/isolinux.bin' ]) @patch('kiwi.iso_tools.iso.Command.run') @patch('kiwi.iso_tools.iso.Path.create') @patch('os.path.exists') def test_setup_isolinux_boot_path_failed_isolinux_config( self, mock_exists, mock_path, mock_command): mock_exists.return_value = True command_raises = [False, True] def side_effect(arg): if command_raises.pop(): raise Exception mock_command.side_effect = side_effect self.iso.setup_isolinux_boot_path() mock_path.assert_called_once_with('source-dir/isolinux') assert mock_command.call_args_list[1] == call([ 'bash', '-c', 'ln source-dir/boot/x86_64/loader/* source-dir/isolinux' ]) def test_create_header_end_block(self): temp_file = NamedTemporaryFile() self.iso.header_end_file = temp_file.name assert self.iso.create_header_end_block( '../data/iso_with_marker.iso') == 96 @raises(KiwiIsoLoaderError) def test_create_header_end_block_raises(self): temp_file = NamedTemporaryFile() self.iso.header_end_file = temp_file.name self.iso.create_header_end_block('../data/iso_no_marker.iso') @patch('kiwi.iso_tools.iso.Command.run') def test_create_hybrid(self, mock_command): command = mock.Mock() command.error = None mock_command.return_value = command Iso.create_hybrid(42, '0x0815', 'some-iso', 'efi') mock_command.assert_called_once_with([ 'isohybrid', '--offset', '42', '--id', '0x0815', '--type', '0x83', '--uefi', 'some-iso' ]) @raises(KiwiCommandError) @patch('kiwi.iso_tools.iso.Command.run') def test_create_hybrid_with_error(self, mock_command): command = mock.Mock() command.error = 'some error message' mock_command.return_value = command Iso.create_hybrid(42, '0x0815', 'some-iso', 'efi') @raises(KiwiCommandError) @patch('kiwi.iso_tools.iso.Command.run') def test_create_hybrid_with_multiple_errors(self, mock_command): command = mock.Mock() command.error = \ 'isohybrid: Warning: more than 1024 cylinders: 1817\n' + \ 'isohybrid: Not all BIOSes will be able to boot this device\n' + \ 'isohybrid: some other error we do not ignore' mock_command.return_value = command Iso.create_hybrid(42, '0x0815', 'some-iso', 'efi') @patch('kiwi.iso_tools.iso.Command.run') def test_create_hybrid_with_cylinders_warning(self, mock_command): command = mock.Mock() command.error = \ 'isohybrid: Warning: more than 1024 cylinders: 1817\n' + \ 'isohybrid: Not all BIOSes will be able to boot this device\n' mock_command.return_value = command Iso.create_hybrid(42, '0x0815', 'some-iso', 'efi') mock_command.assert_called_once_with([ 'isohybrid', '--offset', '42', '--id', '0x0815', '--type', '0x83', '--uefi', 'some-iso' ]) @patch('kiwi.iso_tools.iso.Command.run') def test_set_media_tag(self, mock_command): Iso.set_media_tag('foo') mock_command.assert_called_once_with( ['tagmedia', '--md5', '--check', '--pad', '150', 'foo']) @patch_open @raises(KiwiIsoMetaDataError) def test_iso_metadata_iso9660_invalid(self, mock_open): mock_open.return_value = self.context_manager_mock self.file_mock.read.return_value = bytes(b'bogus') Iso.fix_boot_catalog('isofile') @patch_open @raises(KiwiIsoMetaDataError) def test_iso_metadata_not_bootable(self, mock_open): mock_open.return_value = self.context_manager_mock self.file_mock.read.return_value = bytes(b'CD001') Iso.fix_boot_catalog('isofile') @patch_open @raises(KiwiIsoMetaDataError) def test_iso_metadata_path_table_sector_invalid(self, mock_open): mock_open.return_value = self.context_manager_mock read_results = [bytes(b'EL TORITO SPECIFICATION'), bytes(b'CD001')] def side_effect(arg): return read_results.pop() self.file_mock.read.side_effect = side_effect Iso.fix_boot_catalog('isofile') @patch_open @raises(KiwiIsoMetaDataError) def test_iso_metadata_catalog_sector_invalid(self, mock_open): mock_open.return_value = self.context_manager_mock volume_descriptor = \ bytes(b'CD001') + bytes(b'_') * (0x08c - 0x5) + bytes(b'0x1d5f23a') read_results = [bytes(b'EL TORITO SPECIFICATION'), volume_descriptor] def side_effect(arg): return read_results.pop() self.file_mock.read.side_effect = side_effect Iso.fix_boot_catalog('isofile') @patch_open @raises(KiwiIsoMetaDataError) def test_iso_metadata_catalog_invalid(self, mock_open): mock_open.return_value = self.context_manager_mock volume_descriptor = \ bytes(b'CD001') + bytes(b'_') * (0x08c - 0x5) + bytes(b'0x1d5f23a') eltorito_descriptor = \ bytes(b'EL TORITO SPECIFICATION') + \ bytes(b'_') * (0x47 - 0x17) + bytes(b'0x1d5f23a') read_results = [eltorito_descriptor, volume_descriptor] def side_effect(arg): return read_results.pop() self.file_mock.read.side_effect = side_effect Iso.fix_boot_catalog('isofile') @patch_open def test_relocate_boot_catalog(self, mock_open): mock_open.return_value = self.context_manager_mock volume_descriptor = \ bytes(b'CD001') + bytes(b'_') * (0x08c - 0x5) + bytes(b'0x1d5f23a') eltorito_descriptor = \ bytes(b'EL TORITO SPECIFICATION') + \ bytes(b'_') * (0x47 - 0x17) + bytes(b'0x1d5f23a') new_volume_descriptor = \ bytes(b'bogus') next_new_volume_descriptor = \ bytes(b'TEA01') new_boot_catalog = bytes(b'\x00') * 0x800 read_results = [ new_boot_catalog, next_new_volume_descriptor, new_volume_descriptor, bytes(b'catalog'), eltorito_descriptor, volume_descriptor ] def side_effect(arg): return read_results.pop() self.file_mock.read.side_effect = side_effect Iso.relocate_boot_catalog('isofile') assert self.file_mock.write.call_args_list == [ call(bytes(b'catalog')), call( bytes(b'EL TORITO SPECIFICATION') + bytes(b'_') * (0x47 - 0x17) + bytes(b'\x13\x00\x00\x005f23a')) ] @patch_open def test_fix_boot_catalog(self, mock_open): mock_open.return_value = self.context_manager_mock volume_descriptor = \ bytes(b'CD001') + bytes(b'_') * (0x08c - 0x5) + bytes(b'0x1d5f23a') eltorito_descriptor = \ bytes(b'EL TORITO SPECIFICATION') + \ bytes(b'_') * (0x47 - 0x17) + bytes(b'0x1d5f23a') boot_catalog = bytes(b'_') * 64 + struct.pack('B', 0x88) + \ bytes(b'_') * 32 read_results = [boot_catalog, eltorito_descriptor, volume_descriptor] def side_effect(arg): return read_results.pop() self.file_mock.read.side_effect = side_effect Iso.fix_boot_catalog('isofile') if sys.byteorder == 'big': assert self.file_mock.write.call_args_list == [ call( bytes(b'_') * 44 + bytes(b'\x01Legacy (isolinux)\x00\x00\x91\xef\x00\x01') + bytes(b'\x00') * 28 + bytes(b'\x88___________\x01UEFI (grub)') + bytes(b'\x00') * 8) ] else: assert self.file_mock.write.call_args_list == [ call( bytes(b'_') * 44 + bytes(b'\x01Legacy (isolinux)\x00\x00\x91\xef\x01') + bytes(b'\x00') * 29 + bytes(b'\x88___________\x01UEFI (grub)') + bytes(b'\x00') * 8) ]
def setup(self): Defaults.set_platform_name('x86_64') self.iso = Iso('source-dir')
def create_on_file(self, filename, label=None, exclude=None): """ Create iso filesystem from data tree There is no label which could be set for iso filesystem thus this parameter is not used :param string filename: result file path name :param string label: unused :param string exclude: unused """ meta_data = self.custom_args['meta_data'] efi_mode = meta_data.get('efi_mode') iso_tool = IsoTools(self.root_dir) iso = Iso(self.root_dir) if not efi_mode: iso.setup_isolinux_boot_path() if not iso_tool.has_iso_hybrid_capability(): iso.create_header_end_marker() iso_tool.init_iso_creation_parameters(meta_data) iso_tool.add_efi_loader_parameters() iso_tool.create_iso(filename) if not iso_tool.has_iso_hybrid_capability(): hybrid_offset = iso.create_header_end_block(filename) iso_tool.create_iso(filename, hidden_files=[iso.header_end_name]) iso.relocate_boot_catalog(filename) iso.fix_boot_catalog(filename) mbr_id = meta_data['mbr_id'] if 'mbr_id' in meta_data else \ '0xffffffff' iso.create_hybrid(hybrid_offset, mbr_id, filename, bool(efi_mode))
class TestIso(object): @patch('platform.machine') def setup(self, mock_machine): mock_machine.return_value = 'x86_64' self.context_manager_mock = mock.Mock() self.file_mock = mock.Mock() self.enter_mock = mock.Mock() self.exit_mock = mock.Mock() self.enter_mock.return_value = self.file_mock setattr(self.context_manager_mock, '__enter__', self.enter_mock) setattr(self.context_manager_mock, '__exit__', self.exit_mock) self.iso = Iso('source-dir') @patch_open def test_create_header_end_marker(self, mock_open): mock_open.return_value = self.context_manager_mock self.iso.create_header_end_marker() assert self.file_mock.write.called_once_with( 'source-dir/header_end 1000000\n' ) @raises(KiwiIsoLoaderError) @patch('os.path.exists') def test_setup_isolinux_boot_path_raises(self, mock_exists): mock_exists.return_value = False self.iso.setup_isolinux_boot_path() @patch('os.path.exists') @patch('kiwi.iso_tools.iso.Command.run') def test_setup_isolinux_boot_path(self, mock_command, mock_exists): mock_exists.return_value = True self.iso.setup_isolinux_boot_path() mock_command.assert_called_once_with( [ 'isolinux-config', '--base', 'boot/x86_64/loader', 'source-dir/boot/x86_64/loader/isolinux.bin' ] ) @patch('kiwi.iso_tools.iso.Command.run') @patch('kiwi.iso_tools.iso.Path.create') @patch('os.path.exists') def test_setup_isolinux_boot_path_failed_isolinux_config( self, mock_exists, mock_path, mock_command ): mock_exists.return_value = True command_raises = [False, True] def side_effect(arg): if command_raises.pop(): raise Exception mock_command.side_effect = side_effect self.iso.setup_isolinux_boot_path() mock_path.assert_called_once_with('source-dir/isolinux') assert mock_command.call_args_list[1] == call( [ 'bash', '-c', 'ln source-dir/boot/x86_64/loader/* source-dir/isolinux' ] ) def test_create_header_end_block(self): temp_file = NamedTemporaryFile() self.iso.header_end_file = temp_file.name assert self.iso.create_header_end_block( '../data/iso_with_marker.iso' ) == 96 @raises(KiwiIsoLoaderError) def test_create_header_end_block_raises(self): temp_file = NamedTemporaryFile() self.iso.header_end_file = temp_file.name self.iso.create_header_end_block( '../data/iso_no_marker.iso' ) @patch('kiwi.iso_tools.iso.Command.run') def test_create_hybrid(self, mock_command): command = mock.Mock() command.error = None mock_command.return_value = command Iso.create_hybrid(42, '0x0815', 'some-iso', 'efi') mock_command.assert_called_once_with( [ 'isohybrid', '--offset', '42', '--id', '0x0815', '--type', '0x83', '--uefi', 'some-iso' ] ) @raises(KiwiCommandError) @patch('kiwi.iso_tools.iso.Command.run') def test_create_hybrid_with_error(self, mock_command): command = mock.Mock() command.error = 'some error message' mock_command.return_value = command Iso.create_hybrid(42, '0x0815', 'some-iso', 'efi') @raises(KiwiCommandError) @patch('kiwi.iso_tools.iso.Command.run') def test_create_hybrid_with_multiple_errors(self, mock_command): command = mock.Mock() command.error = \ 'isohybrid: Warning: more than 1024 cylinders: 1817\n' + \ 'isohybrid: Not all BIOSes will be able to boot this device\n' + \ 'isohybrid: some other error we do not ignore' mock_command.return_value = command Iso.create_hybrid(42, '0x0815', 'some-iso', 'efi') @patch('kiwi.iso_tools.iso.Command.run') def test_create_hybrid_with_cylinders_warning(self, mock_command): command = mock.Mock() command.error = \ 'isohybrid: Warning: more than 1024 cylinders: 1817\n' + \ 'isohybrid: Not all BIOSes will be able to boot this device\n' mock_command.return_value = command Iso.create_hybrid(42, '0x0815', 'some-iso', 'efi') mock_command.assert_called_once_with( [ 'isohybrid', '--offset', '42', '--id', '0x0815', '--type', '0x83', '--uefi', 'some-iso' ] ) @patch('kiwi.iso_tools.iso.Command.run') def test_set_media_tag(self, mock_command): Iso.set_media_tag('foo') mock_command.assert_called_once_with( ['tagmedia', '--md5', '--check', '--pad', '150', 'foo'] ) @patch_open @raises(KiwiIsoMetaDataError) def test_iso_metadata_iso9660_invalid(self, mock_open): mock_open.return_value = self.context_manager_mock self.file_mock.read.return_value = bytes(b'bogus') Iso.fix_boot_catalog('isofile') @patch_open @raises(KiwiIsoMetaDataError) def test_iso_metadata_not_bootable(self, mock_open): mock_open.return_value = self.context_manager_mock self.file_mock.read.return_value = bytes(b'CD001') Iso.fix_boot_catalog('isofile') @patch_open @raises(KiwiIsoMetaDataError) def test_iso_metadata_path_table_sector_invalid(self, mock_open): mock_open.return_value = self.context_manager_mock read_results = [bytes(b'EL TORITO SPECIFICATION'), bytes(b'CD001')] def side_effect(arg): return read_results.pop() self.file_mock.read.side_effect = side_effect Iso.fix_boot_catalog('isofile') @patch_open @raises(KiwiIsoMetaDataError) def test_iso_metadata_catalog_sector_invalid(self, mock_open): mock_open.return_value = self.context_manager_mock volume_descriptor = \ bytes(b'CD001') + bytes(b'_') * (0x08c - 0x5) + bytes(b'0x1d5f23a') read_results = [bytes(b'EL TORITO SPECIFICATION'), volume_descriptor] def side_effect(arg): return read_results.pop() self.file_mock.read.side_effect = side_effect Iso.fix_boot_catalog('isofile') @patch_open @raises(KiwiIsoMetaDataError) def test_iso_metadata_catalog_invalid(self, mock_open): mock_open.return_value = self.context_manager_mock volume_descriptor = \ bytes(b'CD001') + bytes(b'_') * (0x08c - 0x5) + bytes(b'0x1d5f23a') eltorito_descriptor = \ bytes(b'EL TORITO SPECIFICATION') + \ bytes(b'_') * (0x47 - 0x17) + bytes(b'0x1d5f23a') read_results = [eltorito_descriptor, volume_descriptor] def side_effect(arg): return read_results.pop() self.file_mock.read.side_effect = side_effect Iso.fix_boot_catalog('isofile') @patch_open def test_relocate_boot_catalog(self, mock_open): mock_open.return_value = self.context_manager_mock volume_descriptor = \ bytes(b'CD001') + bytes(b'_') * (0x08c - 0x5) + bytes(b'0x1d5f23a') eltorito_descriptor = \ bytes(b'EL TORITO SPECIFICATION') + \ bytes(b'_') * (0x47 - 0x17) + bytes(b'0x1d5f23a') new_volume_descriptor = \ bytes(b'bogus') next_new_volume_descriptor = \ bytes(b'TEA01') new_boot_catalog = bytes(b'\x00') * 0x800 read_results = [ new_boot_catalog, next_new_volume_descriptor, new_volume_descriptor, bytes(b'catalog'), eltorito_descriptor, volume_descriptor ] def side_effect(arg): return read_results.pop() self.file_mock.read.side_effect = side_effect Iso.relocate_boot_catalog('isofile') assert self.file_mock.write.call_args_list == [ call(bytes(b'catalog')), call( bytes(b'EL TORITO SPECIFICATION') + bytes(b'_') * (0x47 - 0x17) + bytes(b'\x13\x00\x00\x005f23a') ) ] @patch_open def test_fix_boot_catalog(self, mock_open): mock_open.return_value = self.context_manager_mock volume_descriptor = \ bytes(b'CD001') + bytes(b'_') * (0x08c - 0x5) + bytes(b'0x1d5f23a') eltorito_descriptor = \ bytes(b'EL TORITO SPECIFICATION') + \ bytes(b'_') * (0x47 - 0x17) + bytes(b'0x1d5f23a') boot_catalog = bytes(b'_') * 64 + struct.pack('B', 0x88) + \ bytes(b'_') * 32 read_results = [ boot_catalog, eltorito_descriptor, volume_descriptor ] def side_effect(arg): return read_results.pop() self.file_mock.read.side_effect = side_effect Iso.fix_boot_catalog('isofile') if sys.byteorder == 'big': assert self.file_mock.write.call_args_list == [ call( bytes(b'_') * 44 + bytes(b'\x01Legacy (isolinux)\x00\x00\x91\xef\x00\x01') + bytes(b'\x00') * 28 + bytes(b'\x88___________\x01UEFI (grub)') + bytes(b'\x00') * 8 ) ] else: assert self.file_mock.write.call_args_list == [ call( bytes(b'_') * 44 + bytes(b'\x01Legacy (isolinux)\x00\x00\x91\xef\x01') + bytes(b'\x00') * 29 + bytes(b'\x88___________\x01UEFI (grub)') + bytes(b'\x00') * 8 ) ]
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() } } # 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 ) # prepare dracut initrd call self.boot_image.prepare() # 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['meta_data']['udf'] = True # 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
def setup(self, mock_machine): mock_machine.return_value = 'x86_64' self.iso = Iso('source-dir')
def create_on_file(self, filename, label=None, exclude=None): """ Create iso filesystem from data tree There is no label which could be set for iso filesystem thus this parameter is not used :param string filename: result file path name :param string label: unused :param string exclude: unused """ meta_data = self.custom_args['meta_data'] iso_tool = IsoTools(self.root_dir) iso = Iso(self.root_dir) iso.setup_isolinux_boot_path() if not iso_tool.has_iso_hybrid_capability(): iso.create_header_end_marker() iso_tool.init_iso_creation_parameters(meta_data) iso_tool.add_efi_loader_parameters() iso_tool.create_iso(filename) if not iso_tool.has_iso_hybrid_capability(): hybrid_offset = iso.create_header_end_block(filename) iso_tool.create_iso( filename, hidden_files=[iso.header_end_name] ) iso.relocate_boot_catalog(filename) iso.fix_boot_catalog(filename) efi_mode = meta_data['efi_mode'] if 'efi_mode' in meta_data else \ False mbr_id = meta_data['mbr_id'] if 'mbr_id' in meta_data else \ '0xffffffff' iso.create_hybrid( hybrid_offset, mbr_id, filename, efi_mode )
def test_iso_metadata_iso9660_invalid(self, mock_open): mock_open.return_value = self.context_manager_mock self.file_mock.read.return_value = bytes(b'bogus') Iso.fix_boot_catalog('isofile')
def test_create_hybrid_with_error(self, mock_command): command = mock.Mock() command.error = 'some error message' mock_command.return_value = command Iso.create_hybrid(42, '0x0815', 'some-iso', 'efi')
def test_create_hybrid_with_error(self, mock_command): command = mock.Mock() command.error = 'some error message' mock_command.return_value = command with raises(KiwiCommandError): Iso.create_hybrid(42, '0x0815', 'some-iso', 'efi')
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
def test_iso_metadata_not_bootable(self, mock_open): mock_open.return_value = self.context_manager_mock self.file_mock.read.return_value = bytes(b'CD001') Iso.fix_boot_catalog('isofile')
def create_on_file(self, filename, label=None, exclude=None): """ Create iso filesystem from data tree There is no label which could be set for iso filesystem thus this parameter is not used :param string filename: result file path name :param string label: unused :param string exclude: unused """ meta_data = self.custom_args['meta_data'] efi_mode = meta_data.get('efi_mode') iso_tool = IsoTools(self.root_dir) iso = Iso(self.root_dir) if not efi_mode: iso.setup_isolinux_boot_path() if not iso_tool.has_iso_hybrid_capability(): iso.create_header_end_marker() iso_tool.init_iso_creation_parameters(meta_data) iso_tool.add_efi_loader_parameters() iso_tool.create_iso(filename) if not iso_tool.has_iso_hybrid_capability(): if not efi_mode: hybrid_offset = iso.create_header_end_block(filename) iso_tool.create_iso( filename, hidden_files=[iso.header_end_name] ) iso.relocate_boot_catalog(filename) iso.fix_boot_catalog(filename) mbr_id = meta_data['mbr_id'] if 'mbr_id' in meta_data else \ '0xffffffff' iso.create_hybrid( hybrid_offset, mbr_id, filename ) else: message = dedent(''' Can't create hybrid ISO in EFI mode with cdrtools isohybrid requires isolinux as loader. In EFI mode the configured bootloader e.g grub is used and no isolinux signature exists. ''').strip() + os.linesep log.warning(message)
def test_set_media_tag(self, mock_command): Iso.set_media_tag('foo') mock_command.assert_called_once_with( ['tagmedia', '--md5', '--check', '--pad', '150', 'foo'])