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
+19 -14
View File
@@ -41,7 +41,7 @@ from ...git_gate import (
provision_git_gate_dynamic_keys,
revoke_git_gate_provisioned_keys,
)
from ...image_cache import warn_if_stale
from ...image_cache import check_stale
from ...log import die, info, warn
from . import network as network_mod
from . import util as docker_mod
@@ -105,11 +105,6 @@ def launch(
cached_policy = plan.spec.image_policy == "cached"
if committed and docker_mod.image_exists(committed):
info(f"using committed image {committed!r}")
if cached_policy:
warn_if_stale(
f"agent image {committed!r}",
docker_mod.image_created_at(committed),
)
plan = dataclasses.replace(
plan,
agent_provision=dataclasses.replace(plan.agent_provision, image=committed),
@@ -127,14 +122,6 @@ def launch(
)
info(f"using cached agent image {plan.image!r}")
info(f"using cached sidecar image {SIDECAR_BUNDLE_IMAGE!r}")
warn_if_stale(
f"agent image {plan.image!r}",
docker_mod.image_created_at(plan.image),
)
warn_if_stale(
f"sidecar image {SIDECAR_BUNDLE_IMAGE!r}",
docker_mod.image_created_at(SIDECAR_BUNDLE_IMAGE),
)
else:
docker_mod.build_image(
plan.image, _REPO_DIR,
@@ -236,3 +223,21 @@ def launch(
yield bottle
finally:
teardown()
def stale_checks(plan: DockerBottlePlan) -> None:
"""Raise StaleImageError if a cached image is older than the configured
threshold. Only runs when image_policy is 'cached'. Called by the backend
class's _image_stale_checks before _launch_impl starts any resources."""
if plan.spec.image_policy != "cached":
return
committed = read_committed_image(plan.slug)
if committed and docker_mod.image_exists(committed):
check_stale(f"agent image {committed!r}", docker_mod.image_created_at(committed))
return
for label, ref in [
("agent image", plan.image),
("sidecar image", SIDECAR_BUNDLE_IMAGE),
]:
if docker_mod.image_exists(ref):
check_stale(f"{label} {ref!r}", docker_mod.image_created_at(ref))