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
The Kubernetes compute driver creates a default /sandbox workspace PVC for every sandbox pod (default_workspace_volume_claim_templates() in crates/openshell-driver-kubernetes/src/driver.rs, ~line 2158). The generated PVC spec only sets accessModes and resources.requests.storage — it never sets storageClassName. KubernetesComputeConfig (crates/openshell-driver-kubernetes/src/config.rs, ~line 269) only exposes workspace_default_storage_size; there is no storage-class field anywhere in the config struct, main.rs, or the Helm chart.
In clusters that have multiple StorageClass objects and no cluster-wide default StorageClass (a supported, common configuration), the generated PVC has an empty storageClassName. Kubernetes cannot bind or dynamically provision such a PVC, so it stays Pending indefinitely and sandbox creation fails outright. This is not a hypothetical edge case — we run clusters with multiple StorageClasses and intentionally no default, so this is a functional blocker for us today, not a nice-to-have.
Proposed Design
Mirror the existing workspace_default_storage_size pattern end-to-end so behavior stays backward compatible for clusters that do have a working default StorageClass:
Add workspace_storage_class: String to KubernetesComputeConfig (config.rs). Default is an empty string, meaning "omit storageClassName" — identical to current behavior.
Thread the value through SandboxPodParams in driver.rs and into default_workspace_volume_claim_templates(), setting storageClassName in the generated PVC spec only when the value is non-empty.
Add an environment variable (e.g. OPENSHELL_K8S_WORKSPACE_STORAGE_CLASS) read in main.rs, analogous to the existing OPENSHELL_K8S_WORKSPACE_DEFAULT_STORAGE_SIZE.
Wire the new setting through the Helm chart (deploy/helm/openshell/templates/gateway-config.yaml and values.yaml) as server.workspaceStorageClass, following the same pattern as server.workspaceDefaultStorageSize.
Update docs/reference/gateway-config.mdx and docs/reference/sandbox-compute-drivers.mdx to document the new field.
This keeps the setting at the same granularity as workspace_default_storage_size — a driver-level default applied to every sandbox's workspace PVC, not a per-sandbox override.
Alternatives Considered
Reference a pre-created PVC via driver_config.kubernetes volumes (the mechanism added in feat(kubernetes): support PVC subPath mounts via driver_config #2033): this lets an operator point a sandbox at an existing PVC with persistent_volume_claim.claim_name. It works for a single shared/static PVC but does not support per-sandbox, dynamically-provisioned PVCs on a specific StorageClass, so it isn't equivalent to configuring the default workspace PVC's storage class.
Rely on a cluster-level default StorageClass: this is the current implicit behavior, but it doesn't work for clusters that intentionally have no default StorageClass, which is our actual environment.
Agent Investigation
Investigated via direct code reading (not the create-spike skill): crates/openshell-driver-kubernetes/src/driver.rs (default_workspace_volume_claim_templates, SandboxPodParams), crates/openshell-driver-kubernetes/src/config.rs (KubernetesComputeConfig), crates/openshell-driver-kubernetes/src/main.rs (env var wiring), and deploy/helm/openshell/templates/gateway-config.yaml. Confirmed no storageClassName / storage-class configuration exists anywhere in this path today.
Problem Statement
The Kubernetes compute driver creates a default
/sandboxworkspace PVC for every sandbox pod (default_workspace_volume_claim_templates()incrates/openshell-driver-kubernetes/src/driver.rs, ~line 2158). The generated PVC spec only setsaccessModesandresources.requests.storage— it never setsstorageClassName.KubernetesComputeConfig(crates/openshell-driver-kubernetes/src/config.rs, ~line 269) only exposesworkspace_default_storage_size; there is no storage-class field anywhere in the config struct,main.rs, or the Helm chart.In clusters that have multiple
StorageClassobjects and no cluster-wide defaultStorageClass(a supported, common configuration), the generated PVC has an emptystorageClassName. Kubernetes cannot bind or dynamically provision such a PVC, so it staysPendingindefinitely and sandbox creation fails outright. This is not a hypothetical edge case — we run clusters with multiple StorageClasses and intentionally no default, so this is a functional blocker for us today, not a nice-to-have.Proposed Design
Mirror the existing
workspace_default_storage_sizepattern end-to-end so behavior stays backward compatible for clusters that do have a working defaultStorageClass:workspace_storage_class: StringtoKubernetesComputeConfig(config.rs). Default is an empty string, meaning "omitstorageClassName" — identical to current behavior.SandboxPodParamsindriver.rsand intodefault_workspace_volume_claim_templates(), settingstorageClassNamein the generated PVC spec only when the value is non-empty.OPENSHELL_K8S_WORKSPACE_STORAGE_CLASS) read inmain.rs, analogous to the existingOPENSHELL_K8S_WORKSPACE_DEFAULT_STORAGE_SIZE.deploy/helm/openshell/templates/gateway-config.yamlandvalues.yaml) asserver.workspaceStorageClass, following the same pattern asserver.workspaceDefaultStorageSize.docs/reference/gateway-config.mdxanddocs/reference/sandbox-compute-drivers.mdxto document the new field.This keeps the setting at the same granularity as
workspace_default_storage_size— a driver-level default applied to every sandbox's workspace PVC, not a per-sandbox override.Alternatives Considered
driver_config.kubernetesvolumes (the mechanism added in feat(kubernetes): support PVC subPath mounts via driver_config #2033): this lets an operator point a sandbox at an existing PVC withpersistent_volume_claim.claim_name. It works for a single shared/static PVC but does not support per-sandbox, dynamically-provisioned PVCs on a specificStorageClass, so it isn't equivalent to configuring the default workspace PVC's storage class.StorageClass: this is the current implicit behavior, but it doesn't work for clusters that intentionally have no defaultStorageClass, which is our actual environment.Agent Investigation
Investigated via direct code reading (not the
create-spikeskill):crates/openshell-driver-kubernetes/src/driver.rs(default_workspace_volume_claim_templates,SandboxPodParams),crates/openshell-driver-kubernetes/src/config.rs(KubernetesComputeConfig),crates/openshell-driver-kubernetes/src/main.rs(env var wiring), anddeploy/helm/openshell/templates/gateway-config.yaml. Confirmed nostorageClassName/ storage-class configuration exists anywhere in this path today.