diff --git a/1782.patch b/1782.patch new file mode 100644 index 00000000..ce03c1f4 --- /dev/null +++ b/1782.patch @@ -0,0 +1,286 @@ +From d9d21d3cf4eaad5cc7f2959a4abdafed781bb9cf Mon Sep 17 00:00:00 2001 +From: Lubomír Sedlář +Date: Aug 28 2024 11:07:12 +0000 +Subject: [PATCH 1/2] kiwibuild: Fix location and metadata for ISOs + + +When Kiwi builds an ISO, it is always supposed to be bootable and should +be located in the iso/ subdirectory. + +Any other kind of image should still land in images/ and be listed as +not bootable in the metadata. + +Relates: https://pagure.io/pungi-fedora/issue/1342 +Signed-off-by: Lubomír Sedlář + +--- + +diff --git a/pungi/phases/kiwibuild.py b/pungi/phases/kiwibuild.py +index 7ce3a54..12ec26d 100644 +--- a/pungi/phases/kiwibuild.py ++++ b/pungi/phases/kiwibuild.py +@@ -184,10 +184,20 @@ class RunKiwiBuildThread(WorkerThread): + # image_dir is absolute path to which the image should be copied. + # We also need the same path as relative to compose directory for + # including in the metadata. +- image_dir = compose.paths.compose.image_dir(variant) % {"arch": arch} +- rel_image_dir = compose.paths.compose.image_dir( +- variant, relative=True +- ) % {"arch": arch} ++ if format_ == "iso": ++ # If the produced image is actually an ISO, it should go to ++ # iso/ subdirectory. ++ image_dir = compose.paths.compose.iso_dir(arch, variant) ++ rel_image_dir = compose.paths.compose.iso_dir( ++ arch, variant, relative=True ++ ) ++ else: ++ image_dir = compose.paths.compose.image_dir(variant) % { ++ "arch": arch ++ } ++ rel_image_dir = compose.paths.compose.image_dir( ++ variant, relative=True ++ ) % {"arch": arch} + util.makedirs(image_dir) + + filename = os.path.basename(path) +@@ -211,7 +221,8 @@ class RunKiwiBuildThread(WorkerThread): + img.arch = arch + img.disc_number = 1 # We don't expect multiple disks + img.disc_count = 1 +- img.bootable = False ++ # Kiwi produces only bootable ISOs. Other kinds of images are ++ img.bootable = format_ == "iso" + img.subvariant = config.get("subvariant", variant.uid) + setattr(img, "can_fail", arch in self.failable_arches) + setattr(img, "deliverable", "kiwibuild") +diff --git a/tests/test_kiwibuildphase.py b/tests/test_kiwibuildphase.py +index 50116a2..491dbf3 100644 +--- a/tests/test_kiwibuildphase.py ++++ b/tests/test_kiwibuildphase.py +@@ -242,13 +242,14 @@ class TestKiwiBuildPhase(PungiTestCase): + @mock.patch("pungi.util.get_file_size") + @mock.patch("pungi.wrappers.kojiwrapper.KojiWrapper") + class TestKiwiBuildThread(PungiTestCase): +- def _img_path(self, arch, filename=None): +- path = self.topdir + "/compose/Server/%s/images" % arch ++ def _img_path(self, arch, filename=None, dir=None): ++ dir = dir or "images" ++ path = self.topdir + "/compose/Server/%s/%s" % (arch, dir) + if filename: + path += "/" + filename + return path + +- def test_process(self, KojiWrapper, get_file_size, get_mtime, Linker): ++ def test_process_vagrant_box(self, KojiWrapper, get_file_size, get_mtime, Linker): + img_name = "FCBG.{arch}-Rawhide-1.6.vagrant.libvirt.box" + self.repo = self.topdir + "/compose/Server/$arch/os" + compose = DummyCompose( +@@ -353,6 +354,114 @@ class TestKiwiBuildThread(PungiTestCase): + assert "vagrant-libvirt.box" == image.format + assert "vagrant-libvirt" == image.type + assert "Test" == image.subvariant ++ assert not image.bootable ++ ++ def test_process_iso(self, KojiWrapper, get_file_size, get_mtime, Linker): ++ img_name = "FCBG.{arch}-Rawhide-1.6.iso" ++ self.repo = self.topdir + "/compose/Server/$arch/os" ++ compose = DummyCompose( ++ self.topdir, ++ { ++ "koji_profile": "koji", ++ "kiwibuild_bundle_format": "%N-%P-40_Beta-%I.%A.%T", ++ }, ++ ) ++ config = _merge({"subvariant": "Test"}, MINIMAL_CONF) ++ pool = mock.Mock() ++ ++ get_image_paths = KojiWrapper.return_value.get_image_paths ++ get_image_paths.return_value = { ++ "x86_64": [ ++ "/koji/task/1234/FCBG.x86_64-Rawhide-1.6.packages", ++ "/koji/task/1234/%s" % img_name.format(arch="x86_64"), ++ ], ++ "amd64": [ ++ "/koji/task/1234/FCBG.amd64-Rawhide-1.6.packages", ++ "/koji/task/1234/%s" % img_name.format(arch="amd64"), ++ ], ++ } ++ ++ KojiWrapper.return_value.koji_proxy.kiwiBuild.return_value = 1234 ++ KojiWrapper.return_value.watch_task.return_value = 0 ++ ++ t = RunKiwiBuildThread(pool) ++ get_file_size.return_value = 1024 ++ get_mtime.return_value = 13579 ++ t.process( ++ ( ++ compose, ++ compose.variants["Server"], ++ config, ++ ["amd64", "x86_64"], ++ { ++ "release": "1.6", ++ "target": "f40", ++ "descscm": MINIMAL_CONF["description_scm"], ++ "descpath": MINIMAL_CONF["description_path"], ++ "type": "t", ++ "type_attr": ["ta"], ++ "bundle_name_format": "fmt", ++ "version": "v", ++ "repo_releasever": "r", ++ }, ++ [self.repo], ++ [], ++ ), ++ 1, ++ ) ++ ++ assert KojiWrapper.return_value.koji_proxy.kiwiBuild.mock_calls == [ ++ mock.call( ++ "f40", ++ ["amd64", "x86_64"], ++ MINIMAL_CONF["description_scm"], ++ MINIMAL_CONF["description_path"], ++ profile=MINIMAL_CONF["kiwi_profile"], ++ release="1.6", ++ repos=[self.repo], ++ type="t", ++ type_attr=["ta"], ++ result_bundle_name_format="fmt", ++ optional_arches=[], ++ version="v", ++ repo_releasever="r", ++ ) ++ ] ++ ++ assert get_image_paths.mock_calls == [mock.call(1234)] ++ assert os.path.isdir(self._img_path("x86_64", dir="iso")) ++ assert os.path.isdir(self._img_path("amd64", dir="iso")) ++ Linker.return_value.link.assert_has_calls( ++ [ ++ mock.call( ++ "/koji/task/1234/FCBG.amd64-Rawhide-1.6.iso", ++ self._img_path("amd64", img_name.format(arch="amd64"), dir="iso"), ++ link_type="hardlink-or-copy", ++ ), ++ mock.call( ++ "/koji/task/1234/FCBG.x86_64-Rawhide-1.6.iso", ++ self._img_path("x86_64", img_name.format(arch="x86_64"), dir="iso"), ++ link_type="hardlink-or-copy", ++ ), ++ ], ++ any_order=True, ++ ) ++ ++ assert len(compose.im.add.call_args_list) == 2 ++ for call in compose.im.add.call_args_list: ++ _, kwargs = call ++ image = kwargs["image"] ++ expected_path = "Server/{0.arch}/iso/{1}".format( ++ image, img_name.format(arch=image.arch) ++ ) ++ assert kwargs["variant"] == "Server" ++ assert kwargs["arch"] in ("amd64", "x86_64") ++ assert kwargs["arch"] == image.arch ++ assert image.path == expected_path ++ assert "iso" == image.format ++ assert "iso" == image.type ++ assert image.bootable ++ assert "Test" == image.subvariant + + def test_handle_koji_fail(self, KojiWrapper, get_file_size, get_mtime, Linker): + self.repo = self.topdir + "/compose/Server/$arch/os" + +From cd2ae81e3c63316997b9617ff2e30e3148af14f2 Mon Sep 17 00:00:00 2001 +From: Lubomír Sedlář +Date: Aug 29 2024 06:46:10 +0000 +Subject: [PATCH 2/2] kiwibuild: Allow setting metadata type explicitly + + +It is not possible to reliably detect what the type for an image should +be in the metadata. This commit adds an option for user to explicitly +provide it. + +It can only be configured on the specific image, not globally. + +Signed-off-by: Lubomír Sedlář + +--- + +diff --git a/doc/configuration.rst b/doc/configuration.rst +index c6f936a..ded479e 100644 +--- a/doc/configuration.rst ++++ b/doc/configuration.rst +@@ -1574,6 +1574,9 @@ KiwiBuild Settings + described in :ref:`automatic versioning `. + * ``repo_releasever`` -- (*str*) Override default releasever of the output + image. ++ * ``manifest_type`` -- the image type that is put into the manifest by ++ pungi. If not supplied, an autodetected value will be provided. It may or ++ may not make sense. + + The options can be set either for the specific image, or at the phase level + (see below). Version also falls back to ``global_version``. +diff --git a/pungi/checks.py b/pungi/checks.py +index bcf23e5..cc16d12 100644 +--- a/pungi/checks.py ++++ b/pungi/checks.py +@@ -1214,6 +1214,7 @@ def make_schema(): + "bundle_name_format": {"type": "string"}, + "version": {"type": "string"}, + "repo_releasever": {"type": "string"}, ++ "manifest_type": {"type": "string"}, + }, + "required": [ + # description_scm and description_path +diff --git a/pungi/phases/kiwibuild.py b/pungi/phases/kiwibuild.py +index 12ec26d..bb26812 100644 +--- a/pungi/phases/kiwibuild.py ++++ b/pungi/phases/kiwibuild.py +@@ -211,9 +211,9 @@ class RunKiwiBuildThread(WorkerThread): + # Update image manifest + img = Image(compose.im) + +- # Get the manifest type from the config if supplied, otherwise we +- # determine the manifest type based on the koji output +- img.type = type_ ++ # If user configured exact type, use it, otherwise try to ++ # figure it out based on the koji output. ++ img.type = config.get("manifest_type", type_) + img.format = format_ + img.path = os.path.join(rel_image_dir, filename) + img.mtime = util.get_mtime(image_dest) +diff --git a/tests/test_kiwibuildphase.py b/tests/test_kiwibuildphase.py +index 491dbf3..e3ccdb7 100644 +--- a/tests/test_kiwibuildphase.py ++++ b/tests/test_kiwibuildphase.py +@@ -73,6 +73,7 @@ class TestKiwiBuildPhase(PungiTestCase): + "bundle_name_format": "fmt", + "version": "Rawhide", + "repo_releasever": "41", ++ "manifest_type": "live-kiwi", + }, + MINIMAL_CONF, + ) +@@ -366,7 +367,9 @@ class TestKiwiBuildThread(PungiTestCase): + "kiwibuild_bundle_format": "%N-%P-40_Beta-%I.%A.%T", + }, + ) +- config = _merge({"subvariant": "Test"}, MINIMAL_CONF) ++ config = _merge( ++ {"subvariant": "Test", "manifest_type": "live-kiwi"}, MINIMAL_CONF ++ ) + pool = mock.Mock() + + get_image_paths = KojiWrapper.return_value.get_image_paths +@@ -459,7 +462,7 @@ class TestKiwiBuildThread(PungiTestCase): + assert kwargs["arch"] == image.arch + assert image.path == expected_path + assert "iso" == image.format +- assert "iso" == image.type ++ assert "live-kiwi" == image.type + assert image.bootable + assert "Test" == image.subvariant + +