Skip to content

Commit e1e3d13

Browse files
authored
feat(compose): ability to retain volumes when using context manager (#659)
# changes On fiddling with a local project of mine, I realised we default to removing volumes when using compose. This is neat, but the context manager should also allow control over the volumes kept. This change adds the `keep_volumes` flag and hooks into `self.stop()` that already had the option. I added a test to cover the new functionality :
1 parent b1453e8 commit e1e3d13

File tree

3 files changed

+41
-1
lines changed

3 files changed

+41
-1
lines changed

core/testcontainers/compose/compose.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ class DockerCompose:
165165
pull: bool = False
166166
build: bool = False
167167
wait: bool = True
168+
keep_volumes: bool = False
168169
env_file: Optional[str] = None
169170
services: Optional[list[str]] = None
170171
docker_command_path: Optional[str] = None
@@ -178,7 +179,7 @@ def __enter__(self) -> "DockerCompose":
178179
return self
179180

180181
def __exit__(self, exc_type, exc_val, exc_tb) -> None:
181-
self.stop()
182+
self.stop(not self.keep_volumes)
182183

183184
def docker_compose_command(self) -> list[str]:
184185
"""
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
services:
2+
alpine:
3+
image: alpine:latest
4+
init: true
5+
command:
6+
- sh
7+
- -c
8+
- 'while true; do sleep 0.1 ; date -Ins; done'
9+
read_only: true
10+
volumes:
11+
- type: volume
12+
source: my-data
13+
target: /var/lib/example/data
14+
read_only: false
15+
16+
volumes:
17+
my-data: {}

core/tests/test_compose.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import subprocess
12
from pathlib import Path
23
from re import split
34
from time import sleep
@@ -147,6 +148,27 @@ def test_compose_logs():
147148
assert not line or container.Service in next(iter(line.split("|")), None)
148149

149150

151+
def test_compose_volumes():
152+
_file_in_volume = "/var/lib/example/data/hello"
153+
volumes = DockerCompose(context=FIXTURES / "basic_volume", keep_volumes=True)
154+
with volumes:
155+
stdout, stderr, exitcode = volumes.exec_in_container(
156+
["/bin/sh", "-c", f"echo hello > {_file_in_volume}"], "alpine"
157+
)
158+
assert exitcode == 0
159+
160+
# execute another time to confirm the file is still there, but we're not keeping the volumes this time
161+
volumes.keep_volumes = False
162+
with volumes:
163+
stdout, stderr, exitcode = volumes.exec_in_container(["cat", _file_in_volume], "alpine")
164+
assert exitcode == 0
165+
assert "hello" in stdout
166+
167+
# third time we expect the file to be missing
168+
with volumes, pytest.raises(subprocess.CalledProcessError):
169+
volumes.exec_in_container(["cat", _file_in_volume], "alpine")
170+
171+
150172
# noinspection HttpUrlsUsage
151173
def test_compose_ports():
152174
# fairly straight forward - can we get the right port to request it

0 commit comments

Comments
 (0)