From 0031b6c2d21c4dcebf653251bb3228c84f8c3780 Mon Sep 17 00:00:00 2001 From: Neal Gompa Date: Sat, 24 Aug 2024 19:26:45 -0400 Subject: [PATCH] Add support for isomd5sum for tagging iso files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The isomd5sum tool suite is used and available on all supported distributions except SUSE distributions, and is necessary to produce conformant ISOs for most Linux distributions. This change adds support for isomd5sum tool suite for kiwi, though it does not extend the kiwi-live dracut module to use it. The upstream dracut dmsquash-live module must be used instead. Co-authored-by: Dan Čermák --- kiwi.yml | 3 ++ kiwi/defaults.py | 11 +++++++ kiwi/iso_tools/iso.py | 29 +++++++++++------ kiwi/runtime_checker.py | 5 +++ kiwi/runtime_config.py | 31 +++++++++++++++++++ .../invalid/.config/kiwi/config.yml | 1 + .../kiwi_config/ok/.config/kiwi/config.yml | 1 + .../kiwi_config/other/.config/kiwi/config.yml | 3 ++ test/unit/iso_tools/iso_test.py | 19 ++++++++++-- test/unit/runtime_checker_test.py | 15 +++++++-- test/unit/runtime_config_test.py | 8 +++++ 11 files changed, 113 insertions(+), 13 deletions(-) diff --git a/kiwi.yml b/kiwi.yml index 4e366169ca9..06910ea438d 100644 --- a/kiwi.yml +++ b/kiwi.yml @@ -60,6 +60,9 @@ # # Specify tool category which should be used to build iso images # # Possible values are: xorriso # - tool_category: xorriso +# # Specify media tag tool used to implant iso checksums +# # Possible values are checkmedia and isomd5sum +# - media_tag_tool: checkmedia # Setup process parameters for OCI toolchain diff --git a/kiwi/defaults.py b/kiwi/defaults.py index 1005b0f9a52..c40bf7e25f6 100644 --- a/kiwi/defaults.py +++ b/kiwi/defaults.py @@ -1758,6 +1758,17 @@ def get_iso_tool_category(): """ return 'xorriso' + @staticmethod + def get_iso_media_tag_tool(): + """ + Provides default iso media tag tool + + :return: name + + :rtype: str + """ + return 'checkmedia' + @staticmethod def get_container_compression(): """ diff --git a/kiwi/iso_tools/iso.py b/kiwi/iso_tools/iso.py index 43ece9c5eb0..3ac0215860c 100644 --- a/kiwi/iso_tools/iso.py +++ b/kiwi/iso_tools/iso.py @@ -18,6 +18,7 @@ # project from kiwi.defaults import Defaults from kiwi.command import Command +from kiwi.runtime_config import RuntimeConfig class Iso: @@ -42,12 +43,22 @@ def set_media_tag(isofile: str) -> None: :param str isofile: path to the ISO file """ - Command.run( - [ - 'tagmedia', - '--digest', 'sha256', - '--check', - '--pad', '0', - isofile - ] - ) + media_tagger = RuntimeConfig().get_iso_media_tag_tool() + if media_tagger == 'checkmedia': + Command.run( + [ + 'tagmedia', + '--digest', 'sha256', + '--check', + '--pad', '0', + isofile + ] + ) + elif media_tagger == 'isomd5sum': + Command.run( + [ + 'implantisomd5', + '--force', + isofile + ] + ) diff --git a/kiwi/runtime_checker.py b/kiwi/runtime_checker.py index 3dec6777053..4eabe0f7aa8 100644 --- a/kiwi/runtime_checker.py +++ b/kiwi/runtime_checker.py @@ -919,6 +919,11 @@ def check_mediacheck_installed(self) -> None: ''') if self.xml_state.build_type.get_mediacheck() is True: tool = 'tagmedia' + media_tagger = RuntimeConfig().get_iso_media_tag_tool() + if media_tagger == 'checkmedia': + tool = 'tagmedia' + elif media_tagger == 'isomd5sum': + tool = 'implantisomd5' if not Path.which(filename=tool, access_mode=os.X_OK): raise KiwiRuntimeError( message_tool_not_found.format(name=tool) diff --git a/kiwi/runtime_config.py b/kiwi/runtime_config.py index 4ed7ab9afd7..70a31ca5552 100644 --- a/kiwi/runtime_config.py +++ b/kiwi/runtime_config.py @@ -309,6 +309,37 @@ def get_iso_tool_category(self): ) return Defaults.get_iso_tool_category() + def get_iso_media_tag_tool(self): + """ + Return media tag tool used to checksum iso images + + iso: + - media_tag_tool: checkmedia + + if no or invalid configuration exists the default media tagger + from the Defaults class is returned + + :return: A name + + :rtype: str + """ + iso_media_tag_tool = self._get_attribute( + element='iso', attribute='media_tag_tool' + ) + if not iso_media_tag_tool: + return Defaults.get_iso_media_tag_tool() + elif 'checkmedia' in iso_media_tag_tool: + return iso_media_tag_tool + elif 'isomd5sum' in iso_media_tag_tool: + return iso_media_tag_tool + else: + log.warning( + 'Skipping invalid iso media tag tool: {0}'.format( + iso_media_tag_tool + ) + ) + return Defaults.get_iso_media_tag_tool() + def get_oci_archive_tool(self): """ Return OCI archive tool which should be used on creation of diff --git a/test/data/kiwi_config/invalid/.config/kiwi/config.yml b/test/data/kiwi_config/invalid/.config/kiwi/config.yml index 3e7305d13ae..db4dc92a3eb 100644 --- a/test/data/kiwi_config/invalid/.config/kiwi/config.yml +++ b/test/data/kiwi_config/invalid/.config/kiwi/config.yml @@ -1,5 +1,6 @@ iso: - tool_category: foo + - media_tag_tool: foo container: - compress: foo diff --git a/test/data/kiwi_config/ok/.config/kiwi/config.yml b/test/data/kiwi_config/ok/.config/kiwi/config.yml index 6a7a33da14d..fc19f50cda2 100644 --- a/test/data/kiwi_config/ok/.config/kiwi/config.yml +++ b/test/data/kiwi_config/ok/.config/kiwi/config.yml @@ -13,6 +13,7 @@ obs: iso: - tool_category: xorriso + - media_tag_tool: isomd5sum oci: - archive_tool: umoci diff --git a/test/data/kiwi_config/other/.config/kiwi/config.yml b/test/data/kiwi_config/other/.config/kiwi/config.yml index 568061c4246..0d94c3baac2 100644 --- a/test/data/kiwi_config/other/.config/kiwi/config.yml +++ b/test/data/kiwi_config/other/.config/kiwi/config.yml @@ -3,3 +3,6 @@ bundle: container: - compress: true + +iso: + - media_tag_tool: checkmedia diff --git a/test/unit/iso_tools/iso_test.py b/test/unit/iso_tools/iso_test.py index d3119dbed67..2a3b52324ff 100644 --- a/test/unit/iso_tools/iso_test.py +++ b/test/unit/iso_tools/iso_test.py @@ -1,4 +1,4 @@ -from unittest.mock import patch +from unittest.mock import patch, Mock from kiwi.defaults import Defaults from kiwi.iso_tools.iso import Iso @@ -13,8 +13,23 @@ def setup_method(self, cls): self.setup() @patch('kiwi.iso_tools.iso.Command.run') - def test_set_media_tag(self, mock_command): + @patch('kiwi.iso_tools.iso.RuntimeConfig') + def test_set_media_tag_checkmedia(self, mock_RuntimeConfig, mock_command): + runtime_config = Mock() + runtime_config.get_iso_media_tag_tool.return_value = 'checkmedia' + mock_RuntimeConfig.return_value = runtime_config Iso.set_media_tag('foo') mock_command.assert_called_once_with( ['tagmedia', '--digest', 'sha256', '--check', '--pad', '0', 'foo'] ) + + @patch('kiwi.iso_tools.iso.Command.run') + @patch('kiwi.iso_tools.iso.RuntimeConfig') + def test_set_media_tag_isomd5sum(self, mock_RuntimeConfig, mock_command): + runtime_config = Mock() + runtime_config.get_iso_media_tag_tool.return_value = 'isomd5sum' + mock_RuntimeConfig.return_value = runtime_config + Iso.set_media_tag('foo') + mock_command.assert_called_once_with( + ['implantisomd5', '--force', 'foo'] + ) diff --git a/test/unit/runtime_checker_test.py b/test/unit/runtime_checker_test.py index fd55f762f71..fb800a29d9b 100644 --- a/test/unit/runtime_checker_test.py +++ b/test/unit/runtime_checker_test.py @@ -6,6 +6,7 @@ from pytest import ( raises, fixture ) +import pytest from .test_helper import argv_kiwi_tests @@ -358,16 +359,26 @@ def test_check_efi_mode_for_disk_overlay_correctly_setup(self): self.runtime_checker.\ check_efi_mode_for_disk_overlay_correctly_setup() + @pytest.mark.parametrize("tool_name, tool_binary", [("isomd5sum", "implantisomd5"), ("checkmedia", "tagmedia")]) @patch('kiwi.runtime_checker.Path.which') - def test_check_mediacheck_installed_tagmedia_missing(self, mock_which): + @patch('kiwi.runtime_checker.RuntimeConfig') + def test_check_mediacheck_installed_implantisomd5_missing( + self, mock_RuntimeConfig, mock_which, tool_name, tool_binary + ): + runtime_config = Mock() + runtime_config.get_iso_media_tag_tool.return_value = tool_name + mock_RuntimeConfig.return_value = runtime_config + mock_which.return_value = False xml_state = XMLState( self.description.load(), ['vmxFlavour'], 'iso' ) runtime_checker = RuntimeChecker(xml_state) - with raises(KiwiRuntimeError): + with raises(KiwiRuntimeError) as rt_err_ctx: runtime_checker.check_mediacheck_installed() + assert f"Required tool {tool_binary} not found in caller environment" in str(rt_err_ctx.value) + def test_check_dracut_module_for_live_iso_in_package_list(self): xml_state = XMLState( self.description.load(), ['vmxFlavour'], 'iso' diff --git a/test/unit/runtime_config_test.py b/test/unit/runtime_config_test.py index 8de4a5345aa..2b250247921 100644 --- a/test/unit/runtime_config_test.py +++ b/test/unit/runtime_config_test.py @@ -66,6 +66,7 @@ def test_config_sections_from_home_base_config(self, mock_is_buildservice_worker 'https://api.example.com' assert runtime_config.get_container_compression() is False assert runtime_config.get_iso_tool_category() == 'xorriso' + assert runtime_config.get_iso_media_tag_tool() == 'isomd5sum' assert runtime_config.get_oci_archive_tool() == 'umoci' assert runtime_config.get_mapper_tool() == 'partx' assert runtime_config.get_package_changes() is True @@ -96,6 +97,7 @@ def test_config_sections_defaults( Defaults.get_obs_api_server_url() assert runtime_config.get_container_compression() is True assert runtime_config.get_iso_tool_category() == 'xorriso' + assert runtime_config.get_iso_media_tag_tool() == 'checkmedia' assert runtime_config.get_oci_archive_tool() == 'umoci' assert runtime_config.get_mapper_tool() == 'kpartx' assert runtime_config.get_package_changes() is False @@ -120,9 +122,15 @@ def test_config_sections_invalid(self): assert 'Skipping invalid iso tool category: foo' in \ self._caplog.text + with self._caplog.at_level(logging.WARNING): + assert runtime_config.get_iso_media_tag_tool() == "checkmedia" + assert 'Skipping invalid iso media tag tool: foo' in \ + self._caplog.text + def test_config_sections_other_settings(self): with patch.dict('os.environ', {'HOME': '../data/kiwi_config/other'}): runtime_config = RuntimeConfig(reread=True) assert runtime_config.get_container_compression() is True assert runtime_config.get_package_changes() is True + assert runtime_config.get_iso_media_tag_tool() == "checkmedia"