|
5 | 5 | import os
|
6 | 6 | import platform
|
7 | 7 | import shlex
|
| 8 | +import shutil |
8 | 9 | import subprocess
|
9 | 10 | import sys
|
10 | 11 | import typing
|
@@ -169,6 +170,9 @@ def __init__(
|
169 | 170 | self.cwd = cwd
|
170 | 171 | self.name: str | None = None
|
171 | 172 | self.engine = engine
|
| 173 | + self.host_tar_format = "" |
| 174 | + if sys.platform.startswith("darwin"): |
| 175 | + self.host_tar_format = "--format gnutar" |
172 | 176 |
|
173 | 177 | def _get_platform_args(self, *, oci_platform: OCIPlatform | None = None) -> tuple[str, str]:
|
174 | 178 | if oci_platform is None:
|
@@ -311,10 +315,38 @@ def __exit__(
|
311 | 315 | def copy_into(self, from_path: Path, to_path: PurePath) -> None:
|
312 | 316 | if from_path.is_dir():
|
313 | 317 | self.call(["mkdir", "-p", to_path])
|
314 |
| - call(self.engine.name, "cp", f"{from_path}/.", f"{self.name}:{to_path}") |
| 318 | + subprocess.run( |
| 319 | + f"tar -c {self.host_tar_format} -f - . | {self.engine.name} exec -i {self.name} tar --no-same-owner -xC {shell_quote(to_path)} -f -", |
| 320 | + shell=True, |
| 321 | + check=True, |
| 322 | + cwd=from_path, |
| 323 | + ) |
315 | 324 | else:
|
316 |
| - self.call(["mkdir", "-p", to_path.parent]) |
317 |
| - call(self.engine.name, "cp", from_path, f"{self.name}:{to_path}") |
| 325 | + exec_process: subprocess.Popen[bytes] |
| 326 | + with subprocess.Popen( |
| 327 | + [ |
| 328 | + self.engine.name, |
| 329 | + "exec", |
| 330 | + "-i", |
| 331 | + str(self.name), |
| 332 | + "sh", |
| 333 | + "-c", |
| 334 | + f"cat > {shell_quote(to_path)}", |
| 335 | + ], |
| 336 | + stdin=subprocess.PIPE, |
| 337 | + ) as exec_process: |
| 338 | + assert exec_process.stdin |
| 339 | + with open(from_path, "rb") as from_file: |
| 340 | + # Bug in mypy, https://github.com/python/mypy/issues/15031 |
| 341 | + shutil.copyfileobj(from_file, exec_process.stdin) # type: ignore[misc] |
| 342 | + |
| 343 | + exec_process.stdin.close() |
| 344 | + exec_process.wait() |
| 345 | + |
| 346 | + if exec_process.returncode: |
| 347 | + raise subprocess.CalledProcessError( |
| 348 | + exec_process.returncode, exec_process.args, None, None |
| 349 | + ) |
318 | 350 |
|
319 | 351 | def copy_out(self, from_path: PurePath, to_path: Path) -> None:
|
320 | 352 | # note: we assume from_path is a dir
|
|
0 commit comments