Skip to content

Make sandbox runner pluggable with Kubernetes driver support - #243

Open
eshulman2 wants to merge 3 commits into
mainfrom
pluggable-sandbox-driver
Open

Make sandbox runner pluggable with Kubernetes driver support#243
eshulman2 wants to merge 3 commits into
mainfrom
pluggable-sandbox-driver

Conversation

@eshulman2

Copy link
Copy Markdown
Collaborator

Summary

  • Extract SandboxDriver ABC from monolithic ContainerRunner, creating a pluggable driver interface (ExecutionSpecExecutionResult)
  • Refactor Podman-specific logic into PodmanDriver (command building, timeout handling, image management)
  • Add KubernetesDriver that runs tasks as K8s Jobs with PVC-based workspace sharing
  • Driver selection via FORGE_SANDBOX_DRIVER env var (default: podman, also supports kubernetes)
  • Zero caller impact — all 15 call sites across 11 workflow nodes unchanged

Closes #30

New files

File Purpose
src/forge/sandbox/driver.py SandboxDriver ABC, ExecutionSpec, ExecutionResult
src/forge/sandbox/drivers/__init__.py create_driver() factory
src/forge/sandbox/drivers/podman.py PodmanDriver (extracted from ContainerRunner)
src/forge/sandbox/drivers/kubernetes.py KubernetesDriver (K8s Job-based)
tests/unit/sandbox/test_kubernetes_driver.py 24 tests for K8s driver

Configuration

# Default (no change needed)
FORGE_SANDBOX_DRIVER=podman

# Kubernetes (requires kubernetes Python package: pip install forge[k8s])
FORGE_SANDBOX_DRIVER=kubernetes
FORGE_K8S_NAMESPACE=forge
FORGE_K8S_WORKSPACE_PVC=forge-workspaces
FORGE_K8S_WORKSPACE_BASE_PATH=/mnt/workspaces
# Optional:
FORGE_K8S_IMAGE_PULL_SECRETS=secret1,secret2
FORGE_K8S_SERVICE_ACCOUNT=forge-runner

Test plan

  • All 1904 unit tests pass
  • All 52 sandbox tests pass (3 pre-existing failures in unrelated entrypoint tests)
  • Lint passes (ruff check)
  • No workflow node files changed
  • Test FORGE_SANDBOX_DRIVER=podman runs identically to current behavior (manual)
  • Test FORGE_SANDBOX_DRIVER=kubernetes against a real K8s cluster

🤖 Generated with Claude Code

eshulman2 and others added 3 commits August 2, 2026 12:24
Extract a SandboxDriver ABC from the monolithic ContainerRunner and
refactor the Podman-specific logic into PodmanDriver. Add a
KubernetesDriver that runs tasks as K8s Jobs with PVC-based workspace
sharing. Driver selection is controlled by FORGE_SANDBOX_DRIVER
(default: podman).

The ContainerRunner public API is unchanged — all 15 call sites across
11 workflow nodes continue working without modification.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…itecture

- Run ruff format on new sandbox source files
- Update test_task_execution.py to mock ContainerRunner at the node
  level instead of patching removed subprocess calls
- Update test_task_handoff.py to inject mock driver via constructor
- Use ContainerResult dataclass instead of MagicMock to avoid attribute
  access issues with review_exhausted property

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make sandbox runner pluggable with different execution drivers

1 participant