From 26a28a97da5ce4ca91e7f4eea3b606bfaa744013 Mon Sep 17 00:00:00 2001 From: Drew Newberry Date: Wed, 9 Sep 2026 21:48:04 -0700 Subject: [PATCH 1/3] refactor(compute): remove legacy host users encoding Closes #2861 Remove the Kubernetes driver fallback for platform_config.host_users and document the typed-only user namespace contract for 0.1.0. Signed-off-by: Drew Newberry --- architecture/compute-runtimes.md | 8 +++++++ .../openshell-driver-kubernetes/src/driver.rs | 23 ++++--------------- docs/about/release-notes.mdx | 14 +++++++++++ docs/reference/sandbox-compute-drivers.mdx | 21 +++++++++++++++++ 4 files changed, 48 insertions(+), 18 deletions(-) diff --git a/architecture/compute-runtimes.md b/architecture/compute-runtimes.md index e1e731a0ce..885df909d0 100644 --- a/architecture/compute-runtimes.md +++ b/architecture/compute-runtimes.md @@ -42,6 +42,14 @@ Process-identity omissions are preserved across this boundary so every driver can apply its native image or runtime defaults. Driver-requested listeners are structurally validated and remain restricted to sandbox callback RPCs. +`DriverSandboxTemplate.user_namespaces` is the sole portable representation of +user-namespace intent. Drivers that implement the intent map this typed field to +their runtime; Kubernetes maps it to `hostUsers: false`. The gateway does not +encode that intent in `platform_config`, and drivers do not read the former +Kubernetes-specific `platform_config.host_users` key. Gateways and external +drivers that implement the legacy encoding must not be mixed with this typed-only +contract when per-sandbox user namespaces are required. + Canonical main-process support is part of the `ComputeDriver` contract. Every in-tree and extension driver must forward the exact specification; it is not an optional capability that drivers can omit or negotiate. diff --git a/crates/openshell-driver-kubernetes/src/driver.rs b/crates/openshell-driver-kubernetes/src/driver.rs index 1e790bf348..979687fed4 100644 --- a/crates/openshell-driver-kubernetes/src/driver.rs +++ b/crates/openshell-driver-kubernetes/src/driver.rs @@ -3851,12 +3851,9 @@ fn sandbox_template_to_k8s_with_validated_config( apply_pod_driver_config(&mut spec, &driver_config.pod); // Per-sandbox portable intent overrides the cluster-wide default. This - // driver owns the Kubernetes-specific `hostUsers` translation. Accept the - // former platform_config encoding during rolling upgrades from gateways - // that predate the typed field. + // driver owns the Kubernetes-specific `hostUsers` translation. let use_user_namespaces = template .user_namespaces - .or_else(|| platform_config_bool(template, "host_users").map(|host_users| !host_users)) .unwrap_or(params.enable_user_namespaces); if use_user_namespaces { @@ -4469,15 +4466,6 @@ fn platform_config_string(template: &SandboxTemplate, key: &str) -> Option Option { - let config = template.platform_config.as_ref()?; - let value = config.fields.get(key)?; - match value.kind.as_ref() { - Some(prost_types::value::Kind::BoolValue(value)) => Some(*value), - _ => None, - } -} - /// Extract a nested Struct value from the template's `platform_config`, /// converting it to `serde_json::Value`. fn platform_config_struct(template: &SandboxTemplate, key: &str) -> Option { @@ -7728,7 +7716,7 @@ mod tests { } #[test] - fn user_namespaces_accepts_legacy_host_users_encoding() { + fn user_namespaces_ignores_legacy_host_users_encoding() { let template = SandboxTemplate { platform_config: Some(Struct { fields: std::iter::once(( @@ -7751,10 +7739,9 @@ mod tests { ¶ms, ); - assert_eq!( - pod_template["spec"]["hostUsers"], - serde_json::json!(false), - "legacy host_users: false must still enable user namespaces" + assert!( + pod_template["spec"]["hostUsers"].is_null(), + "legacy host_users must not enable user namespaces" ); } diff --git a/docs/about/release-notes.mdx b/docs/about/release-notes.mdx index f763c89952..d5b1af283f 100644 --- a/docs/about/release-notes.mdx +++ b/docs/about/release-notes.mdx @@ -10,6 +10,20 @@ position: 6 NVIDIA OpenShell follows a frequent release cadence. Use the following GitHub resources directly. +## 0.1.0 Migration Notes + +The compute-driver contract now carries portable user-namespace intent only in +the typed `DriverSandboxTemplate.user_namespaces` field. The gateway no longer +emits the former Kubernetes-specific `platform_config.host_users` value, and +the Kubernetes driver no longer honors it. + +If you run the Kubernetes driver as an external process, upgrade it together +with the gateway. A gateway or driver that relies on the legacy pre-`0.1.0` +encoding does not preserve per-sandbox user-namespace overrides when paired +with the typed-only contract. Out-of-tree driver maintainers must regenerate +their protobuf bindings and consume the typed field. See the +[compute driver compatibility matrix](/reference/sandbox-compute-drivers#compute-driver-compatibility). + | Resource | Description | |---|---| | [Releases](https://github.com/NVIDIA/OpenShell/releases) | Versioned release notes and downloadable assets. | diff --git a/docs/reference/sandbox-compute-drivers.mdx b/docs/reference/sandbox-compute-drivers.mdx index e46ebf8a23..99a1e39283 100644 --- a/docs/reference/sandbox-compute-drivers.mdx +++ b/docs/reference/sandbox-compute-drivers.mdx @@ -40,6 +40,27 @@ an exited canonical process remains a terminal sandbox result. Exit code zero produces `Completed`; a nonzero or signal-normalized exit produces `Error` with the exact exit code. Driver and supervisor failures remain `Error`. +## Compute Driver Compatibility + +OpenShell `0.1.0` establishes `DriverSandboxTemplate.user_namespaces` as the +only compute-driver representation of portable user-namespace intent. The +Kubernetes driver maps the typed value to PodSpec `hostUsers`; Docker, Podman, +MicroVM, and MXC do not currently implement this optional intent. In-process +and standalone first-party drivers use the same protobuf contract and driver +implementation. + +| Gateway contract | External Kubernetes driver contract | Per-sandbox user namespaces | +|---|---|---| +| Typed `user_namespaces` | Typed `user_namespaces` | Supported. | +| Typed `user_namespaces` | Legacy `platform_config.host_users` | Unsupported. The driver does not consume the typed field. | +| Legacy `platform_config.host_users` | Typed `user_namespaces` | Unsupported. The driver ignores the removed opaque encoding. | + +Keep an external Kubernetes driver on the same release train as its gateway +when using per-sandbox user namespaces. Out-of-tree drivers that implement +this intent must regenerate bindings from the `0.1.0` compute-driver protobuf +and read `user_namespaces`; `platform_config.host_users` is not emitted or +honored. + ## Configure a Compute Driver Configure the compute driver on the gateway. Current releases accept one driver per gateway. Set `compute_drivers` in the gateway TOML file: From 491598b27382c1b24e04aea1a3b9fc3e002cf6ad Mon Sep 17 00:00:00 2001 From: Drew Newberry Date: Wed, 9 Sep 2026 22:24:18 -0700 Subject: [PATCH 2/3] docs(compute): defer public compatibility guidance Signed-off-by: Drew Newberry --- docs/about/release-notes.mdx | 14 -------------- docs/reference/sandbox-compute-drivers.mdx | 21 --------------------- 2 files changed, 35 deletions(-) diff --git a/docs/about/release-notes.mdx b/docs/about/release-notes.mdx index d5b1af283f..f763c89952 100644 --- a/docs/about/release-notes.mdx +++ b/docs/about/release-notes.mdx @@ -10,20 +10,6 @@ position: 6 NVIDIA OpenShell follows a frequent release cadence. Use the following GitHub resources directly. -## 0.1.0 Migration Notes - -The compute-driver contract now carries portable user-namespace intent only in -the typed `DriverSandboxTemplate.user_namespaces` field. The gateway no longer -emits the former Kubernetes-specific `platform_config.host_users` value, and -the Kubernetes driver no longer honors it. - -If you run the Kubernetes driver as an external process, upgrade it together -with the gateway. A gateway or driver that relies on the legacy pre-`0.1.0` -encoding does not preserve per-sandbox user-namespace overrides when paired -with the typed-only contract. Out-of-tree driver maintainers must regenerate -their protobuf bindings and consume the typed field. See the -[compute driver compatibility matrix](/reference/sandbox-compute-drivers#compute-driver-compatibility). - | Resource | Description | |---|---| | [Releases](https://github.com/NVIDIA/OpenShell/releases) | Versioned release notes and downloadable assets. | diff --git a/docs/reference/sandbox-compute-drivers.mdx b/docs/reference/sandbox-compute-drivers.mdx index 99a1e39283..e46ebf8a23 100644 --- a/docs/reference/sandbox-compute-drivers.mdx +++ b/docs/reference/sandbox-compute-drivers.mdx @@ -40,27 +40,6 @@ an exited canonical process remains a terminal sandbox result. Exit code zero produces `Completed`; a nonzero or signal-normalized exit produces `Error` with the exact exit code. Driver and supervisor failures remain `Error`. -## Compute Driver Compatibility - -OpenShell `0.1.0` establishes `DriverSandboxTemplate.user_namespaces` as the -only compute-driver representation of portable user-namespace intent. The -Kubernetes driver maps the typed value to PodSpec `hostUsers`; Docker, Podman, -MicroVM, and MXC do not currently implement this optional intent. In-process -and standalone first-party drivers use the same protobuf contract and driver -implementation. - -| Gateway contract | External Kubernetes driver contract | Per-sandbox user namespaces | -|---|---|---| -| Typed `user_namespaces` | Typed `user_namespaces` | Supported. | -| Typed `user_namespaces` | Legacy `platform_config.host_users` | Unsupported. The driver does not consume the typed field. | -| Legacy `platform_config.host_users` | Typed `user_namespaces` | Unsupported. The driver ignores the removed opaque encoding. | - -Keep an external Kubernetes driver on the same release train as its gateway -when using per-sandbox user namespaces. Out-of-tree drivers that implement -this intent must regenerate bindings from the `0.1.0` compute-driver protobuf -and read `user_namespaces`; `platform_config.host_users` is not emitted or -honored. - ## Configure a Compute Driver Configure the compute driver on the gateway. Current releases accept one driver per gateway. Set `compute_drivers` in the gateway TOML file: From 36951b129091a0e25ee8570b67c1aaa8b4c83ae4 Mon Sep 17 00:00:00 2001 From: Drew Newberry Date: Wed, 9 Sep 2026 22:27:33 -0700 Subject: [PATCH 3/3] docs(compute): defer contract documentation Signed-off-by: Drew Newberry --- architecture/compute-runtimes.md | 8 -------- 1 file changed, 8 deletions(-) diff --git a/architecture/compute-runtimes.md b/architecture/compute-runtimes.md index 885df909d0..e1e731a0ce 100644 --- a/architecture/compute-runtimes.md +++ b/architecture/compute-runtimes.md @@ -42,14 +42,6 @@ Process-identity omissions are preserved across this boundary so every driver can apply its native image or runtime defaults. Driver-requested listeners are structurally validated and remain restricted to sandbox callback RPCs. -`DriverSandboxTemplate.user_namespaces` is the sole portable representation of -user-namespace intent. Drivers that implement the intent map this typed field to -their runtime; Kubernetes maps it to `hostUsers: false`. The gateway does not -encode that intent in `platform_config`, and drivers do not read the former -Kubernetes-specific `platform_config.host_users` key. Gateways and external -drivers that implement the legacy encoding must not be mixed with this typed-only -contract when per-sandbox user namespaces are required. - Canonical main-process support is part of the `ComputeDriver` contract. Every in-tree and extension driver must forward the exact specification; it is not an optional capability that drivers can omit or negotiate.