diff --git a/localstack-core/localstack/utils/container_utils/container_client.py b/localstack-core/localstack/utils/container_utils/container_client.py index 075b339d95731..7e1b2b0c0cdc2 100644 --- a/localstack-core/localstack/utils/container_utils/container_client.py +++ b/localstack-core/localstack/utils/container_utils/container_client.py @@ -450,7 +450,7 @@ class ContainerConfiguration: volumes: VolumeMappings = dataclasses.field(default_factory=VolumeMappings) ports: PortMappings = dataclasses.field(default_factory=PortMappings) exposed_ports: List[str] = dataclasses.field(default_factory=list) - entrypoint: Optional[str] = None + entrypoint: Optional[Union[List[str], str]] = None additional_flags: Optional[str] = None command: Optional[List[str]] = None env_vars: Dict[str, str] = dataclasses.field(default_factory=dict) @@ -861,7 +861,7 @@ def create_container( image_name: str, *, name: Optional[str] = None, - entrypoint: Optional[str] = None, + entrypoint: Optional[Union[List[str], str]] = None, remove: bool = False, interactive: bool = False, tty: bool = False, diff --git a/localstack-core/localstack/utils/container_utils/docker_cmd_client.py b/localstack-core/localstack/utils/container_utils/docker_cmd_client.py index 440c8593c7f47..360e9bdbe3434 100644 --- a/localstack-core/localstack/utils/container_utils/docker_cmd_client.py +++ b/localstack-core/localstack/utils/container_utils/docker_cmd_client.py @@ -714,7 +714,7 @@ def _build_run_create_cmd( image_name: str, *, name: Optional[str] = None, - entrypoint: Optional[str] = None, + entrypoint: Optional[Union[List[str], str]] = None, remove: bool = False, interactive: bool = False, tty: bool = False, @@ -746,7 +746,10 @@ def _build_run_create_cmd( if name: cmd += ["--name", name] if entrypoint is not None: # empty string entrypoint can be intentional - cmd += ["--entrypoint", entrypoint] + if isinstance(entrypoint, str): + cmd += ["--entrypoint", entrypoint] + else: + cmd += ["--entrypoint", shlex.join(entrypoint)] if privileged: cmd += ["--privileged"] if volumes: diff --git a/localstack-core/localstack/utils/container_utils/docker_sdk_client.py b/localstack-core/localstack/utils/container_utils/docker_sdk_client.py index e38cb2e203117..29ecd0a4424ec 100644 --- a/localstack-core/localstack/utils/container_utils/docker_sdk_client.py +++ b/localstack-core/localstack/utils/container_utils/docker_sdk_client.py @@ -606,7 +606,7 @@ def create_container( image_name: str, *, name: Optional[str] = None, - entrypoint: Optional[str] = None, + entrypoint: Optional[Union[List[str], str]] = None, remove: bool = False, interactive: bool = False, tty: bool = False, diff --git a/tests/integration/docker_utils/test_docker.py b/tests/integration/docker_utils/test_docker.py index 001ca7595eb18..a2b785e881b5a 100644 --- a/tests/integration/docker_utils/test_docker.py +++ b/tests/integration/docker_utils/test_docker.py @@ -6,7 +6,7 @@ import re import textwrap import time -from typing import NamedTuple, Type +from typing import Callable, NamedTuple, Type import pytest from docker.models.containers import Container @@ -85,7 +85,7 @@ def create_container(docker_client: ContainerClient, create_network): """ containers = [] - def _create_container(image_name: str, **kwargs): + def _create_container(image_name: str, **kwargs) -> ContainerInfo: kwargs["name"] = kwargs.get("name", _random_container_name()) cid = docker_client.create_container(image_name, **kwargs) cid = cid.strip() @@ -187,6 +187,28 @@ def test_create_container_remove_removes_container( # it takes a while for it to be removed assert "foobar" in output + @pytest.mark.parametrize( + "entrypoint", + [ + "echo", + ["echo"], + ], + ) + def test_set_container_entrypoint( + self, + docker_client: ContainerClient, + create_container: Callable[..., ContainerInfo], + entrypoint: list[str] | str, + ): + info = create_container("alpine", entrypoint=entrypoint, command=["true"]) + assert 1 == len(docker_client.list_containers(f"id={info.container_id}")) + + # start the container + output, _ = docker_client.start_container(info.container_id, attach=True) + output = to_str(output).strip() + + assert output == "true" + @markers.skip_offline def test_create_container_non_existing_image(self, docker_client: ContainerClient): with pytest.raises(NoSuchImage):