Fix using git URL as build context

Podman-compose actually did not work with git URL as build context.

Signed-off-by: Monika Kairaityte <monika@kibit.lt>
This commit is contained in:
Monika Kairaityte 2025-03-25 19:46:59 +02:00
parent 5f4fc4618c
commit 92f0a8583a
3 changed files with 46 additions and 7 deletions

View File

@ -0,0 +1 @@
- Fix using git URL as build context

View File

@ -26,6 +26,7 @@ import signal
import subprocess import subprocess
import sys import sys
import tempfile import tempfile
import urllib.parse
from asyncio import Task from asyncio import Task
from enum import Enum from enum import Enum
@ -1663,6 +1664,8 @@ def normalize_service_final(service: dict, project_dir: str) -> dict:
if "build" in service: if "build" in service:
build = service["build"] build = service["build"]
context = build if isinstance(build, str) else build.get("context", ".") context = build if isinstance(build, str) else build.get("context", ".")
if not is_path_git_url(context):
context = os.path.normpath(os.path.join(project_dir, context)) context = os.path.normpath(os.path.join(project_dir, context))
if not isinstance(service["build"], dict): if not isinstance(service["build"], dict):
service["build"] = {} service["build"] = {}
@ -2501,12 +2504,17 @@ async def compose_push(compose, args):
await compose.podman.run([], "push", [cnt["image"]]) await compose.podman.run([], "push", [cnt["image"]])
def is_path_git_url(path):
r = urllib.parse.urlparse(path)
return r.scheme == 'git' or r.path.endswith('.git')
def container_to_build_args(compose, cnt, args, path_exists, cleanup_callbacks=None): 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", "")
dockerfile_inline = build_desc.get("dockerfile_inline") dockerfile_inline = build_desc.get("dockerfile_inline")
if dockerfile_inline is not None: if dockerfile_inline is not None:
dockerfile_inline = str(dockerfile_inline) dockerfile_inline = str(dockerfile_inline)
@ -2524,7 +2532,10 @@ def container_to_build_args(compose, cnt, args, path_exists, cleanup_callbacks=N
if cleanup_callbacks is not None: if cleanup_callbacks is not None:
list.append(cleanup_callbacks, cleanup_temp_dockfile) list.append(cleanup_callbacks, cleanup_temp_dockfile)
else:
build_args = []
if not is_path_git_url(ctx):
if dockerfile: if dockerfile:
dockerfile = os.path.join(ctx, dockerfile) dockerfile = os.path.join(ctx, dockerfile)
else: else:
@ -2540,11 +2551,16 @@ def container_to_build_args(compose, cnt, args, path_exists, cleanup_callbacks=N
dockerfile = os.path.join(ctx, dockerfile) dockerfile = os.path.join(ctx, dockerfile)
if path_exists(dockerfile): if path_exists(dockerfile):
break break
if not path_exists(dockerfile):
raise OSError("Dockerfile not found in " + ctx)
if path_exists(dockerfile):
# normalize dockerfile path, as the user could have provided unpredictable file formats
dockerfile = os.path.normpath(os.path.join(ctx, dockerfile)) dockerfile = os.path.normpath(os.path.join(ctx, dockerfile))
build_args = ["-f", dockerfile, "-t", cnt["image"]] build_args.extend(["-f", dockerfile])
else:
raise OSError(f"Dockerfile not found in {ctx}")
build_args.extend(["-t", cnt["image"]])
if "platform" in cnt: if "platform" in cnt:
build_args.extend(["--platform", cnt["platform"]]) build_args.extend(["--platform", cnt["platform"]])
for secret in build_desc.get("secrets", []): for secret in build_desc.get("secrets", []):

View File

@ -0,0 +1,22 @@
# SPDX-License-Identifier: GPL-2.0
import unittest
from parameterized import parameterized
from podman_compose import is_path_git_url
class TestIsPathGitUrl(unittest.TestCase):
@parameterized.expand([
("prefix_git", "git://host.xz/path/to/repo", True),
("prefix_almost_git", "gitt://host.xz/path/to/repo", False),
("prefix_wrong", "http://host.xz/path/to/repo", False),
("suffix_git", "http://host.xz/path/to/repo.git", True),
("suffix_wrong", "http://host.xz/path/to/repo", False),
("suffix_with_url_fragment", "http://host.xz/path/to/repo.git#fragment", True),
("suffix_and_prefix", "git://host.xz/path/to/repo.git", True),
("empty_url_path", "http://#fragment", False),
])
def test_is_path_git_url(self, test_name, path, result):
self.assertEqual(is_path_git_url(path), result)