diff --git a/core/testcontainers/core/config.py b/core/testcontainers/core/config.py index c9cd8c21..2643cf7f 100644 --- a/core/testcontainers/core/config.py +++ b/core/testcontainers/core/config.py @@ -110,11 +110,12 @@ def _render_bool(self, env_name: str, prop_name: str) -> bool: _docker_auth_config: Optional[str] = field(default_factory=lambda: environ.get("DOCKER_AUTH_CONFIG")) tc_host_override: Optional[str] = environ.get("TC_HOST", environ.get("TESTCONTAINERS_HOST_OVERRIDE")) connection_mode_override: Optional[ConnectionMode] = field(default_factory=get_user_overwritten_connection_mode) - """ https://github.com/testcontainers/testcontainers-go/blob/dd76d1e39c654433a3d80429690d07abcec04424/docker.go#L644 if os env TC_HOST is set, use it """ + hub_image_name_prefix: str = environ.get("TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX", "") + """ Prefix to use for hub image names, e.g. for private registries. """ @property def docker_auth_config(self) -> Optional[str]: diff --git a/core/testcontainers/core/container.py b/core/testcontainers/core/container.py index f7665c32..d2c6007e 100644 --- a/core/testcontainers/core/container.py +++ b/core/testcontainers/core/container.py @@ -3,7 +3,7 @@ import pathlib import sys import tarfile -from os import PathLike +from os import PathLike, getenv from socket import socket from types import TracebackType from typing import TYPE_CHECKING, Any, Optional, TypedDict, Union, cast @@ -89,8 +89,7 @@ def __init__( self.with_volume_mapping(*vol) self.tmpfs: dict[str, str] = {} - - self.image = image + self.image = c.hub_image_name_prefix + image self._docker = DockerClient(**(docker_client_kw or {})) self._container: Optional[Container] = None self._command: Optional[Union[str, list[str]]] = command diff --git a/core/tests/test_config.py b/core/tests/test_config.py index 43586031..90261f89 100644 --- a/core/tests/test_config.py +++ b/core/tests/test_config.py @@ -27,7 +27,14 @@ def test_read_tc_properties(monkeypatch: MonkeyPatch) -> None: config = TCC() assert config.tc_properties == {"tc.host": "some_value"} - +def test_hub_image_name_prefix(monkeypatch: MonkeyPatch) -> None: + """ + Ensure that the hub_image_name_prefix configuration variable can be read from the environment + """ + monkeypatch.setenv("TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX", "myregistry.local/") + config = TCC() + assert config.hub_image_name_prefix == "myregistry.local/" + def test_set_tc_properties(monkeypatch: MonkeyPatch) -> None: """ Ensure the configuration file variables can be read if no environment variable is set diff --git a/core/tests/test_container.py b/core/tests/test_container.py index 84949fef..aa2f66c9 100644 --- a/core/tests/test_container.py +++ b/core/tests/test_container.py @@ -5,6 +5,7 @@ from testcontainers.core.container import DockerContainer from testcontainers.core.docker_client import DockerClient from testcontainers.core.config import ConnectionMode +from testcontainers.core.config import testcontainers_config FAKE_ID = "ABC123" @@ -103,6 +104,28 @@ def test_attribute(init_attr, init_value, class_attr, stored_value): assert getattr(container, class_attr) == stored_value +def test_image_prefix_applied(monkeypatch: pytest.MonkeyPatch) -> None: + """Test that the hub_image_name_prefix is properly applied to the image name.""" + + # Set a prefix + test_prefix = "myregistry.example.com/" + monkeypatch.setattr(testcontainers_config, "hub_image_name_prefix", test_prefix) + + # Create a container and verify the prefix is applied + container = DockerContainer("nginx:latest") + assert container.image == "myregistry.example.com/nginx:latest" + + +def test_image_no_prefix_applied_when_empty(monkeypatch: pytest.MonkeyPatch) -> None: + """Test that when hub_image_name_prefix is empty, no prefix is applied.""" + # Set an empty prefix + monkeypatch.setattr(testcontainers_config, "hub_image_name_prefix", "") + + # Create a container and verify no prefix is applied + container = DockerContainer("nginx:latest") + assert container.image == "nginx:latest" + + def test_container_info(): """Test get_container_info functionality with a real container.""" with DockerContainer("alpine:latest").with_command("sleep 30") as container: