From ca58d7cd58d22356b036aa4e17adbc154982d669 Mon Sep 17 00:00:00 2001 From: Sebastian Wick Date: Sun, 7 Jul 2024 19:00:57 +0200 Subject: [PATCH] Pass build description labels to podman build The Compose Specification supports adding labels to the build image which is also used in practice. Support this and pass the labels to `podman build`. Signed-off-by: Sebastian Wick --- podman_compose.py | 5 ++ tests/integration/build/README.md | 2 - .../build_labels/context/Dockerfile | 1 + .../build_labels/docker-compose.yml | 22 +++++++ .../build_labels/test_build_labels.py | 60 +++++++++++++++++++ 5 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 tests/integration/build_labels/context/Dockerfile create mode 100644 tests/integration/build_labels/docker-compose.yml create mode 100644 tests/integration/build_labels/test_build_labels.py diff --git a/podman_compose.py b/podman_compose.py index ec6471c..2272271 100755 --- a/podman_compose.py +++ b/podman_compose.py @@ -2378,6 +2378,11 @@ async def build_one(compose, args, cnt): build_args.extend(get_secret_args(compose, cnt, secret, podman_is_building=True)) for tag in build_desc.get("tags", []): build_args.extend(["-t", tag]) + labels = build_desc.get("labels", []) + if isinstance(labels, dict): + labels = [f"{k}={v}" for (k, v) in labels.items()] + for label in labels: + build_args.extend(["--label", label]) for additional_ctx in build_desc.get("additional_contexts", {}): build_args.extend([f"--build-context={additional_ctx}"]) if "target" in build_desc: diff --git a/tests/integration/build/README.md b/tests/integration/build/README.md index e67b421..b8b260a 100644 --- a/tests/integration/build/README.md +++ b/tests/integration/build/README.md @@ -21,5 +21,3 @@ ALT buildno=2 port 8000 2019-09-03T15:16:38+0000 as you can see we were able to override buildno to be 2 instead of 1, and httpd_port to 8000. - -NOTE: build labels are not passed to `podman build` diff --git a/tests/integration/build_labels/context/Dockerfile b/tests/integration/build_labels/context/Dockerfile new file mode 100644 index 0000000..24a79d0 --- /dev/null +++ b/tests/integration/build_labels/context/Dockerfile @@ -0,0 +1 @@ +FROM busybox diff --git a/tests/integration/build_labels/docker-compose.yml b/tests/integration/build_labels/docker-compose.yml new file mode 100644 index 0000000..a901d83 --- /dev/null +++ b/tests/integration/build_labels/docker-compose.yml @@ -0,0 +1,22 @@ +version: "3" +services: + test_build_labels_map: + build: + context: ./context + dockerfile: Dockerfile + labels: + com.example.description: "Accounting webapp" + com.example.department: "Finance" + com.example.label-with-empty-value: "" + image: my-busybox-build-labels-map + command: env + test_build_labels_array: + build: + context: ./context + dockerfile: Dockerfile + labels: + - "com.example.description=Accounting webapp" + - "com.example.department=Finance" + - "com.example.label-with-empty-value" + image: my-busybox-build-labels-array + command: env diff --git a/tests/integration/build_labels/test_build_labels.py b/tests/integration/build_labels/test_build_labels.py new file mode 100644 index 0000000..aaa37a5 --- /dev/null +++ b/tests/integration/build_labels/test_build_labels.py @@ -0,0 +1,60 @@ +# SPDX-License-Identifier: GPL-2.0 + + +import json +import os +import unittest + +from tests.integration.test_podman_compose import podman_compose_path +from tests.integration.test_podman_compose import test_path +from tests.integration.test_utils import RunSubprocessMixin + + +class TestBuildLabels(unittest.TestCase, RunSubprocessMixin): + def test_build_labels(self): + """The build context can contain labels which should be added to the resulting image. They + can be either an array or a map. + """ + + compose_path = os.path.join(test_path(), "build_labels/docker-compose.yml") + + try: + self.run_subprocess_assert_returncode([ + podman_compose_path(), + "-f", + compose_path, + "build", + "test_build_labels_map", + "test_build_labels_array", + ]) + + expected_labels = { + "com.example.department": "Finance", + "com.example.description": "Accounting webapp", + "com.example.label-with-empty-value": "", + } + + out, _ = self.run_subprocess_assert_returncode([ + "podman", + "inspect", + "my-busybox-build-labels-map", + "my-busybox-build-labels-array", + ]) + + images = json.loads(out) + self.assertEqual(len(images), 2) + labels_map = images[0].get("Config", {}).get("Labels", {}) + labels_array = images[1].get("Config", {}).get("Labels", {}) + for k, v in expected_labels.items(): + self.assertIn(k, labels_map) + self.assertEqual(labels_map[k], v) + self.assertIn(k, labels_array) + self.assertEqual(labels_array[k], v) + + finally: + self.run_subprocess_assert_returncode([ + "podman", + "rmi", + "my-busybox-build-labels-map", + "my-busybox-build-labels-array", + ])