Skip to content

Commit cc1eee7

Browse files
committed
feat(server): support static provisioning PV for k8s PVC volumes
1 parent 8fab5d8 commit cc1eee7

14 files changed

Lines changed: 175 additions & 13 deletions

File tree

kubernetes/charts/opensandbox-server/templates/server.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ rules:
2929
- apiGroups: [""]
3030
resources: ["persistentvolumeclaims"]
3131
verbs: ["create", "get"]
32+
- apiGroups: [""]
33+
resources: ["persistentvolumes"]
34+
verbs: ["create", "get"]
3235
- apiGroups: ["node.k8s.io"]
3336
resources: ["runtimeclasses"]
3437
verbs: ["get", "list"]

sdks/sandbox/csharp/src/OpenSandbox/Models/Sandboxes.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,14 @@ public class PVC
185185
/// </summary>
186186
[JsonPropertyName("accessModes")]
187187
public IReadOnlyList<string>? AccessModes { get; set; }
188+
189+
/// <summary>
190+
/// Gets or sets the static PersistentVolume spec for Kubernetes.
191+
/// When provided, the server creates a PV with this spec bound to the auto-created PVC.
192+
/// Defaults to dynamic provisioning when omitted. Ignored for Docker volumes.
193+
/// </summary>
194+
[JsonPropertyName("pv")]
195+
public IReadOnlyDictionary<string, object>? Pv { get; set; }
188196
}
189197

190198
/// <summary>

sdks/sandbox/go/types.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,13 @@ type Host struct {
7777

7878
// PVC represents a platform-managed named volume backend.
7979
type PVC struct {
80-
ClaimName string `json:"claimName"`
81-
CreateIfNotExists *bool `json:"createIfNotExists,omitempty"`
82-
DeleteOnSandboxTermination *bool `json:"deleteOnSandboxTermination,omitempty"`
83-
StorageClass *string `json:"storageClass,omitempty"`
84-
Storage *string `json:"storage,omitempty"`
85-
AccessModes []string `json:"accessModes,omitempty"`
80+
ClaimName string `json:"claimName"`
81+
CreateIfNotExists *bool `json:"createIfNotExists,omitempty"`
82+
DeleteOnSandboxTermination *bool `json:"deleteOnSandboxTermination,omitempty"`
83+
StorageClass *string `json:"storageClass,omitempty"`
84+
Storage *string `json:"storage,omitempty"`
85+
AccessModes []string `json:"accessModes,omitempty"`
86+
PV map[string]any `json:"pv,omitempty"`
8687
}
8788

8889
// OSSFS represents an Alibaba Cloud OSS mount backend via ossfs.

sdks/sandbox/javascript/src/api/lifecycle.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1325,6 +1325,12 @@ export interface components {
13251325
* volumes.
13261326
*/
13271327
accessModes?: string[] | null;
1328+
/**
1329+
* @description Static PersistentVolume spec for Kubernetes. When provided,
1330+
* the server creates a PV with this spec bound to the auto-created PVC.
1331+
* Defaults to dynamic provisioning when omitted. Ignored for Docker volumes.
1332+
*/
1333+
pv?: Record<string, unknown> | null;
13281334
};
13291335
/**
13301336
* @description Alibaba Cloud OSS mount backend via ossfs.

sdks/sandbox/javascript/src/models/sandboxes.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,12 @@ export interface PVC extends Record<string, unknown> {
128128
* Ignored for Docker.
129129
*/
130130
accessModes?: string[] | null;
131+
/**
132+
* Static PersistentVolume spec for Kubernetes. When provided, the server
133+
* creates a PV with this spec bound to the auto-created PVC.
134+
* Defaults to dynamic provisioning when omitted. Ignored for Docker volumes.
135+
*/
136+
pv?: Record<string, unknown> | null;
131137
}
132138

133139
/**

sdks/sandbox/kotlin/sandbox/src/main/kotlin/com/alibaba/opensandbox/sandbox/domain/models/sandboxes/SandboxModels.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,7 @@ class PVC private constructor(
418418
val storageClass: String?,
419419
val storage: String?,
420420
val accessModes: List<String>?,
421+
val pv: Map<String, Any>?,
421422
) {
422423
companion object {
423424
@JvmStatic
@@ -434,6 +435,7 @@ class PVC private constructor(
434435
private var storageClass: String? = null
435436
private var storage: String? = null
436437
private var accessModes: List<String>? = null
438+
private var pv: Map<String, Any>? = null
437439

438440
fun claimName(claimName: String): Builder {
439441
require(claimName.isNotBlank()) { "Claim name cannot be blank" }
@@ -471,6 +473,11 @@ class PVC private constructor(
471473
return this
472474
}
473475

476+
fun pv(pv: Map<String, Any>?): Builder {
477+
this.pv = pv
478+
return this
479+
}
480+
474481
fun build(): PVC {
475482
val claimNameValue = claimName ?: throw IllegalArgumentException("Claim name must be specified")
476483
return PVC(
@@ -480,6 +487,7 @@ class PVC private constructor(
480487
storageClass = storageClass,
481488
storage = storage,
482489
accessModes = accessModes,
490+
pv = pv,
483491
)
484492
}
485493
}

sdks/sandbox/kotlin/sandbox/src/main/kotlin/com/alibaba/opensandbox/sandbox/infrastructure/adapters/converter/SandboxModelConverter.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ internal object SandboxModelConverter {
205205
storageClass = this.storageClass,
206206
storage = this.storage,
207207
accessModes = this.accessModes,
208+
pv = this.pv,
208209
)
209210
}
210211

sdks/sandbox/python/src/opensandbox/adapters/converter/sandbox_model_converter.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ def to_api_volume(volume: Volume):
125125
storage_class=volume.pvc.storage_class,
126126
storage=volume.pvc.storage,
127127
access_modes=volume.pvc.access_modes,
128+
pv=volume.pvc.pv,
128129
)
129130

130131
api_ossfs = UNSET

sdks/sandbox/python/src/opensandbox/api/lifecycle/models/pvc.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from __future__ import annotations
1818

1919
from collections.abc import Mapping
20-
from typing import Any, TypeVar, cast
20+
from typing import Any, TypeVar, cast, Dict
2121

2222
from attrs import define as _attrs_define
2323

@@ -66,6 +66,7 @@ class PVC:
6666
storage_class: None | str | Unset = UNSET
6767
storage: None | str | Unset = UNSET
6868
access_modes: list[str] | None | Unset = UNSET
69+
pv: Dict[str, Any] | None | Unset = UNSET
6970

7071
def to_dict(self) -> dict[str, Any]:
7172
claim_name = self.claim_name
@@ -113,6 +114,14 @@ def to_dict(self) -> dict[str, Any]:
113114
if access_modes is not UNSET:
114115
field_dict["accessModes"] = access_modes
115116

117+
pv: Dict[str, Any] | None | Unset
118+
if isinstance(self.pv, Unset):
119+
pv = UNSET
120+
else:
121+
pv = self.pv
122+
if pv is not UNSET:
123+
field_dict["pv"] = pv
124+
116125
return field_dict
117126

118127
@classmethod
@@ -159,13 +168,23 @@ def _parse_access_modes(data: object) -> list[str] | None | Unset:
159168

160169
access_modes = _parse_access_modes(d.pop("accessModes", UNSET))
161170

171+
def _parse_pv(data: object) -> Dict[str, Any] | None | Unset:
172+
if data is None:
173+
return data
174+
if isinstance(data, Unset):
175+
return data
176+
return cast(Dict[str, Any], data)
177+
178+
pv = _parse_pv(d.pop("pv", UNSET))
179+
162180
pvc = cls(
163181
claim_name=claim_name,
164182
create_if_not_exists=create_if_not_exists,
165183
delete_on_sandbox_termination=delete_on_sandbox_termination,
166184
storage_class=storage_class,
167185
storage=storage,
168186
access_modes=access_modes,
187+
pv=pv,
169188
)
170189

171190
return pvc

sdks/sandbox/python/src/opensandbox/models/sandboxes.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
import re
2323
from datetime import datetime
24-
from typing import Literal
24+
from typing import Any, Dict, Literal, Optional
2525

2626
from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
2727

@@ -227,6 +227,13 @@ class PVC(BaseModel):
227227
"Ignored for Docker."
228228
),
229229
)
230+
pv: Optional[Dict[str, Any]] = Field(
231+
None,
232+
description=(
233+
"static provisioning pv for auto-created PVCs. "
234+
"Defaults dynamic provisioning when omitted. Ignored for Docker volumes."
235+
),
236+
)
230237

231238
model_config = ConfigDict(populate_by_name=True)
232239

0 commit comments

Comments
 (0)