|
14 | 14 | import os |
15 | 15 | import re |
16 | 16 | import subprocess |
17 | | -import sys |
18 | 17 | from dataclasses import dataclass, field |
19 | 18 | from pathlib import Path |
20 | 19 | from uuid import uuid4 |
21 | 20 |
|
| 21 | +from rich.console import Console |
| 22 | + |
22 | 23 | from lightcone.engine.container import ( |
23 | 24 | _DAEMONLESS_RUNTIMES, |
24 | 25 | ContainerBuildError, |
|
36 | 37 | # Registry where pre-built release images are published. |
37 | 38 | _GHCR_PREFIX = "ghcr.io/lightconeresearch" |
38 | 39 |
|
| 40 | +_console = Console(stderr=True) |
| 41 | + |
39 | 42 | # Local image name for the shared sandbox base image. |
40 | 43 | _SANDBOX_IMAGE_NAME = "lightcone-sandbox" |
41 | 44 |
|
@@ -394,16 +397,16 @@ def _try_pull_and_cache( |
394 | 397 | if runtime in _DAEMONLESS_RUNTIMES: |
395 | 398 | return False |
396 | 399 | try: |
397 | | - _print(f"Pulling {registry_ref} from registry…") |
398 | | - pull_image(registry_ref, runtime=runtime) |
399 | | - # Retag to the content-addressed local tag so the rest of the launch |
400 | | - # pipeline (image_exists_locally, _exec_interactive) works unchanged. |
401 | | - subprocess.run( |
402 | | - [runtime, "tag", registry_ref, tag], |
403 | | - check=True, |
404 | | - capture_output=True, |
405 | | - ) |
406 | | - save_image_as_tarball(tag, tarball, runtime=runtime) |
| 400 | + with _console.status(f"Pulling [bold]{registry_ref}[/] from registry…"): |
| 401 | + pull_image(registry_ref, runtime=runtime) |
| 402 | + # Retag to the content-addressed local tag so the rest of the launch |
| 403 | + # pipeline (image_exists_locally, _exec_interactive) works unchanged. |
| 404 | + subprocess.run( |
| 405 | + [runtime, "tag", registry_ref, tag], |
| 406 | + check=True, |
| 407 | + capture_output=True, |
| 408 | + ) |
| 409 | + save_image_as_tarball(tag, tarball, runtime=runtime) |
407 | 410 | return True |
408 | 411 | except (ContainerBuildError, subprocess.CalledProcessError, OSError): |
409 | 412 | _print("Registry pull failed — falling back to local build.") |
@@ -449,18 +452,23 @@ def _ensure_harness_image( |
449 | 452 |
|
450 | 453 | tmp_name = f"lc-install-{target.name}-{uuid4().hex[:8]}" |
451 | 454 | install_cmd = " && ".join(target.install_cmds) |
452 | | - _print(f"Installing {target.name} harness (first run — this may take a few minutes)…") |
453 | 455 | try: |
454 | | - subprocess.run( |
455 | | - [runtime, "run", "--entrypoint", "sh", "--name", tmp_name, |
456 | | - base_image, "-c", install_cmd], |
457 | | - check=True, |
458 | | - ) |
459 | | - subprocess.run( |
460 | | - [runtime, "commit", tmp_name, committed_tag], |
461 | | - check=True, |
462 | | - capture_output=True, |
463 | | - ) |
| 456 | + with _console.status(f"Installing [bold]{target.name}[/] harness…"): |
| 457 | + result = subprocess.run( |
| 458 | + [runtime, "run", "--entrypoint", "sh", "--name", tmp_name, |
| 459 | + base_image, "-c", install_cmd], |
| 460 | + capture_output=True, |
| 461 | + text=True, |
| 462 | + ) |
| 463 | + if result.returncode != 0: |
| 464 | + if result.stderr: |
| 465 | + _console.print(result.stderr.strip(), style="red") |
| 466 | + raise subprocess.CalledProcessError(result.returncode, result.args) |
| 467 | + subprocess.run( |
| 468 | + [runtime, "commit", tmp_name, committed_tag], |
| 469 | + check=True, |
| 470 | + capture_output=True, |
| 471 | + ) |
464 | 472 | except subprocess.CalledProcessError as exc: |
465 | 473 | raise ContainerBuildError(f"Harness install failed for {target.name}: {exc}") from exc |
466 | 474 | finally: |
@@ -495,9 +503,9 @@ def launch_target( |
495 | 503 | registry_ref = _registry_image_ref(target.registry_name or target.name, version) |
496 | 504 | pulled = _try_pull_and_cache(tag, registry_ref, tarball, runtime=choice.runtime) |
497 | 505 | if not pulled: |
498 | | - _print(f"Building {name} container (first run — this may take a few minutes)…") |
499 | | - build_image(tag, rendered_cf, rendered_cf.parent, runtime=choice.runtime) |
500 | | - save_image_as_tarball(tag, tarball, runtime=choice.runtime) |
| 506 | + with _console.status(f"Building [bold]{name}[/] container…"): |
| 507 | + build_image(tag, rendered_cf, rendered_cf.parent, runtime=choice.runtime) |
| 508 | + save_image_as_tarball(tag, tarball, runtime=choice.runtime) |
501 | 509 |
|
502 | 510 | if not image_exists_locally(tag, runtime=choice.runtime, project_path=project_root): |
503 | 511 | load_image_from_tarball(tarball, runtime=choice.runtime) |
@@ -611,4 +619,4 @@ def _exec_interactive( |
611 | 619 |
|
612 | 620 |
|
613 | 621 | def _print(msg: str) -> None: |
614 | | - print(msg, file=sys.stderr) |
| 622 | + _console.print(msg) |
0 commit comments