Skip to content

Commit b00a675

Browse files
committed
fix(docker): validate explicit CDI device inventory
Signed-off-by: Evan Lezar <elezar@nvidia.com>
1 parent 877ddba commit b00a675

5 files changed

Lines changed: 53 additions & 10 deletions

File tree

‎crates/openshell-driver-docker/README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ contract:
8585
| `apparmor=unconfined` | Avoids Docker's default profile blocking required mount operations. |
8686
| `restart_policy = unless-stopped` | Keeps managed sandboxes resumable across daemon or gateway restarts. |
8787
| `PidsLimit` | Enforces the sandbox PID budget at the Docker cgroup layer. Set `[openshell.drivers.docker].sandbox_pids_limit = 0` to inherit the Docker/runtime default. |
88-
| CDI GPU request | Uses opaque `driver_config.cdi_devices` values when set; otherwise selects the requested count of NVIDIA CDI GPUs in round-robin order when daemon CDI support is detected. Docker daemon `/info` can permit `nvidia.com/gpu=all` as a WSL2 all-only compatibility fallback, where it counts as one selectable device. Exact CDI device lists must not contain duplicates and must match the effective GPU count. |
88+
| CDI GPU request | Validates `driver_config.cdi_devices` against Docker's current NVIDIA CDI inventory when set; otherwise selects the requested count in round-robin order when daemon CDI support is detected. Docker daemon `/info` can permit `nvidia.com/gpu=all` as a WSL2 all-only compatibility fallback, where it counts as one selectable device. Exact CDI device lists must not contain duplicates and must match the effective GPU count. |
8989

9090
The agent child process does not retain these supervisor privileges.
9191

‎crates/openshell-driver-docker/src/lib.rs‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,10 @@ impl DockerComputeDriver {
654654
"driver_config.cdi_devices",
655655
)
656656
.map_err(Status::invalid_argument)?;
657+
658+
self.refresh_gpu_inventory().await?;
659+
validate_discovered_cdi_gpu_devices(cdi_devices, &self.gpu_selector.device_ids())?;
660+
657661
return Ok(Some(cdi_devices.to_vec()));
658662
}
659663

@@ -2543,6 +2547,30 @@ fn docker_gpu_selection_status(err: CdiGpuSelectionError) -> Status {
25432547
Status::failed_precondition(err.to_string())
25442548
}
25452549

2550+
fn validate_discovered_cdi_gpu_devices(
2551+
requested: &[String],
2552+
discovered: &[String],
2553+
) -> Result<(), Status> {
2554+
let unavailable = requested
2555+
.iter()
2556+
.filter(|device| !discovered.iter().any(|known| known == *device))
2557+
.cloned()
2558+
.collect::<Vec<_>>();
2559+
if unavailable.is_empty() {
2560+
return Ok(());
2561+
}
2562+
2563+
let available = if discovered.is_empty() {
2564+
"none".to_string()
2565+
} else {
2566+
discovered.join(", ")
2567+
};
2568+
Err(Status::failed_precondition(format!(
2569+
"requested Docker CDI GPU device(s) were not discovered: {}; available devices: {available}",
2570+
unavailable.join(", "),
2571+
)))
2572+
}
2573+
25462574
#[cfg(test)]
25472575
fn build_container_create_body(
25482576
sandbox: &DriverSandbox,

‎crates/openshell-driver-docker/src/tests.rs‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1666,6 +1666,19 @@ fn validate_sandbox_accepts_single_cdi_device_without_gpu_count() {
16661666
.expect("single exact CDI device should be compatible with a default GPU request");
16671667
}
16681668

1669+
#[test]
1670+
fn explicit_cdi_devices_must_be_in_docker_inventory() {
1671+
let err = validate_discovered_cdi_gpu_devices(
1672+
&["nvidia.com/gpu=invalid".to_string()],
1673+
&["nvidia.com/gpu=0".to_string()],
1674+
)
1675+
.unwrap_err();
1676+
1677+
assert_eq!(err.code(), tonic::Code::FailedPrecondition);
1678+
assert!(err.message().contains("nvidia.com/gpu=invalid"));
1679+
assert!(err.message().contains("nvidia.com/gpu=0"));
1680+
}
1681+
16691682
#[test]
16701683
fn validate_sandbox_rejects_multiple_cdi_devices_without_gpu_count() {
16711684
let mut config = runtime_config();

‎docs/reference/sandbox-compute-drivers.mdx‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,13 @@ creates. On WSL2 all-only runtimes, Docker or Podman can use
9898
selectable device.
9999

100100
Exact GPU device selection remains driver-owned and requires `--gpu`. Docker
101-
and Podman accept `cdi_devices` as opaque CDI device names; replace the
102-
top-level `docker` key with `podman` when using the Podman driver, for example
103-
`{"docker":{"cdi_devices":["nvidia.com/gpu=0"]}}`. Explicit CDI device lists
104-
must not contain duplicates, and their length must match the effective GPU
105-
count. A single exact CDI device is compatible with the default `--gpu`
106-
request. The VM driver accepts `gpu_device_ids`, for example
101+
validates `cdi_devices` against its current NVIDIA CDI inventory before it
102+
creates a container. Podman accepts CDI device names as driver-owned values.
103+
Replace the top-level `docker` key with `podman` when using the Podman driver.
104+
For example: `{"docker":{"cdi_devices":["nvidia.com/gpu=0"]}}`. Explicit
105+
CDI device lists must not contain duplicates, and their length must match the
106+
effective GPU count. A single exact CDI device is compatible with the default
107+
`--gpu` request. The VM driver accepts `gpu_device_ids`, for example
107108
`{"vm":{"gpu_device_ids":["0000:2d:00.0"]}}`; the current VM implementation
108109
accepts at most one entry and allows either `--gpu` or `--gpu 1` when
109110
`gpu_device_ids` is set.

‎docs/sandboxes/manage-sandboxes.mdx‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,10 @@ device.
100100
101101
Exact GPU device selection is driver-specific and still requires `--gpu`. For
102102
Docker or Podman, pass CDI IDs through `cdi_devices`. The top-level key must
103-
match the active driver; replace `docker` with `podman` when using Podman. CDI
104-
IDs are treated as opaque strings. The list must not contain duplicate IDs, and
105-
its length must match the effective GPU count:
103+
match the active driver; replace `docker` with `podman` when using Podman.
104+
Docker validates each ID against its current NVIDIA CDI inventory before it
105+
creates the sandbox container. The list must not contain duplicate IDs, and its
106+
length must match the effective GPU count:
106107
107108
```shell
108109
openshell sandbox create \

0 commit comments

Comments
 (0)