feat(box): support custom sandbox container image via config.yaml

Add 'image' field to box config section. When set, it overrides the
profile default image (python:3.11-slim) for all sandbox containers.
Priority: caller-specified > config.yaml image > profile default.
This commit is contained in:
Junyan Qin
2026-04-18 22:40:32 +08:00
committed by WangCham
parent cbb36139f4
commit 5a4ec62b14
2 changed files with 10 additions and 0 deletions

View File

@@ -60,6 +60,7 @@ class BoxService:
self.allowed_host_mount_roots = self._load_allowed_host_mount_roots()
self.default_host_workspace = self._load_default_host_workspace()
self.profile = self._load_profile()
self.custom_image = self._load_custom_image()
self.workspace_quota_mb = self._load_workspace_quota_mb()
self._recent_errors: collections.deque[dict] = collections.deque(maxlen=_MAX_RECENT_ERRORS)
self._shutdown_task = None
@@ -209,6 +210,10 @@ class BoxService:
if spec_payload.get('workspace_quota_mb') in (None, '') and self.workspace_quota_mb is not None:
spec_payload['workspace_quota_mb'] = self.workspace_quota_mb
# Global custom image overrides profile default (but not caller-specified image)
if self.custom_image and 'image' not in spec_payload:
spec_payload['image'] = self.custom_image
self._apply_profile(spec_payload)
try:
@@ -360,6 +365,10 @@ class BoxService:
default_host_workspace = os.path.join(self.shared_host_root, 'default')
return os.path.realpath(os.path.abspath(default_host_workspace))
def _load_custom_image(self) -> str | None:
raw = str(_get_box_config(self.ap).get('image', '') or '').strip()
return raw or None
def _load_workspace_quota_mb(self) -> int | None:
raw_value = _get_box_config(self.ap).get('workspace_quota_mb')
if raw_value in (None, ''):

View File

@@ -89,6 +89,7 @@ monitoring:
check_interval_hours: 1
box:
profile: 'default'
image: '' # Custom sandbox container image. Leave empty to use the profile default (python:3.11-slim).
runtime_url: '' # Action-RPC WebSocket URL of an external Box Runtime. Leave empty for auto-detection (stdio locally, Docker service in containers).
shared_host_root: './data/box' # For Docker deployment, use '/workspaces'
default_host_workspace: '' # Defaults to '<shared_host_root>/default'