Merge pull request #1116 from Zeglius/dockerfile_inline

Add support for dockerfile_inline
This commit is contained in:
Povilas Kanapickas 2025-01-27 21:52:05 +02:00 committed by GitHub
commit 9c905f9012
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 72 additions and 15 deletions

View File

@ -0,0 +1,9 @@
---
version: '3'
services:
dummy:
build:
context: .
dockerfile_inline: |
FROM alpine
RUN echo "hello world"

View File

@ -25,6 +25,7 @@ import shlex
import signal import signal
import subprocess import subprocess
import sys import sys
import tempfile
from asyncio import Task from asyncio import Task
from enum import Enum from enum import Enum
@ -2471,27 +2472,45 @@ async def compose_push(compose, args):
await compose.podman.run([], "push", [cnt["image"]]) await compose.podman.run([], "push", [cnt["image"]])
def container_to_build_args(compose, cnt, args, path_exists): def container_to_build_args(compose, cnt, args, path_exists, cleanup_callbacks=None):
build_desc = cnt["build"] build_desc = cnt["build"]
if not hasattr(build_desc, "items"): if not hasattr(build_desc, "items"):
build_desc = {"context": build_desc} build_desc = {"context": build_desc}
ctx = build_desc.get("context", ".") ctx = build_desc.get("context", ".")
dockerfile = build_desc.get("dockerfile") dockerfile = build_desc.get("dockerfile")
if dockerfile: dockerfile_inline = build_desc.get("dockerfile_inline")
dockerfile = os.path.join(ctx, dockerfile) if dockerfile_inline is not None:
dockerfile_inline = str(dockerfile_inline)
# Error if both `dockerfile_inline` and `dockerfile` are set
if dockerfile and dockerfile_inline:
raise OSError("dockerfile_inline and dockerfile can't be used simultaneously")
dockerfile = tempfile.NamedTemporaryFile(delete=False, suffix=".containerfile")
dockerfile.write(dockerfile_inline.encode())
dockerfile.close()
dockerfile = dockerfile.name
def cleanup_temp_dockfile():
if os.path.exists(dockerfile):
os.remove(dockerfile)
if cleanup_callbacks is not None:
list.append(cleanup_callbacks, cleanup_temp_dockfile)
else: else:
dockerfile_alts = [ if dockerfile:
"Containerfile",
"ContainerFile",
"containerfile",
"Dockerfile",
"DockerFile",
"dockerfile",
]
for dockerfile in dockerfile_alts:
dockerfile = os.path.join(ctx, dockerfile) dockerfile = os.path.join(ctx, dockerfile)
if path_exists(dockerfile): else:
break dockerfile_alts = [
"Containerfile",
"ContainerFile",
"containerfile",
"Dockerfile",
"DockerFile",
"dockerfile",
]
for dockerfile in dockerfile_alts:
dockerfile = os.path.join(ctx, dockerfile)
if path_exists(dockerfile):
break
if not path_exists(dockerfile): if not path_exists(dockerfile):
raise OSError("Dockerfile not found in " + ctx) raise OSError("Dockerfile not found in " + ctx)
build_args = ["-f", dockerfile, "-t", cnt["image"]] build_args = ["-f", dockerfile, "-t", cnt["image"]]
@ -2546,8 +2565,13 @@ async def build_one(compose, args, cnt):
if img_id: if img_id:
return None return None
build_args = container_to_build_args(compose, cnt, args, os.path.exists) cleanup_callbacks = []
build_args = container_to_build_args(
compose, cnt, args, os.path.exists, cleanup_callbacks=cleanup_callbacks
)
status = await compose.podman.run([], "build", build_args) status = await compose.podman.run([], "build", build_args)
for c in cleanup_callbacks:
c()
return status return status

View File

@ -1,5 +1,6 @@
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
import os
import unittest import unittest
from unittest import mock from unittest import mock
@ -156,3 +157,26 @@ class TestContainerToBuildArgs(unittest.TestCase):
'.', '.',
], ],
) )
def test_dockerfile_inline(self):
c = create_compose_mock()
cnt = get_minimal_container()
cnt['build']['dockerfile_inline'] = "FROM busybox\nRUN echo 'hello world'"
args = get_minimal_args()
cleanup_callbacks = []
args = container_to_build_args(
c, cnt, args, lambda path: True, cleanup_callbacks=cleanup_callbacks
)
temp_dockerfile = args[args.index("-f") + 1]
self.assertTrue(os.path.exists(temp_dockerfile))
with open(temp_dockerfile, "rt") as file:
contents = file.read()
self.assertEqual(contents, "FROM busybox\n" + "RUN echo 'hello world'")
for c in cleanup_callbacks:
c()
self.assertFalse(os.path.exists(temp_dockerfile))