fix(sandbox): require local runtime opt-in (#3092)

This commit is contained in:
Yufeng He
2026-06-17 19:50:00 +08:00
committed by GitHub
parent 03e5811d57
commit fe35e832a4
3 changed files with 69 additions and 6 deletions

View File

@@ -35,6 +35,14 @@ MAX_DEPENDENCY_INSTALL_SIZE = 200 * 1024 * 1024 # 200MB
MAX_PROCESSES = 10
SANDBOX_RUNTIME = os.getenv(
"SANDBOX_RUNTIME", "local"
) # Optional values: docker, podman, nerdctl, local
def _env_flag(name: str, default: bool = False) -> bool:
value = os.getenv(name)
if value is None:
return default
return value.lower() in {"1", "true", "yes", "on"}
# Optional values: docker, podman, nerdctl, local. When unset, RuntimeFactory
# auto-detects container runtimes and fails closed if none are available.
SANDBOX_RUNTIME = os.getenv("SANDBOX_RUNTIME")
SANDBOX_ALLOW_LOCAL_RUNTIME = _env_flag("SANDBOX_ALLOW_LOCAL_RUNTIME")

View File

@@ -4,7 +4,7 @@
根据本机环境优先级自动选择 Docker/Podman/Nerdctl/Local 运行时。
"""
from ..config import SANDBOX_RUNTIME
from ..config import SANDBOX_ALLOW_LOCAL_RUNTIME, SANDBOX_RUNTIME
from .docker_runtime import DockerRuntime
from .local_runtime import LocalRuntime
from .nerdctl_runtime import NerdctlRuntime
@@ -15,6 +15,16 @@ from .utils import EnvironmentDetector
class RuntimeFactory:
"""自动选择最佳沙箱运行时"""
@staticmethod
def _local_runtime() -> LocalRuntime:
if not SANDBOX_ALLOW_LOCAL_RUNTIME:
raise RuntimeError(
"LocalRuntime executes code on the host. Set "
"SANDBOX_RUNTIME=local and SANDBOX_ALLOW_LOCAL_RUNTIME=true "
"to opt in explicitly."
)
return LocalRuntime()
@staticmethod
def create(runtime_preference: str = None):
"""
@@ -42,7 +52,7 @@ class RuntimeFactory:
):
return NerdctlRuntime()
if runtime_preference == "local":
return LocalRuntime()
return RuntimeFactory._local_runtime()
raise RuntimeError(f"指定的运行时不可用: {runtime_preference}")
if EnvironmentDetector.is_docker_sdk_available():
@@ -59,4 +69,10 @@ class RuntimeFactory:
return PodmanRuntime()
if EnvironmentDetector.is_nerdctl_available():
return NerdctlRuntime()
return LocalRuntime()
if SANDBOX_ALLOW_LOCAL_RUNTIME:
return LocalRuntime()
raise RuntimeError(
"No container sandbox runtime is available. Install Docker, Podman, "
"or Nerdctl, or explicitly opt into host-local execution with "
"SANDBOX_RUNTIME=local and SANDBOX_ALLOW_LOCAL_RUNTIME=true."
)

View File

@@ -0,0 +1,39 @@
import pytest
from dbgpt_sandbox.sandbox.execution_layer import runtime_factory
from dbgpt_sandbox.sandbox.execution_layer.local_runtime import LocalRuntime
def _disable_container_runtimes(monkeypatch):
detector = runtime_factory.EnvironmentDetector
monkeypatch.setattr(
detector, "is_docker_sdk_available", staticmethod(lambda: False)
)
monkeypatch.setattr(detector, "is_podman_available", staticmethod(lambda: False))
monkeypatch.setattr(detector, "is_nerdctl_available", staticmethod(lambda: False))
def test_auto_runtime_fails_closed_without_container(monkeypatch):
_disable_container_runtimes(monkeypatch)
monkeypatch.setattr(runtime_factory, "SANDBOX_RUNTIME", None)
monkeypatch.setattr(runtime_factory, "SANDBOX_ALLOW_LOCAL_RUNTIME", False)
with pytest.raises(RuntimeError, match="No container sandbox runtime"):
runtime_factory.RuntimeFactory.create()
def test_local_runtime_requires_explicit_opt_in(monkeypatch):
_disable_container_runtimes(monkeypatch)
monkeypatch.setattr(runtime_factory, "SANDBOX_ALLOW_LOCAL_RUNTIME", False)
with pytest.raises(RuntimeError, match="LocalRuntime executes code on the host"):
runtime_factory.RuntimeFactory.create("local")
def test_local_runtime_can_be_enabled_explicitly(monkeypatch):
_disable_container_runtimes(monkeypatch)
monkeypatch.setattr(runtime_factory, "SANDBOX_ALLOW_LOCAL_RUNTIME", True)
runtime = runtime_factory.RuntimeFactory.create("local")
assert isinstance(runtime, LocalRuntime)