Skip to content

Commit 53ab83f

Browse files
Merge pull request containers#603 from gsilva00/feat/build-support-secrets
Add support to `--secrets` when building container images
2 parents 35fd182 + 65d38d8 commit 53ab83f

File tree

3 files changed

+45
-3
lines changed

3 files changed

+45
-3
lines changed

podman/domain/images_build.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ def build(self, **kwargs) -> tuple[Image, Iterator[bytes]]:
6868
outputformat (str) - The format of the output image's manifest and configuration data.
6969
manifest (str) - add the image to the specified manifest list.
7070
Creates manifest list if it does not exist.
71+
secrets (list[str]) - Secret files/envs to expose to the build
7172
7273
Returns:
7374
first item is the podman.domain.images.Image built
@@ -209,6 +210,9 @@ def _render_params(kwargs) -> dict[str, list[Any]]:
209210
if "labels" in kwargs:
210211
params["labels"] = json.dumps(kwargs.get("labels"))
211212

213+
if "secrets" in kwargs:
214+
params["secrets"] = json.dumps(kwargs.get("secrets"))
215+
212216
if params["dockerfile"] is None:
213217
params["dockerfile"] = f".containerfile.{random.getrandbits(160):x}"
214218

podman/tests/integration/test_images.py

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,17 @@
1515
"""Images integration tests."""
1616

1717
import io
18+
import os
1819
import platform
1920
import tarfile
21+
import tempfile
2022
import types
2123
import unittest
2224

2325
import podman.tests.integration.base as base
2426
from podman import PodmanClient
2527
from podman.domain.images import Image
26-
from podman.errors import APIError, ImageNotFound, PodmanError
27-
28+
from podman.errors import APIError, ContainerError, ImageNotFound, PodmanError
2829

2930
# @unittest.skipIf(os.geteuid() != 0, 'Skipping, not running as root')
3031

@@ -197,6 +198,41 @@ def add_file(name: str, content: str):
197198
self.assertIsNotNone(image)
198199
self.assertIsNotNone(image.id)
199200

201+
def test_build_with_secret(self):
202+
with tempfile.TemporaryDirectory() as context_dir:
203+
dockerfile_path = os.path.join(context_dir, "Dockerfile")
204+
with open(dockerfile_path, "w") as f:
205+
f.write("""
206+
FROM quay.io/libpod/alpine_labels:latest
207+
RUN --mount=type=secret,id=example cat /run/secrets/example > /output.txt
208+
""")
209+
210+
secret_path = os.path.join(context_dir, "build-secret.txt")
211+
with open(secret_path, "w") as f:
212+
f.write("secret123")
213+
214+
image, _ = self.client.images.build(
215+
path=context_dir,
216+
secrets=["id=example,src=build-secret.txt"],
217+
dockerfile="Dockerfile",
218+
)
219+
220+
self.assertIsNotNone(image)
221+
self.assertIsNotNone(image.id)
222+
223+
# Verify secret was passed and stored in file (NOT RECOMMENDED for real use cases)
224+
container_out = self.client.containers.run(
225+
image.id, command=["cat", "/output.txt"], remove=True, log_config={"Type": "json-file"}
226+
)
227+
self.assertIn(b"secret123", container_out)
228+
229+
# Verify mounted secret file is not present in image
230+
with self.assertRaises(ContainerError) as exc:
231+
self.client.containers.run(
232+
image.id, command=["cat", "/run/secrets/example"], remove=True
233+
)
234+
self.assertIn("No such file or directory", b"".join(exc.exception.stderr).decode("utf-8"))
235+
200236
@unittest.skipIf(platform.architecture()[0] == "32bit", "no 32-bit image available")
201237
def test_pull_stream(self):
202238
generator = self.client.images.pull("ubi8", tag="latest", stream=True)

podman/tests/unit/test_build.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ def test_build(self, mock_prepare_containerfile, mock_create_tar):
6767
"&cpuperiod=10"
6868
"&extrahosts=%7B%22database%22%3A+%22127.0.0.1%22%7D"
6969
"&labels=%7B%22Unittest%22%3A+%22true%22%7D"
70-
"&manifest=example%3Av1.2.3",
70+
"&manifest=example%3Av1.2.3"
71+
"&secrets=%5B%22id%3Dexample%2Csrc%3Dpodman-build-secret123%22%5D",
7172
text=buffer.getvalue(),
7273
)
7374
mock.get(
@@ -100,6 +101,7 @@ def test_build(self, mock_prepare_containerfile, mock_create_tar):
100101
extra_hosts={"database": "127.0.0.1"},
101102
labels={"Unittest": "true"},
102103
manifest="example:v1.2.3",
104+
secrets=["id=example,src=podman-build-secret123"],
103105
)
104106
self.assertIsInstance(image, Image)
105107
self.assertEqual(image.id, "032b8b2855fc")

0 commit comments

Comments
 (0)