Skip to content

feat(k8s): support configuring storageClassName for the default workspace PVC #2442

Description

@loveRhythm1990

Problem Statement

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.

Activity

  1. loveRhythm1990 commented on Jul 23, 2026

    @loveRhythm1990
    ContributorAuthor

    If maintainers agree this request is reasonable, I'd be happy to implement this feature myself, including tests.

  2. matthewgrossman commented on Jul 23, 2026

    @matthewgrossman
    Member

    📋 triage-agent

    Triage Assessment

    Classification: feature-valid

    Summary

    Clusters without a default StorageClass cannot provision the default workspace PVC, and the requested optional setting is a bounded extension.

    Investigation

    The Kubernetes workspace PVC builder accepts a size but does not populate storageClassName. The limitation remains in current code.

    Recommendation

    Add an optional driver, gateway TOML, Helm, and documentation field; omit it when unset and render-test both paths.

  3. added
    area:clusterRelated to running OpenShell on k3s/docker
    and removed
    state:triage-neededOpened without agent diagnostics and needs triage
    on Jul 23, 2026
  4. added a commit that references this issue on Jul 24, 2026
    9a705b3
  5. added a commit that references this issue on Jul 29, 2026
    7955c83
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

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions