Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ repos:
# Run the formatter.
- id: ruff-format
- repo: https://github.com/teemtee/tmt.git
rev: 1.39.0
rev: 1.60.0
hooks:
- id: tmt-lint
- repo: https://github.com/pre-commit/mirrors-mypy
Expand Down
4 changes: 4 additions & 0 deletions podman/domain/images_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ def build(self, **kwargs) -> tuple[Image, Iterator[bytes]]:
outputformat (str) - The format of the output image's manifest and configuration data.
manifest (str) - add the image to the specified manifest list.
Creates manifest list if it does not exist.
secrets (list[str]) - Secret files/envs to expose to the build

Returns:
first item is the podman.domain.images.Image built
Expand Down Expand Up @@ -209,6 +210,9 @@ def _render_params(kwargs) -> dict[str, list[Any]]:
if "labels" in kwargs:
params["labels"] = json.dumps(kwargs.get("labels"))

if "secrets" in kwargs:
params["secrets"] = json.dumps(kwargs.get("secrets"))

if params["dockerfile"] is None:
params["dockerfile"] = f".containerfile.{random.getrandbits(160):x}"

Expand Down
40 changes: 38 additions & 2 deletions podman/tests/integration/test_images.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,17 @@
"""Images integration tests."""

import io
import os
import platform
import tarfile
import tempfile
import types
import unittest

import podman.tests.integration.base as base
from podman import PodmanClient
from podman.domain.images import Image
from podman.errors import APIError, ImageNotFound, PodmanError

from podman.errors import APIError, ContainerError, ImageNotFound, PodmanError

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

Expand Down Expand Up @@ -197,6 +198,41 @@ def add_file(name: str, content: str):
self.assertIsNotNone(image)
self.assertIsNotNone(image.id)

def test_build_with_secret(self):
with tempfile.TemporaryDirectory() as context_dir:
dockerfile_path = os.path.join(context_dir, "Dockerfile")
with open(dockerfile_path, "w") as f:
f.write("""
FROM quay.io/libpod/alpine_labels:latest
RUN --mount=type=secret,id=example cat /run/secrets/example > /output.txt
""")

secret_path = os.path.join(context_dir, "build-secret.txt")
with open(secret_path, "w") as f:
f.write("secret123")

image, _ = self.client.images.build(
path=context_dir,
secrets=["id=example,src=build-secret.txt"],
dockerfile="Dockerfile",
)

self.assertIsNotNone(image)
self.assertIsNotNone(image.id)

# Verify secret was passed and stored in file (NOT RECOMMENDED for real use cases)
container_out = self.client.containers.run(
image.id, command=["cat", "/output.txt"], remove=True, log_config={"Type": "json-file"}
)
self.assertIn(b"secret123", container_out)

# Verify mounted secret file is not present in image
with self.assertRaises(ContainerError) as exc:
self.client.containers.run(
image.id, command=["cat", "/run/secrets/example"], remove=True
)
self.assertIn("No such file or directory", b"".join(exc.exception.stderr).decode("utf-8"))

@unittest.skipIf(platform.architecture()[0] == "32bit", "no 32-bit image available")
def test_pull_stream(self):
generator = self.client.images.pull("ubi8", tag="latest", stream=True)
Expand Down
4 changes: 3 additions & 1 deletion podman/tests/unit/test_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ def test_build(self, mock_prepare_containerfile, mock_create_tar):
"&cpuperiod=10"
"&extrahosts=%7B%22database%22%3A+%22127.0.0.1%22%7D"
"&labels=%7B%22Unittest%22%3A+%22true%22%7D"
"&manifest=example%3Av1.2.3",
"&manifest=example%3Av1.2.3"
"&secrets=%5B%22id%3Dexample%2Csrc%3Dpodman-build-secret123%22%5D",
text=buffer.getvalue(),
)
mock.get(
Expand Down Expand Up @@ -100,6 +101,7 @@ def test_build(self, mock_prepare_containerfile, mock_create_tar):
extra_hosts={"database": "127.0.0.1"},
labels={"Unittest": "true"},
manifest="example:v1.2.3",
secrets=["id=example,src=podman-build-secret123"],
)
self.assertIsInstance(image, Image)
self.assertEqual(image.id, "032b8b2855fc")
Expand Down