Skip to content

Commit fc5f459

Browse files
authored
Merge branch 'main' into ports_refactor
2 parents dec26d7 + e9e40f9 commit fc5f459

File tree

26 files changed

+655
-68
lines changed

26 files changed

+655
-68
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
".": "4.9.0"
2+
".": "4.10.0"
33
}

.github/CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ You need to have the following tools available to you:
3333
- Run `make install` to get `poetry` to install all dependencies and set up `pre-commit`
3434
- **Recommended**: Run `make` or `make help` to see other commands available to you.
3535
- After this, you should have a working virtual environment and proceed with writing code with your favourite IDE
36-
- **TIP**: You can run `make core/tests` or `make module/<my-module>/tests` to run the tests specifically for that to speed up feedback cycles
36+
- **TIP**: You can run `make core/tests` or `make modules/<my-module>/tests` to run the tests specifically for that to speed up feedback cycles
3737
- You can also run `make lint` to run the `pre-commit` for the entire codebase.
3838

3939

.github/workflows/ci-community.yml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,20 @@ jobs:
1919
- name: Checkout contents
2020
uses: actions/checkout@v4
2121
with:
22-
fetch-depth: 0 # recommended by tj-actions/changed-files
22+
fetch-depth: 0
2323
- name: Get changed files
2424
id: changed-files
25-
uses: tj-actions/changed-files@v42
25+
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3
2626
with:
27-
path: "./modules"
28-
diff_relative: true
29-
dir_names: true
30-
dir_names_exclude_current_dir: true
31-
json: true
27+
base: ${{ github.ref }}
28+
list-files: 'json'
29+
filters: |
30+
modules:
31+
- 'modules/**'
3232
- name: Compute modules from files
3333
id: compute-changes
3434
run: |
35-
modules=$(echo "${{ steps.changed-files.outputs.all_changed_files }}" | jq '.[] | split("/") | first' | jq -s -c '. | unique')
35+
modules=$(echo "${{ toJson(steps.changed-files.outputs.modules_files) }}" | jq '.[] | split("/") | nth(1)' | jq -s -c '. | unique')
3636
echo "computed_modules=$modules"
3737
echo "computed_modules=$modules" >> $GITHUB_OUTPUT
3838
outputs:

.readthedocs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@ build:
1414
# https://github.com/readthedocs/readthedocs.org/issues/4912#issuecomment-1143587902s
1515
jobs:
1616
post_install:
17-
- pip install poetry==1.7.1 # match version from poetry.lock
17+
- pip install poetry==2.1.2 # match version from poetry.lock
1818
- poetry config virtualenvs.create false
1919
- poetry install --all-extras

CHANGELOG.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,43 @@
11
# Changelog
22

3+
## [4.10.0](https://github.com/testcontainers/testcontainers-python/compare/testcontainers-v4.9.2...testcontainers-v4.10.0) (2025-04-02)
4+
5+
6+
### Features
7+
8+
* Add SocatContainer ([#795](https://github.com/testcontainers/testcontainers-python/issues/795)) ([2f9139c](https://github.com/testcontainers/testcontainers-python/commit/2f9139ca3ea9fba36325373b63635a5f539a3003))
9+
10+
11+
### Bug Fixes
12+
13+
* **ollama:** make device request a list ([#799](https://github.com/testcontainers/testcontainers-python/issues/799)) ([9497a45](https://github.com/testcontainers/testcontainers-python/commit/9497a45c39d13761aa3dd30dd5605676cbbe4b46))
14+
* **security:** Update track-modules job ([#787](https://github.com/testcontainers/testcontainers-python/issues/787)) ([f979525](https://github.com/testcontainers/testcontainers-python/commit/f97952505eba089f9cbbc979f8091dafbf520669))
15+
16+
## [4.9.2](https://github.com/testcontainers/testcontainers-python/compare/testcontainers-v4.9.1...testcontainers-v4.9.2) (2025-02-26)
17+
18+
19+
### Bug Fixes
20+
21+
* Change env var disabling OpenSearch security plugin ([#773](https://github.com/testcontainers/testcontainers-python/issues/773)) ([2620d7f](https://github.com/testcontainers/testcontainers-python/commit/2620d7fb1157caa18c3bef4bf2f9b3b79cd2f075))
22+
* **core:** create_label test ([#771](https://github.com/testcontainers/testcontainers-python/issues/771)) ([7517297](https://github.com/testcontainers/testcontainers-python/commit/751729722a013b46f67c09b4318b1b3d92b98008))
23+
* **core:** multiple container start invocations with custom labels ([#769](https://github.com/testcontainers/testcontainers-python/issues/769)) ([3e783a8](https://github.com/testcontainers/testcontainers-python/commit/3e783a80aa11b9c87201404a895d922624f0d451))
24+
* **keycloak:** Fixed Keycloak testcontainer for latest version v26.1.0 ([#766](https://github.com/testcontainers/testcontainers-python/issues/766)) ([b1642e9](https://github.com/testcontainers/testcontainers-python/commit/b1642e98c4d349564c4365782d1b58c9810b719a))
25+
* **scylla:** scylla get cluster method ([#778](https://github.com/testcontainers/testcontainers-python/issues/778)) ([46913c1](https://github.com/testcontainers/testcontainers-python/commit/46913c18a8b6f37bf8dc193828148926b6fc56a8))
26+
27+
28+
### Documentation
29+
30+
* Fixed typo in CONTRIBUTING.md ([#767](https://github.com/testcontainers/testcontainers-python/issues/767)) ([f0bb0f5](https://github.com/testcontainers/testcontainers-python/commit/f0bb0f54bea83885698bd137e24c397498709362))
31+
32+
## [4.9.1](https://github.com/testcontainers/testcontainers-python/compare/testcontainers-v4.9.0...testcontainers-v4.9.1) (2025-01-21)
33+
34+
35+
### Bug Fixes
36+
37+
* milvus healthcheck: use correct requests errors ([#759](https://github.com/testcontainers/testcontainers-python/issues/759)) ([78b137c](https://github.com/testcontainers/testcontainers-python/commit/78b137cfe53fc81eb8d5d858e98610fb6a8792ad))
38+
* **mysql:** add dialect parameter instead of hardcoded mysql dialect ([#739](https://github.com/testcontainers/testcontainers-python/issues/739)) ([8d77bd3](https://github.com/testcontainers/testcontainers-python/commit/8d77bd3541e1c5e73c7ed5d5bd3c0d7bb617f5c0))
39+
* **tests:** replace dind-test direct docker usage with sdk ([#750](https://github.com/testcontainers/testcontainers-python/issues/750)) ([ace2a7d](https://github.com/testcontainers/testcontainers-python/commit/ace2a7d143fb80576ddc0859a9106aa8652f2356))
40+
341
## [4.9.0](https://github.com/testcontainers/testcontainers-python/compare/testcontainers-v4.8.2...testcontainers-v4.9.0) (2024-11-26)
442

543

core/testcontainers/compose/compose.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ class DockerCompose:
139139
The list of services to use from this DockerCompose.
140140
client_args:
141141
arguments to pass to docker.from_env()
142+
docker_command_path:
143+
The docker compose command to run.
142144
143145
Example:
144146
@@ -195,7 +197,7 @@ def docker_compose_command(self) -> list[str]:
195197

196198
@cached_property
197199
def compose_command_property(self) -> list[str]:
198-
docker_compose_cmd = [self.docker_command_path or "docker", "compose"]
200+
docker_compose_cmd = [self.docker_command_path] if self.docker_command_path else ["docker", "compose"]
199201
if self.compose_file_name:
200202
for file in self.compose_file_name:
201203
docker_compose_cmd += ["-f", file]

core/testcontainers/core/config.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
from pathlib import Path
77
from typing import Optional, Union
88

9+
import docker
10+
911

1012
class ConnectionMode(Enum):
1113
bridge_ip = "bridge_ip"
@@ -24,14 +26,32 @@ def use_mapped_port(self) -> bool:
2426
return True
2527

2628

29+
def get_docker_socket() -> str:
30+
"""
31+
Determine the docker socket, prefer value given by env variable
32+
33+
Using the docker api ensure we handle rootless docker properly
34+
"""
35+
if socket_path := environ.get("TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE"):
36+
return socket_path
37+
38+
client = docker.from_env()
39+
try:
40+
socket_path = client.api.get_adapter(client.api.base_url).socket_path
41+
# return the normalized path as string
42+
return str(Path(socket_path).absolute())
43+
except AttributeError:
44+
return "/var/run/docker.sock"
45+
46+
2747
MAX_TRIES = int(environ.get("TC_MAX_TRIES", 120))
2848
SLEEP_TIME = int(environ.get("TC_POOLING_INTERVAL", 1))
2949
TIMEOUT = MAX_TRIES * SLEEP_TIME
3050

3151
RYUK_IMAGE: str = environ.get("RYUK_CONTAINER_IMAGE", "testcontainers/ryuk:0.8.1")
3252
RYUK_PRIVILEGED: bool = environ.get("TESTCONTAINERS_RYUK_PRIVILEGED", "false") == "true"
3353
RYUK_DISABLED: bool = environ.get("TESTCONTAINERS_RYUK_DISABLED", "false") == "true"
34-
RYUK_DOCKER_SOCKET: str = environ.get("TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE", "/var/run/docker.sock")
54+
RYUK_DOCKER_SOCKET: str = get_docker_socket()
3555
RYUK_RECONNECTION_TIMEOUT: str = environ.get("RYUK_RECONNECTION_TIMEOUT", "10s")
3656
TC_HOST_OVERRIDE: Optional[str] = environ.get("TC_HOST", environ.get("TESTCONTAINERS_HOST_OVERRIDE"))
3757

@@ -86,7 +106,7 @@ class TestcontainersConfiguration:
86106
tc_properties: dict[str, str] = field(default_factory=read_tc_properties)
87107
_docker_auth_config: Optional[str] = field(default_factory=lambda: environ.get("DOCKER_AUTH_CONFIG"))
88108
tc_host_override: Optional[str] = TC_HOST_OVERRIDE
89-
connection_mode_override: Optional[ConnectionMode] = None
109+
connection_mode_override: Optional[ConnectionMode] = field(default_factory=get_user_overwritten_connection_mode)
90110

91111
"""
92112
https://github.com/testcontainers/testcontainers-go/blob/dd76d1e39c654433a3d80429690d07abcec04424/docker.go#L644

core/testcontainers/core/container.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ def get_exposed_port(self, port: int) -> int:
182182
return self.get_docker_client().port(self._container.id, port)
183183
return port
184184

185-
def with_command(self, command: str) -> Self:
185+
def with_command(self, command: Union[str, list[str]]) -> Self:
186186
self._command = command
187187
return self
188188

core/testcontainers/core/image.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,13 @@ class DockerImage:
2323
>>> with DockerImage(path="./core/tests/image_fixtures/sample/", tag="test-image") as image:
2424
... logs = image.get_logs()
2525
26-
:param tag: Tag for the image to be built (default: None)
2726
:param path: Path to the build context
27+
:param docker_client_kw: Keyword arguments to pass to the DockerClient
28+
:param tag: Tag for the image to be built (default: None)
29+
:param clean_up: Remove the image after exiting the context (default: True)
2830
:param dockerfile_path: Path to the Dockerfile within the build context path (default: Dockerfile)
2931
:param no_cache: Bypass build cache; CLI's --no-cache
32+
:param kwargs: Additional keyword arguments to pass to the underlying docker-py
3033
"""
3134

3235
def __init__(
@@ -49,11 +52,11 @@ def __init__(
4952
self._dockerfile_path = dockerfile_path
5053
self._no_cache = no_cache
5154

52-
def build(self, **kwargs) -> Self:
55+
def build(self) -> Self:
5356
logger.info(f"Building image from {self.path}")
5457
docker_client = self.get_docker_client()
5558
self._image, self._logs = docker_client.build(
56-
path=str(self.path), tag=self.tag, dockerfile=self._dockerfile_path, nocache=self._no_cache, **kwargs
59+
path=str(self.path), tag=self.tag, dockerfile=self._dockerfile_path, nocache=self._no_cache, **self._kwargs
5760
)
5861
logger.info(f"Built image {self.short_id} with tag {self.tag}")
5962
return self

core/testcontainers/core/labels.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,15 @@ def create_labels(image: str, labels: Optional[dict[str, str]]) -> dict[str, str
2121
if k.startswith(TESTCONTAINERS_NAMESPACE):
2222
raise ValueError("The org.testcontainers namespace is reserved for internal use")
2323

24-
labels[LABEL_LANG] = "python"
25-
labels[LABEL_TESTCONTAINERS] = "true"
26-
labels[LABEL_VERSION] = importlib.metadata.version("testcontainers")
24+
tc_labels = {
25+
**labels,
26+
LABEL_LANG: "python",
27+
LABEL_TESTCONTAINERS: "true",
28+
LABEL_VERSION: importlib.metadata.version("testcontainers"),
29+
}
2730

2831
if image == c.ryuk_image:
29-
return labels
32+
return tc_labels
3033

31-
labels[LABEL_SESSION_ID] = SESSION_ID
32-
return labels
34+
tc_labels[LABEL_SESSION_ID] = SESSION_ID
35+
return tc_labels

0 commit comments

Comments
 (0)