|
1 | 1 | from __future__ import annotations
|
2 | 2 |
|
3 | 3 | import json
|
| 4 | +import platform |
4 | 5 | import re
|
5 | 6 | import subprocess
|
6 | 7 | import tarfile
|
@@ -289,15 +290,46 @@ def docker_pull_image(image_name: str, timeout: int) -> None:
|
289 | 290 |
|
290 | 291 | Timeout after `timeout` seconds.
|
291 | 292 | """
|
292 |
| - command = ["docker", "pull", image_name] |
| 293 | + # Base command for docker pull |
| 294 | + base_command = ["docker", "pull", image_name] |
| 295 | + |
| 296 | + # Try standard pull first |
| 297 | + if _run_docker_command(base_command, timeout): |
| 298 | + return |
| 299 | + |
| 300 | + # Apple Silicon: fall back to linux/amd64 if no success |
| 301 | + if platform.system() == "Darwin" and platform.machine() == "arm64": |
| 302 | + amd64_command = base_command + ["--platform=linux/amd64"] |
| 303 | + if _run_docker_command(amd64_command, timeout): |
| 304 | + return |
| 305 | + |
| 306 | + # Raise error if no success |
| 307 | + raise UsageError(f'Image "{image_name}" not found') |
| 308 | + |
| 309 | + |
| 310 | +def _run_docker_command(command: List[str], timeout: int) -> bool: |
| 311 | + """ |
| 312 | + Run a docker command with timeout and return success status |
| 313 | +
|
| 314 | + Args: |
| 315 | + command: Docker command to run as a list of strings |
| 316 | + timeout: Timeout in seconds |
| 317 | +
|
| 318 | + Returns: |
| 319 | + True if command succeeded, False if CalledProcessError |
| 320 | +
|
| 321 | + Raises: |
| 322 | + UnexpectedError: If command times out |
| 323 | + """ |
293 | 324 | try:
|
294 | 325 | subprocess.run(
|
295 | 326 | command,
|
296 | 327 | check=True,
|
297 | 328 | timeout=timeout,
|
298 | 329 | )
|
| 330 | + return True |
299 | 331 | except subprocess.CalledProcessError:
|
300 |
| - raise UsageError(f'Image "{image_name}" not found') |
| 332 | + return False |
301 | 333 | except subprocess.TimeoutExpired:
|
302 | 334 | raise UnexpectedError('Command "{}" timed out'.format(" ".join(command)))
|
303 | 335 |
|
@@ -325,7 +357,7 @@ def docker_save_to_tmp(image_name: str, destination_path: Path, timeout: int) ->
|
325 | 357 | except subprocess.CalledProcessError as exc:
|
326 | 358 | err_string = str(exc.stderr)
|
327 | 359 | if "No such image" in err_string or "reference does not exist" in err_string:
|
328 |
| - ui.display_info("need to download image first") |
| 360 | + ui.display_info("need to download image first") # ici |
329 | 361 | docker_pull_image(image_name, timeout)
|
330 | 362 |
|
331 | 363 | docker_save_to_tmp(image_name, destination_path, timeout)
|
|
0 commit comments