Pull the Docker image if not already available.
(self)
| 380 | return returncode |
| 381 | |
| 382 | def pull_image(self): |
| 383 | """Pull the Docker image if not already available.""" |
| 384 | print(f"Ensuring Docker image {self.docker_image} is available...") |
| 385 | try: |
| 386 | # Check if image exists locally |
| 387 | proc = RunningProcess( |
| 388 | ["docker", "images", "-q", self.docker_image], |
| 389 | env=get_docker_env(), |
| 390 | auto_run=True, |
| 391 | ) |
| 392 | stdout_lines: list[str] = [] |
| 393 | with proc.line_iter(timeout=None) as it: |
| 394 | for line in it: |
| 395 | stdout_lines.append(line) |
| 396 | result_stdout = "\n".join(stdout_lines) |
| 397 | if not result_stdout.strip(): |
| 398 | # Image doesn't exist, pull it directly using docker command |
| 399 | print(f"Pulling Docker image: {self.docker_image}") |
| 400 | run_docker_command_streaming(["docker", "pull", self.docker_image]) |
| 401 | print(f"Successfully pulled {self.docker_image}") |
| 402 | else: |
| 403 | print(f"Image {self.docker_image} already available locally") |
| 404 | except subprocess.CalledProcessError as e: |
| 405 | print(f"Warning: Failed to pull image {self.docker_image}: {e}") |
| 406 | if self.docker_image == DEFAULT_DOCKER_IMAGE: |
| 407 | print(f"Trying alternative image: {ALTERNATIVE_DOCKER_IMAGE}") |
| 408 | self.docker_image = ALTERNATIVE_DOCKER_IMAGE |
| 409 | try: |
| 410 | print(f"Pulling alternative Docker image: {self.docker_image}") |
| 411 | run_docker_command_streaming(["docker", "pull", self.docker_image]) |
| 412 | print(f"Successfully pulled {self.docker_image}") |
| 413 | except subprocess.CalledProcessError as e2: |
| 414 | print(f"Failed to pull alternative image: {e2}") |
| 415 | print(f"Trying fallback image: {FALLBACK_DOCKER_IMAGE}") |
| 416 | self.docker_image = FALLBACK_DOCKER_IMAGE |
| 417 | try: |
| 418 | print(f"Pulling fallback Docker image: {self.docker_image}") |
| 419 | run_docker_command_streaming( |
| 420 | ["docker", "pull", self.docker_image] |
| 421 | ) |
| 422 | print(f"Successfully pulled {self.docker_image}") |
| 423 | except subprocess.CalledProcessError as e3: |
| 424 | print(f"Failed to pull fallback image: {e3}") |
| 425 | raise e3 |
| 426 | else: |
| 427 | raise e |
| 428 | |
| 429 | def prepare_firmware(self, firmware_path: Path) -> Path: |
| 430 | """Prepare firmware files for mounting into Docker container. |