diff --git a/doc/configuration.rst b/doc/configuration.rst index 54708c80..fba4ab2e 100644 --- a/doc/configuration.rst +++ b/doc/configuration.rst @@ -1690,6 +1690,10 @@ OSBuild Composer for building images * ``ostree_ref`` -- name of the ostree branch * ``ostree_parent`` -- commit hash or a a branch-like reference to the parent commit. + * ``customizations`` -- a dictionary with customizations to use for the + image build. For the list of supported customizations, see the **hosted** + variants in the `Image Builder documentation + `. * ``upload_options`` -- a dictionary with upload options specific to the target cloud environment. If provided, the image will be uploaded to the cloud environment, in addition to the Koji server. One can't combine diff --git a/pungi/checks.py b/pungi/checks.py index e1c4f1b7..bdbcfbaf 100644 --- a/pungi/checks.py +++ b/pungi/checks.py @@ -1325,6 +1325,10 @@ def make_schema(): "ostree_ref": {"type": "string"}, "ostree_parent": {"type": "string"}, "manifest_type": {"type": "string"}, + "customizations": { + "type": "object", + "additionalProperties": True, + }, "upload_options": { # this should be really 'oneOf', but the minimal # required properties in AWSEC2 and GCP options diff --git a/pungi/phases/osbuild.py b/pungi/phases/osbuild.py index 34be17c8..35d3318f 100644 --- a/pungi/phases/osbuild.py +++ b/pungi/phases/osbuild.py @@ -159,6 +159,10 @@ class RunOSBuildThread(WorkerThread): if upload_options: opts["upload_options"] = upload_options + customizations = config.get("customizations") + if customizations: + opts["customizations"] = customizations + if release: opts["release"] = release task_id = koji.koji_proxy.osbuildImage( diff --git a/tests/test_osbuild_phase.py b/tests/test_osbuild_phase.py index 31ee6361..fdab383a 100644 --- a/tests/test_osbuild_phase.py +++ b/tests/test_osbuild_phase.py @@ -186,6 +186,51 @@ class OSBuildPhaseTest(helpers.PungiTestCase): ) self.assertNotEqual(validate(compose.conf), ([], [])) + @mock.patch("pungi.phases.osbuild.ThreadPool") + def test_run_with_customizations(self, ThreadPool): + cfg = { + "name": "test-image", + "distro": "rhel-8", + "image_types": ["qcow2"], + "customizations": {"installation_device": "/dev/sda"}, + } + compose = helpers.DummyCompose( + self.topdir, + { + "osbuild": {"^Everything$": [cfg]}, + "osbuild_target": "image-target", + "osbuild_version": "1", + "osbuild_release": "2", + }, + ) + + self.assertValidConfig(compose.conf) + + pool = ThreadPool.return_value + + phase = osbuild.OSBuildPhase(compose) + phase.run() + + self.assertEqual(len(pool.add.call_args_list), 1) + self.assertEqual( + pool.queue_put.call_args_list, + [ + mock.call( + ( + compose, + compose.variants["Everything"], + cfg, + sorted(compose.variants["Everything"].arches), + "1", + "2", + "image-target", + [self.topdir + "/compose/Everything/$arch/os"], + [], + ), + ), + ], + ) + @mock.patch("pungi.phases.osbuild.ThreadPool") def test_rich_repos(self, ThreadPool): repo = {"baseurl": "http://example.com/repo", "package_sets": ["build"]}