@@ -31,16 +31,17 @@ type Metadata struct {
3131}
3232
3333type DevEnvSpec struct {
34- Namespace string `yaml:"namespace"`
35- KubeContext string `yaml:"kubeContext"`
36- Session SessionSpec `yaml:"session"`
37- Workspace Workspace `yaml:"workspace"`
38- Sync SyncSpec `yaml:"sync"`
39- Ports []PortMapping `yaml:"ports"`
40- SSH SSHSpec `yaml:"ssh"`
41- Lifecycle LifecycleSpec `yaml:"lifecycle"`
42- Sidecar SidecarSpec `yaml:"sidecar"`
43- PodTemplate PodTemplateRef `yaml:"podTemplate"`
34+ Namespace string `yaml:"namespace"`
35+ KubeContext string `yaml:"kubeContext"`
36+ Session SessionSpec `yaml:"session"`
37+ Volumes []corev1.Volume `yaml:"volumes"`
38+ Workspace * LegacyWorkspace `yaml:"workspace,omitempty"`
39+ Sync SyncSpec `yaml:"sync"`
40+ Ports []PortMapping `yaml:"ports"`
41+ SSH SSHSpec `yaml:"ssh"`
42+ Lifecycle LifecycleSpec `yaml:"lifecycle"`
43+ Sidecar SidecarSpec `yaml:"sidecar"`
44+ PodTemplate PodTemplateRef `yaml:"podTemplate"`
4445}
4546
4647type SidecarSpec struct {
@@ -54,15 +55,15 @@ type SessionSpec struct {
5455 Shareable bool `yaml:"shareable"`
5556}
5657
57- type Workspace struct {
58- MountPath string `yaml:"mountPath"`
59- PVC PVCSettings `yaml:"pvc"`
60- }
58+ const (
59+ DefaultWorkspacePath = "/workspace"
60+ DefaultWorkspaceName = "workspace"
61+ )
6162
62- type PVCSettings struct {
63- ClaimName string `yaml:"claimName"`
64- Size string `yaml:"size "`
65- StorageClassName string `yaml:"storageClassName "`
63+ // LegacyWorkspace exists only to produce a clear migration error for removed config.
64+ type LegacyWorkspace struct {
65+ MountPath string `yaml:"mountPath "`
66+ PVC map [ string ] string `yaml:"pvc "`
6667}
6768
6869type PodTemplateRef struct {
@@ -173,8 +174,8 @@ func (d *DevEnvironment) Validate() error {
173174 if d .Metadata .Name == "" {
174175 return errors .New ("metadata.name is required" )
175176 }
176- if d .Spec .Workspace . MountPath == "" {
177- return errors .New ("spec.workspace.mountPath is required " )
177+ if d .Spec .Workspace != nil {
178+ return errors .New ("spec.workspace is removed; use spec.volumes (k8s Volume) and podTemplate.spec.containers[*].volumeMounts " )
178179 }
179180 if d .Spec .Sync .Engine != "syncthing" {
180181 return fmt .Errorf ("spec.sync.engine must be syncthing, got %q" , d .Spec .Sync .Engine )
@@ -229,6 +230,40 @@ func (s SyncthingSpec) AutoInstallEnabled() bool {
229230 return * s .AutoInstall
230231}
231232
233+ func (d * DevEnvironment ) EffectiveVolumes () []corev1.Volume {
234+ out := make ([]corev1.Volume , 0 , len (d .Spec .Volumes )+ 1 )
235+ hasWorkspace := false
236+ for _ , v := range d .Spec .Volumes {
237+ if v .Name == DefaultWorkspaceName {
238+ hasWorkspace = true
239+ }
240+ out = append (out , v )
241+ }
242+ if ! hasWorkspace {
243+ out = append (out , corev1.Volume {
244+ Name : DefaultWorkspaceName ,
245+ VolumeSource : corev1.VolumeSource {
246+ EmptyDir : & corev1.EmptyDirVolumeSource {},
247+ },
248+ })
249+ }
250+ return out
251+ }
252+
253+ func (d * DevEnvironment ) WorkspaceMountPath () string {
254+ for _ , c := range d .Spec .PodTemplate .Spec .Containers {
255+ if c .Name != "dev" {
256+ continue
257+ }
258+ for _ , vm := range c .VolumeMounts {
259+ if vm .Name == DefaultWorkspaceName && strings .TrimSpace (vm .MountPath ) != "" {
260+ return vm .MountPath
261+ }
262+ }
263+ }
264+ return DefaultWorkspacePath
265+ }
266+
232267func validateSyncPaths (paths []string ) error {
233268 for _ , p := range paths {
234269 parts := strings .Split (p , ":" )
0 commit comments