refactor(image-cache): replace warn_if_stale with StaleImageError; add launch template
lint / lint (push) Successful in 2m0s
test / unit (pull_request) Successful in 57s
test / integration (pull_request) Successful in 17s
test / coverage (pull_request) Failing after 1m7s

- image_cache: StaleImageError exception + check_stale/check_stale_path (raise instead of warn)
- BottleBackend.launch: template method (skip_stale flag) that calls _image_stale_checks then _launch_impl
- Each backend: _image_stale_checks delegates to a stale_checks() function in its launch module; _launch_impl replaces launch override
- macos_container: adds image_created_at to util, cached-image support in _build_images, stale_checks
- cli/start.py: catches StaleImageError, prompts interactively, retries with skip_stale=True; headless mode dies on it
This commit is contained in:
2026-07-09 18:39:44 +00:00
parent 83bd20f9b3
commit 60b394e4fb
13 changed files with 200 additions and 80 deletions
+15 -11
View File
@@ -1,4 +1,4 @@
"""Shared helpers for cached-image quickstart warnings."""
"""Shared helpers for cached-image quickstart stale checks."""
from __future__ import annotations
@@ -7,13 +7,19 @@ from pathlib import Path
try:
from .config_store import ConfigStore
from .log import warn
except ImportError:
from config_store import ConfigStore # type: ignore[import-not-found] # pylint: disable=import-error,no-name-in-module
from log import warn # type: ignore[import-not-found] # pylint: disable=import-error,no-name-in-module
def warn_if_stale(label: str, created_at: datetime) -> None:
class StaleImageError(Exception):
"""Raised when a cached image or artifact exceeds the configured staleness
threshold. Callers can catch this to prompt interactively; headless paths
let it propagate as a fatal error."""
def check_stale(label: str, created_at: datetime) -> None:
"""Raise StaleImageError if `created_at` is older than the configured
stale-warning threshold. Negative threshold disables the check."""
threshold_days = ConfigStore().cached_image_stale_warning_days()
if threshold_days < 0:
return
@@ -22,17 +28,15 @@ def warn_if_stale(label: str, created_at: datetime) -> None:
age = now - created
if age.total_seconds() <= threshold_days * 86400:
return
warn(
raise StaleImageError(
f"cached {label} is {age.days} day(s) old; "
"quickstart does not verify it matches the current Dockerfile/context"
)
def warn_if_stale_path(label: str, path: Path) -> None:
warn_if_stale(
label,
datetime.fromtimestamp(path.stat().st_mtime, tz=timezone.utc),
)
def check_stale_path(label: str, path: Path) -> None:
"""Raise StaleImageError if `path`'s mtime exceeds the staleness threshold."""
check_stale(label, datetime.fromtimestamp(path.stat().st_mtime, tz=timezone.utc))
__all__ = ["warn_if_stale", "warn_if_stale_path"]
__all__ = ["StaleImageError", "check_stale", "check_stale_path"]