Skip to content

Commit c08ae6c

Browse files
committed
add copying files to/from container
Signed-off-by: mgorsk1 <[email protected]>
1 parent d5de0aa commit c08ae6c

File tree

1 file changed

+40
-1
lines changed

1 file changed

+40
-1
lines changed

core/testcontainers/core/container.py

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import contextlib
2+
import io
3+
import tarfile
4+
from pathlib import Path
25
from platform import system
36
from socket import socket
4-
from typing import TYPE_CHECKING, Optional
7+
from typing import TYPE_CHECKING, Optional, Tuple
58

69
import docker.errors
710
from docker import version
@@ -52,6 +55,7 @@ def __init__(
5255
self._network: Optional[Network] = None
5356
self._network_aliases: Optional[list[str]] = None
5457
self._kwargs = kwargs
58+
self._files: list[Tuple[Path, Path]] = []
5559

5660
def with_env(self, key: str, value: str) -> Self:
5761
self.env[key] = value
@@ -78,6 +82,33 @@ def with_kwargs(self, **kwargs) -> Self:
7882
self._kwargs = kwargs
7983
return self
8084

85+
def with_copy_file_to_container(self, source_file: Path, destination_file: Path) -> Self:
86+
self._files.append((source_file, destination_file))
87+
88+
return self
89+
90+
def copy_file_from_container(self, container_file: str, destination_file: str) -> str:
91+
tar_stream, _ = self._container.get_archive(container_file)
92+
93+
for chunk in tar_stream:
94+
with tarfile.open(fileobj=io.BytesIO(chunk)) as tar:
95+
for member in tar.getmembers():
96+
with open(destination_file, 'wb') as f:
97+
f.write(tar.extractfile(member).read())
98+
99+
return destination_file
100+
101+
@staticmethod
102+
def _put_file_in_container(container, source_file: Path, destination_file: str):
103+
data = io.BytesIO()
104+
105+
with tarfile.open(fileobj=data, mode='w') as tar:
106+
tar.add(source_file, arcname=destination_file)
107+
108+
data.seek(0)
109+
110+
container.put_archive("/", data)
111+
81112
def maybe_emulate_amd64(self) -> Self:
82113
if is_arm():
83114
return self.with_kwargs(platform="linux/amd64")
@@ -115,6 +146,14 @@ def start(self) -> Self:
115146
)
116147

117148
logger.info("Container started: %s", self._container.short_id)
149+
if self._network:
150+
self._network.connect(self._container.id, self._network_aliases)
151+
152+
for file in self._files:
153+
source, destination = file[0], file[1]
154+
155+
DockerContainer._put_file_in_container(self._container, source, destination)
156+
118157
return self
119158

120159
def stop(self, force=True, delete_volume=True) -> None:

0 commit comments

Comments
 (0)