Skip to content

feat(gpu): support explicit all-GPU sandboxes on Docker Desktop WSL #4849

Open

Description

@rsliter

User Story

We use OpenShell to run GPU workloads inside isolated sandboxes and need Docker Desktop WSL support for our OpenShell 0.1.x upgrade. We have directly tested the proposed workflow on an ARM64 NVIDIA RTX Spark N1X host. This is the independently deliverable WSL slice of #4837; that issue retains the broader Jetson and integration qualification work.

Problem Statement

The Docker driver at #4204 revision 33350a881f55011286e7c3a68d8007e43e50e0bf supports CDI GPU selection. We need an explicit OpenShell-owned NVIDIA injection path for Docker Desktop WSL where usable CDI is unavailable. External workload recreation does not preserve the split runtime's ownership of bootstrap credentials, networking and restart identity.

Impact / Why This Matters

This blocks the Docker Desktop WSL GPU workflow needed for our upgrade. A direct Docker CUDA probe works on our host, but callers need that capability through normal OpenShell sandbox creation and lifecycle operations with enforcement active.

Proposed Design

Allow a gateway operator to enable an explicit all-GPU selection for Docker Desktop WSL. Create the sandbox through the normal OpenShell CLI, retain runtime ownership and isolation, and preserve the selection across sandbox and gateway restarts. Keep ordinary CDI selection unchanged. Unsupported hosts or conflicting selections must fail clearly.

Suggested UX

With the gateway operator's allow_driver_config enabled:

openshell sandbox create --gpu \
  --driver-config-json '{"docker":{"nvidia_wsl_gpus":"all"}}' \
  --from <gpu-workload-image> -- <command>

The setting explicitly selects all GPUs. It must not silently convert a request for one GPU into access to all GPUs.

Acceptance Criteria

  • Normal OpenShell creation supports explicit NVIDIA all-GPU injection on Docker Desktop WSL, without requiring usable CDI or externally recreating the workload.
  • Require operator opt-in and reject unsupported daemons, conflicting CDI configuration, invalid modes and explicit GPU counts for this all-GPU mode.
  • Demonstrate CUDA initialization, enumeration, allocation and kernel execution as a non-root workload on the recorded ARM64 Docker Desktop WSL host.
  • Preserve workload identity, explicit GPU selection and sandbox data through sandbox stop/start and gateway restart; repeat CUDA validation afterward.
  • Keep Landlock, seccomp, capability restrictions and workload network isolation active. Demonstrate filesystem and direct network denials.
  • Retain bootstrap credential custody within OpenShell, reject mismatched protected GPU selection and clean up owned resources after deletion or failed creation.
  • Document configuration, supported scope and validation limits in the same PR.

Scope Boundaries

Initial hardware qualification is ARM64 Docker Desktop WSL on NVIDIA RTX Spark N1X with explicit all-GPU selection. Jetson, x86 hardware qualification, individual-device selection on multi-GPU hosts, Windows/Docker Desktop reboot, model inference and downstream compatibility-suite qualification remain outside this slice. This issue does not close #4837. Existing gateway endpoint configuration is used; no automatic WSL gateway-network discovery is proposed here.

Alternatives Considered

  • CDI remains the normal path; feat(gpu): derive Docker sandbox requirements from CDI specs #4204 supplies the parent work but does not establish the non-CDI workflow requested here.
  • External container recreation breaks runtime ownership and is not the proposed solution.
  • Middleware, interceptors and inference providers do not own Docker workload GPU injection.
  • Requiring all users to configure CDI would not establish support for the targeted host configuration.

Prototype Evidence

The local prototype and hardware results are summarized in #4837 (comment). The tested host uses Ubuntu24.04 WSL2, Docker Desktop4.96.0 / Engine29.9.1 and NVIDIA620.66. The prototype passed non-root CUDA kernel execution, enforcement checks, sandbox and gateway restarts, identity/state continuity and cleanup. The driver suite passed165 tests on macOS and ARM64 Linux, with two existing ignored tests.

This is a request for maintainer acceptance of the scoped workflow. It is not a claim that a supported release has shipped. The prototype remains unpublished pending issue acceptance.

Activity

  1. purp commented on Nov 5, 2026

    @purp
    Collaborator

    📋 triage-agent

    Thanks for the detailed report and prototype evidence. The User Story, acceptance criteria, scope boundaries, and hardware results are clear. Two points need your input before a maintainer can decide.

    1. Relationship to the existing WSL2 fallback on main. CdiGpuDefaultSelector already falls back to nvidia.com/gpu=all on WSL2 all-only runtimes (crates/openshell-core/src/gpu.rs, documented in docs/how-it-works/sandboxes/overview.mdx). That path still uses CDI. Please state, for the tested Docker Desktop host:

    • whether CDI specs are absent or present but unusable, with the relevant docker info CDI fields and the failure you see when requesting --gpu today, and
    • why the existing all-device fallback does not meet the need.

    2. Base revision. The issue cites #4204 at 33350a8, which is still open and not merged. main already contains CDI GPU selection. Please confirm which parts of #4204 the prototype still depends on, and whether it can be rebased onto current main.

    Also note that docs/about/support-matrix.mdx lists WSL 2 + Docker Desktop only as x86_64 Experimental, while this slice qualifies ARM64 only. A maintainer will need to decide whether that scope is acceptable.

    Related: #4837 (broader parent) and draft PR #4854.

    Next human decision: a maintainer decides whether to accept this WSL slice, ideally together with #4837, once the questions above are answered.

  2. added
    state:needs-infoAssessment needs specific evidence or reproduction details
    and removed
    state:triage-neededOpened without agent diagnostics and needs triage
    on Nov 5, 2026
  3. elezar commented on Nov 5, 2026

    @elezar
    Member

    Docker Desktop WSL where usable CDI is unavailable

    On Docker Desktop using the WSL backend, CDI should be available. The Docker Desktop VM includes the NVIDIA Container Toolkit and this should be generating CDI specs for the available devices. There may be a gap here though.

    A valid CDI specification is a hard prerequisite for providing a container (and thus a sandbox) access to a GPU. If there are not CDI specs available in Docker Desktop on this particular system, then we would need to loop in maintainers from the NVIDIA Container Toolkit and Docker Desktop.

    In oder to assess what the current state is, could you provide the output of docker info on this system? It would also be good to get the ouput (if any) of:

    docker run --rm -ti --gpus=nvidia.com/gpu=all ubuntu nividia-smi -L
    
    docker run --rm -ti --gpus=all ubuntu nvidia-smi -L
    
    docker run --rm -ti --gpus=all --runtime=runc ubuntu nvidia-smi -L
    
  4. rsliter commented on Nov 5, 2026

    @rsliter
    Author

    Thanks, Evan. We collected fresh diagnostics on the Yukon test system (ARM64 N1X, with the GPU reported as “NVIDIA RTX Spark N1X”) running WSL2, Docker Desktop 4.97.0 / Engine 29.9.2, and NVIDIA driver 621.14.

    Relevant docker info output:

    CDI spec directories:
     /etc/cdi
     /var/run/cdi
    Discovered Devices:
     cdi: docker.com/gpu=webgpu
    Runtimes: io.containerd.runc.v2 nvidia runc
    Default Runtime: runc
    

    The GPU probes returned:

    • --gpus=all: succeeds and lists the N1X GPU.
    • --gpus=all --runtime=runc: also succeeds.
    • --gpus=nvidia.com/gpu=all: Docker rejects the argument with unexpected key 'nvidia.com/gpu'.
    • We additionally tried --device=nvidia.com/gpu=all, which fails with CDI device injection failed: unresolvable CDI devices nvidia.com/gpu=all.

    So Docker can expose the GPU, but it isn’t discovering a usable NVIDIA CDI device on this configuration. We haven’t established why, or reproduced this through current OpenShell main; the installed OpenShell is still 0.0.116.

    Our prototype demonstrates that the alternate path works, but we agree that doesn’t establish it as the right permanent fix. Does this point to a CDI generation/discovery gap in Docker Desktop or Container Toolkit? What additional diagnostics would help narrow that down?

  5. rsliter commented on Nov 5, 2026

    @rsliter
    Author

    Follow-up with additional evidence from the Yukon configuration above: the NVIDIA CDI specification is absent from Docker’s discovery directories, but the installed NVIDIA Container Toolkit can generate one manually.

    Daemon filesystem and Toolkit

    We inspected the Docker daemon’s filesystem through its process root. The outer docker-desktop WSL distribution has a different filesystem view, so checking its /etc/cdi alone would be misleading.

    • Daemon /etc/cdi contains only docker-desktop.json, defining docker.com/gpu=webgpu.
    • Daemon /var/run/cdi does not exist.
    • NVIDIA Container Toolkit is 1.20.1. Running the following inside the daemon filesystem succeeds:
    nvidia-ctk --quiet cdi generate --output="" --format=json

    The generator detects WSL and emits a specification with kind nvidia.com/gpu, device all, /dev/dxg, WSL CUDA driver library mounts, and NVIDIA hooks. The installed nvidia-cdi-refresh service file targets /var/run/cdi/nvidia.yaml, but we have not established whether or how that service runs under Docker Desktop.

    We captured the generated specification without installing it. Docker discovery still lists only WebGPU. This establishes that generation can succeed, but not why automatic generation/publication is missing or whether the generated specification works end to end.

    WebGPU versus CUDA control

    Using the same cached NemoClaw sandbox image, Python ctypes probes produced:

    Docker selection Result
    --device=docker.com/gpu=webgpu Loading libcuda.so.1 fails: cannot open shared object file: No such file or directory
    --gpus=all cuInit: 0; cuDeviceGetCount: 0, devices: 1

    The WebGPU specification sets DD_WEBGPU=1, mounts /usr/lib/webgpu, and runs Docker Desktop’s WebGPU hooks. It does not provide the CUDA access needed by this workload in our test. We did not test WebGPU rendering or execute a CUDA kernel in this round.

    OpenShell reproduction on a mainline development build

    We also tested the official 0.1.8-dev.29+g1cdfe7088 CLI and gateway, verifying the release checksums and using isolated configuration/state directories. This build is from commit 1cdfe7088e5e4a44a9e4d8f79966055566cf2155, four commits behind main at the time of testing, so this is not an exact-tip-of-main result.

    openshell sandbox create --name qa-4849-current-cdi \
      --gpu --from ubuntu:latest --detach -- /bin/sleep 60

    It exits with FailedPrecondition:

    no NVIDIA CDI GPU devices were discovered
    

    No sandbox was created. The temporary gateway was stopped, test containers were removed, and existing workloads and the installed OpenShell 0.0.116 were left unchanged.

    These results narrow the investigation to the missing NVIDIA CDI specification in this Docker Desktop configuration. They do not establish that OpenShell supports only WebGPU, or that a separate GPU injection path is the necessary permanent fix.

  6. ericcurtin commented on Nov 9, 2026

    @ericcurtin
    Contributor

    @rsliter there was a patch for the added to Docker Desktop. Please try again in the latest version of Docker Desktop at the start of December. It may no longer be an issue in that release, if that proves to be true. This can be closed. We didn't have an RTX Spark to test, but we now run:

    nvidia-ctk cdi generate --output=/var/run/cdi/nvidia.yaml
    

    on startup. We think that should fix it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    state:needs-infoAssessment needs specific evidence or reproduction details

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions