You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Adds the optional modules/sbx runtime provider. Importing the module and selecting TESTCONTAINERS_PROVIDER=sbx (or provider=sbx) starts one owned, detached Docker Sandbox before Docker client discovery, so test containers and Ryuk use its Docker Engine. The module passes the published sbx/docker-tcp:latest kit to sbx, promotes the created sandbox with sbx run --detach --name <name>, then verifies the explicitly requested loopback API publication and waits for the Engine. Detached promotion prevents sbx's 30-second session auto-stop from interrupting longer test runs; keeping create first preserves collision-safe ownership.
A local Docker API proxy allocates host TCP/UDP ports before inner container creation and keeps outer and guest port numbers aligned. It manages port and bind-mount lifecycle, streaming and hijacked connections, and reconciliation after Ryuk removes containers. Native Compose uses the same managed endpoint. Unsupported network modes and automatic restart policies fail explicitly; sandbox teardown is available through sbx.Cleanup(ctx).
Host binds are limited to the workspace and directories explicitly allowed through TESTCONTAINERS_SBX_BIND_ROOTS. The provider inspects requested paths through os.Root, preserves configured aliases and nested-root permissions, and rejects parent components, escaping or absolute symlinks, and unsupported special files before forwarding. External binds, including temporary directories and Compose service volumes, require configuration before initialization. Root identity is checked before mounting, but pathname replacement can still race the external sbx mount operation.
Core file-copy archives now encode root-relative member names while preserving absolute container destinations and nested directories. This fixes the strict tar validation failure exposed by the sandbox Engine. The public copy APIs have fake-Engine regressions using strict tar readers; real sbx exec assertions use the documented stream-decoding option.
CI adds Go 1.26.x and 1.27.x sbx runtime legs on Ubuntu 24.04 through the shared Go workflow and its existing module dependency hook. Each leg runs the complete root Go-module ./... suite without retries, the sbx module suite, and separate Compose routing/native integration checks. Three core tests explicitly skip unsupported host/container network modes. Reuse and Ryuk subprocess fixtures share the parent's sandbox Engine, and bootstrap remains lazy for configuration and fake-runtime tests. Each suite has its own report; sandbox cleanup failures fail the tests.
Live sbx legs run for relevant pushes to main and same-repository PRs using DOCKERHUB_USERNAME and DOCKERHUB_TOKEN, with a unique CLI namespace per run, attempt, and Go leg. Fork PRs retain ordinary lint/unit checks and skip the authenticated matrix. The final CI gate uses the same condition. The runtime guide documents local setup, cleanup, supported behavior, and host test commands.
Why is it important?
Provider initialization selects the sandbox Engine before any container or network can bootstrap Ryuk. Allocating the host port first prevents an inner Engine's random port choice from conflicting with a port already occupied on the host. The runtime remains optional through a separate Go module.
Local validation passed: pinned core golangci-lint 2.14.0, compile-only checks for every harness mode on Go 1.26.8 and Go 1.27.2, sbx unit tests with the race detector, Compose routing tests, and existing configuration/fake-runtime/session tests under the actual injected bootstrap. VM-free regressions verify inherited-provider validation, lazy property-file handling, failed-stage propagation, subsequent-stage execution, cleanup, and refusal to overwrite existing bootstrap files. Actionlint, shell checks, and path-selection regressions pass; temporary bootstrap files are removed and module metadata remains unchanged. The module's generated Dependabot/editor metadata and runtime guide are included.
Bind authorization also passes the full sbx race suite with a private allowed root, go vet, golangci-lint 2.14.0, and the compile-only module harness. Regressions cover rejected API requests without backend or port side effects, aliases, nested roots, symlink ordering, root replacement, read-only mounts, and concurrent cleanup.
On a host with sbx v0.48.0 or newer, virtualization support, and a Docker Hub login:
core runs the full root-module suite; all runs core plus the module and Compose stages. No real sandbox was started in this development environment because nested virtualization is unavailable. The current full runtime suite still requires host or eligible CI validation; this fork PR intentionally skips the authenticated sbx matrix. This PR remains a draft.
Register an optional sbx runtime before Docker discovery and run test
containers and Ryuk inside one owned Docker Sandbox. Embed the Docker TCP
kit source, let sbx build it, and verify the exact requested loopback API
publication before connecting.
Reserve host ports before inner container creation, reconcile forwarding
through container lifecycle events, and route native Compose through the
managed endpoint. Add dedicated change-triggered sbx CI, a host test
harness, and runtime documentation.
Co-Authored-By: GPT-5.6 Sol <[email protected]>
Co-Authored-By: GPT-6 Sol <[email protected]>
Co-Authored-By: GPT-6.1 Sol <[email protected]>
Co-Authored-By: GPT-6 Luna <[email protected]>
Encode container copy destinations as root-relative POSIX tar members
while preserving nested paths and the Engine extraction destination.
Reject invalid or escaping relative destinations and cover both public
copy methods with strict tar readers and a fake Engine.
Use the documented Multiplexed option in sbx integration exec assertions
so they compare decoded payloads instead of Docker stream framing.
Co-Authored-By: GPT-5.6 Sol <[email protected]>
Co-Authored-By: GPT-6.1 Sol <[email protected]>
Co-Authored-By: GPT-6 Luna <[email protected]>
Move the CI-only setup helper into .github/scripts and update workflow
and change-detection references. Preserve the developer-facing host
test runner at scripts/test-sbx.sh.
Co-Authored-By: GPT-6 Luna <[email protected]>
Pass sbx/docker-tcp:latest directly to the CLI and remove embedded source
materialization. Preserve sandbox cleanup ownership and document verbose
host test output.
Co-Authored-By: GPT-6.1 Sol <[email protected]>
Co-Authored-By: GPT-6 Luna <[email protected]>
Promote a newly created sandbox with run --detach before Docker discovery.
Create releases its CLI session, which otherwise lets sbx stop the sandbox
after the session grace period and interrupt longer test runs.
Keep collision-safe creation and fresh-context cleanup on promotion failure.
Cover the command sequence, timeout/error cleanup, and idle survival beyond
the 30-second grace period in the opt-in integration suite.
Co-Authored-By: GPT-6.1 Sol <[email protected]>
Pass DOCKERHUB_USERNAME and DOCKERHUB_TOKEN to the reusable sbx workflow
and read both credentials from secrets. Align the login checks and
documentation with the organization's existing credential names.
Co-Authored-By: GPT-6 Luna <[email protected]>
Refresh Dependabot and the VS Code workspace for the new sbx module.
This keeps modulegen refresh from leaving changes that fail CI's tidy
clean-tree check.
Co-Authored-By: GPT-6 Luna <[email protected]>
Refresh the sbx module metadata for dependencies already updated in the
root module on main. The stale metadata prevented read-only package
loading in the PR merge and made golangci-lint report no Go files.
Co-Authored-By: GPT-6 Luna <[email protected]>
Document host setup, provider registration and selection, explicit
sandbox cleanup, and verbose repository test commands. Link the guide
from System Requirements and the sbx module reference.
Co-Authored-By: GPT-6.1 Sol <[email protected]>
Run both supported Go versions through the shared dependency hook and
credentialed sbx runtime path for main pushes and same-repository PRs.
Keep subprocess reuse and Ryuk checks on the parent sandbox daemon,
preserve lazy configuration, and report module and Compose supplements.
Co-Authored-By: GPT-5.6 Sol <[email protected]>
Co-Authored-By: GPT-6.1 Sol <[email protected]>
Co-Authored-By: GPT-6 Luna <[email protected]>
Reuse the existing core module classification and configure sbx-specific
paths in the changed-files action. Classify rename sources as deletions
so changes moving between modules retain the same test coverage.
Remove the redundant sbx detector and its fixture script.
Co-Authored-By: GPT-6.1 Sol <[email protected]>
Document provider initialization and cleanup with concise Go comments.
Make authenticated sbx a prerequisite and show local and CI login,
including the configured CLI namespace.
Co-Authored-By: GPT-6.1 Sol <[email protected]>
Co-Authored-By: GPT-6 Luna <[email protected]>
Adds an optional Docker Sandboxes provider using the existing runtime registry, allowing Testcontainers and native Compose to share a managed sandbox Engine.
Changes:
Adds sandbox initialization, cleanup, port forwarding, and bind-mount management.
Routes Compose and subprocess tests through the selected runtime and fixes file-copy archive paths.
Adds regression tests, authenticated CI coverage, and setup documentation.
Allow workspace binds by default and require TESTCONTAINERS_SBX_BIND_ROOTS
for external host directories. Resolve requested paths through os.Root,
preserve configured aliases, and reject escaping symlinks and special files.
Check root identity before the sbx mount handoff and close directory handles
with the proxy. Cover authorization, aliases, lifecycle, and read-only binds;
document the configuration and prepare a private root for integration tests.
Co-Authored-By: GPT-5.6 Sol <[email protected]>
Co-Authored-By: GPT-6.1 Sol <[email protected]>
Reserve Docker public ports and serialize orphan cleanup with allocation.
Read immutable lease tuples without copying concurrent lifecycle state.
Co-Authored-By: GPT-5.6 Sol <[email protected]>
Keep the current shutdown error while allowing later cleanup to succeed.
Retain ownership when sandbox removal must be retried.
Co-Authored-By: GPT-6.1 Sol <[email protected]>
The reason will be displayed to describe this comment to others. Learn more.
🔵 Needs a closer look
The concurrent runtime and filesystem integration still require live-sandbox validation and final human review.
No open issues 🎉
1 previously missed issue
In code that hasn't changed since last review
Exclude later fixed ports from ephemeral allocation
modules/sbx/ports.go:93
Ephemeral allocation can consume a fixed port requested later in the same create request. For example, with 80/tcp random and 81/tcp fixed at 40000, an ephemeral candidate of 40000 makes planning fail as “already owned” instead of trying another port. Valid mixed bindings can therefore fail intermittently. Exclude every requested fixed protocol/port tuple from ephemeral selection before planning any bindings. Add a deterministic regression where the first candidate matches a later fixed binding.
Merge main and align the sbx properties dependency with the core library
so lint can load its packages in the pull request merge checkout.
Co-Authored-By: GPT-6 Luna <[email protected]>
Collect requested fixed protocol/port pairs before choosing random ports.
Add deterministic coverage for mixed bindings and protocol isolation.
Co-Authored-By: GPT-6.1 Sol <[email protected]>
Fixed this allocation-order finding in f51b0ecd. The planner excludes every requested fixed protocol/port pair before choosing ephemeral ports. The deterministic regression tries 40000 first, skips it, and selects 40001 while preserving the later fixed binding. It also covers UDP, a later binding in the same slice, and TCP/UDP independence.
The regression failed before the fix. The sbx non-live race suite, go vet, and golangci-lint 2.14.0 pass.
Use tab-delimited package inventory when adding core test bootstraps.
Co-Authored-By: GPT-6.1 Sol <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
featureNew functionality or new behaviors on the existing one
3 participants
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Adds the optional
modules/sbxruntime provider. Importing the module and selectingTESTCONTAINERS_PROVIDER=sbx(orprovider=sbx) starts one owned, detached Docker Sandbox before Docker client discovery, so test containers and Ryuk use its Docker Engine. The module passes the publishedsbx/docker-tcp:latestkit tosbx, promotes the created sandbox withsbx run --detach --name <name>, then verifies the explicitly requested loopback API publication and waits for the Engine. Detached promotion prevents sbx's 30-second session auto-stop from interrupting longer test runs; keepingcreatefirst preserves collision-safe ownership.A local Docker API proxy allocates host TCP/UDP ports before inner container creation and keeps outer and guest port numbers aligned. It manages port and bind-mount lifecycle, streaming and hijacked connections, and reconciliation after Ryuk removes containers. Native Compose uses the same managed endpoint. Unsupported network modes and automatic restart policies fail explicitly; sandbox teardown is available through
sbx.Cleanup(ctx).Host binds are limited to the workspace and directories explicitly allowed through
TESTCONTAINERS_SBX_BIND_ROOTS. The provider inspects requested paths throughos.Root, preserves configured aliases and nested-root permissions, and rejects parent components, escaping or absolute symlinks, and unsupported special files before forwarding. External binds, including temporary directories and Compose service volumes, require configuration before initialization. Root identity is checked before mounting, but pathname replacement can still race the externalsbx mountoperation.Core file-copy archives now encode root-relative member names while preserving absolute container destinations and nested directories. This fixes the strict tar validation failure exposed by the sandbox Engine. The public copy APIs have fake-Engine regressions using strict tar readers; real sbx exec assertions use the documented stream-decoding option.
CI adds Go
1.26.xand1.27.xsbx runtime legs on Ubuntu 24.04 through the shared Go workflow and its existing module dependency hook. Each leg runs the complete root Go-module./...suite without retries, the sbx module suite, and separate Compose routing/native integration checks. Three core tests explicitly skip unsupported host/container network modes. Reuse and Ryuk subprocess fixtures share the parent's sandbox Engine, and bootstrap remains lazy for configuration and fake-runtime tests. Each suite has its own report; sandbox cleanup failures fail the tests.Live sbx legs run for relevant pushes to
mainand same-repository PRs usingDOCKERHUB_USERNAMEandDOCKERHUB_TOKEN, with a unique CLI namespace per run, attempt, and Go leg. Fork PRs retain ordinary lint/unit checks and skip the authenticated matrix. The final CI gate uses the same condition. The runtime guide documents local setup, cleanup, supported behavior, and host test commands.Why is it important?
Provider initialization selects the sandbox Engine before any container or network can bootstrap Ryuk. Allocating the host port first prevents an inner Engine's random port choice from conflicting with a port already occupied on the host. The runtime remains optional through a separate Go module.
Related issues
mainindependently.How to test this PR
Local validation passed: pinned core golangci-lint 2.14.0, compile-only checks for every harness mode on Go 1.26.8 and Go 1.27.2, sbx unit tests with the race detector, Compose routing tests, and existing configuration/fake-runtime/session tests under the actual injected bootstrap. VM-free regressions verify inherited-provider validation, lazy property-file handling, failed-stage propagation, subsequent-stage execution, cleanup, and refusal to overwrite existing bootstrap files. Actionlint, shell checks, and path-selection regressions pass; temporary bootstrap files are removed and module metadata remains unchanged. The module's generated Dependabot/editor metadata and runtime guide are included.
Bind authorization also passes the full sbx race suite with a private allowed root,
go vet, golangci-lint 2.14.0, and the compile-only module harness. Regressions cover rejected API requests without backend or port side effects, aliases, nested roots, symlink ordering, root replacement, read-only mounts, and concurrent cleanup.On a host with sbx v0.48.0 or newer, virtualization support, and a Docker Hub login:
sbx login unset TESTCONTAINERS_SBX_APP_NAME GOFLAGS=-v ./scripts/test-sbx.sh module GOFLAGS=-v ./scripts/test-sbx.sh core GOFLAGS=-v ./scripts/test-sbx.sh composecoreruns the full root-module suite;allruns core plus the module and Compose stages. No real sandbox was started in this development environment because nested virtualization is unavailable. The current full runtime suite still requires host or eligible CI validation; this fork PR intentionally skips the authenticated sbx matrix. This PR remains a draft.