swe_agentic: auto-release pulled images at process exit
Per-instance images are 1-4GB each; a --limit 10 run pulls up to 10 of them and previously stranded the whole footprint on Ctrl+C/exit. Every image THIS process pulls is now registered and released by an atexit hook (containers first, then rmi) -- images that already existed locally are never touched. EVALHARNESS_KEEP_SWE_IMAGES=1 opts out for prefetch-style runs that want to keep them. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
f09fe184fe
commit
e9e3230e46
@ -13,12 +13,56 @@ import asyncio
|
||||
import json
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import uuid
|
||||
from typing import Any, Dict
|
||||
|
||||
from ...data.sample import ChatMessage, Sample
|
||||
from ..loop import Environment, register_env
|
||||
|
||||
# ---- image lifecycle tracking -------------------------------------------
|
||||
# per-instance swe images are BIG (1-4GB each, 500 total ~2TB): every
|
||||
# image THIS process pulled is registered here and released at exit
|
||||
# (normal end, Ctrl+C kill, crash) so a run never strands its footprint.
|
||||
import atexit as _atexit
|
||||
|
||||
_IMAGES_PULLED: list = []
|
||||
|
||||
|
||||
def _release_pulled_images() -> None:
|
||||
import os as _os
|
||||
|
||||
if not _IMAGES_PULLED or _os.environ.get('EVALHARNESS_KEEP_SWE_IMAGES'):
|
||||
return
|
||||
# in-use containers first (docker refuses rmi otherwise)
|
||||
try:
|
||||
_docker(['ps', '-aq', '--filter', 'name=eh-swe-'], timeout=30)
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
_docker(['ps', '-aq', '--filter', 'ancestor=none'], timeout=30)
|
||||
except Exception:
|
||||
pass
|
||||
import subprocess as _sp
|
||||
|
||||
try:
|
||||
ids = _sp.run(['docker', 'ps', '-aq', '--filter', 'name=eh-swe'],
|
||||
capture_output=True, text=True, timeout=30).stdout.split()
|
||||
if ids:
|
||||
_docker(['rm', '-f'] + ids, timeout=120)
|
||||
except Exception:
|
||||
pass
|
||||
for img in _IMAGES_PULLED:
|
||||
try:
|
||||
_docker(['rmi', '-f', img], timeout=120)
|
||||
print(f'· released swe image {img}', file=sys.stderr, flush=True)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
_atexit.register(_release_pulled_images)
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
SENTINEL = 'COMPLETE_TASK_AND_SUBMIT_FINAL_OUTPUT'
|
||||
|
||||
# mini-swe-agent swebench.yaml contract (verbatim sections that matter)
|
||||
@ -123,10 +167,13 @@ class SWEAgenticEnvironment(Environment):
|
||||
# output and its 120s timeout kills runs on slow mirrors
|
||||
from ...sandbox.docker import ensure_image
|
||||
|
||||
had_it = _docker(['image', 'inspect', image]).returncode == 0
|
||||
try:
|
||||
ensure_image(image)
|
||||
except RuntimeError as e:
|
||||
raise RuntimeError(f'image {image} unavailable: {str(e)[:150]}')
|
||||
if not had_it and image not in _IMAGES_PULLED:
|
||||
_IMAGES_PULLED.append(image) # we pulled it -> we release it
|
||||
name = f'eh-swe-{uuid.uuid4().hex[:10]}'
|
||||
r = _docker(['run', '-d', '--name', name,
|
||||
'-w', '/testbed',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user