Skip to content

Commit 108d9f3

Browse files
Merge pull request #552 from aseering/main
Add support for custom contexts
2 parents 9f56d1c + b536f24 commit 108d9f3

File tree

2 files changed

+53
-3
lines changed

2 files changed

+53
-3
lines changed

podman/domain/images_build.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def build(self, **kwargs) -> tuple[Image, Iterator[bytes]]:
3434
nocache (bool) – Don’t use the cache when set to True
3535
rm (bool) – Remove intermediate containers. Default True
3636
timeout (int) – HTTP timeout
37-
custom_context (bool) – Optional if using fileobj (ignored)
37+
custom_context (bool) – Optional if using fileobj
3838
encoding (str) – The encoding for a stream. Set to gzip for compressing (ignored)
3939
pull (bool) – Downloads any updates to the FROM image in Dockerfile
4040
forcerm (bool) – Always remove intermediate containers, even after unsuccessful builds
@@ -82,7 +82,21 @@ def build(self, **kwargs) -> tuple[Image, Iterator[bytes]]:
8282

8383
body = None
8484
path = None
85-
if "fileobj" in kwargs:
85+
if kwargs.get("custom_context"):
86+
if "fileobj" not in kwargs:
87+
raise PodmanError(
88+
"Custom context requires fileobj to be set to a binary file-like object containing a build-directory tarball."
89+
)
90+
if "dockerfile" not in kwargs:
91+
# TODO: Scan the tarball for either a Dockerfile or a Containerfile.
92+
# This could be slow if the tarball is large,
93+
# and could require buffering/copying the tarball if `fileobj` is not seekable.
94+
# As a workaround for now, don't support omitting the filename.
95+
raise PodmanError(
96+
"Custom context requires specifying the name of the Dockerfile (typically 'Dockerfile' or 'Containerfile')."
97+
)
98+
body = kwargs["fileobj"]
99+
elif "fileobj" in kwargs:
86100
path = tempfile.TemporaryDirectory() # pylint: disable=consider-using-with
87101
filename = pathlib.Path(path.name) / params["dockerfile"]
88102

podman/tests/integration/test_images.py

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
import podman.tests.integration.base as base
2424
from podman import PodmanClient
2525
from podman.domain.images import Image
26-
from podman.errors import APIError, ImageNotFound
26+
from podman.errors import APIError, ImageNotFound, PodmanError
2727

2828

2929
# @unittest.skipIf(os.geteuid() != 0, 'Skipping, not running as root')
@@ -144,6 +144,42 @@ def test_build(self):
144144
self.assertIsNotNone(image)
145145
self.assertIsNotNone(image.id)
146146

147+
def test_build_with_context(self):
148+
context = io.BytesIO()
149+
with tarfile.open(fileobj=context, mode="w") as tar:
150+
151+
def add_file(name: str, content: str):
152+
binary_content = content.encode("utf-8")
153+
fileobj = io.BytesIO(binary_content)
154+
tarinfo = tarfile.TarInfo(name=name)
155+
tarinfo.size = len(binary_content)
156+
tar.addfile(tarinfo, fileobj)
157+
158+
# Use a non-standard Dockerfile name to test the 'dockerfile' argument
159+
add_file(
160+
"MyDockerfile", ("FROM quay.io/libpod/alpine_labels:latest\nCOPY example.txt .\n")
161+
)
162+
add_file("example.txt", "This is an example file.\n")
163+
164+
# Rewind to the start of the generated file so we can read it
165+
context.seek(0)
166+
167+
with self.assertRaises(PodmanError) as e:
168+
# If requesting a custom context, must provide the context as `fileobj`
169+
self.client.images.build(custom_context=True, path='invalid')
170+
171+
with self.assertRaises(PodmanError) as e:
172+
# If requesting a custom context, currently must specify the dockerfile name
173+
self.client.images.build(custom_context=True, fileobj=context)
174+
175+
image, stream = self.client.images.build(
176+
fileobj=context,
177+
dockerfile="MyDockerfile",
178+
custom_context=True,
179+
)
180+
self.assertIsNotNone(image)
181+
self.assertIsNotNone(image.id)
182+
147183
@unittest.skipIf(platform.architecture()[0] == "32bit", "no 32-bit image available")
148184
def test_pull_stream(self):
149185
generator = self.client.images.pull("ubi8", tag="latest", stream=True)

0 commit comments

Comments
 (0)