Skip to content

Commit e6aeba9

Browse files
committed
feat: Mounting PVC into Workspace within Subpath
Signed-off-by: Anatolii Bazko <abazko@redhat.com>
1 parent e5db1b6 commit e6aeba9

File tree

5 files changed

+77
-7
lines changed

5 files changed

+77
-7
lines changed

pkg/constants/metadata.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Copyright (c) 2019-2025 Red Hat, Inc.
2+
// Copyright (c) 2019-2026 Red Hat, Inc.
33
// Licensed under the Apache License, Version 2.0 (the "License");
44
// you may not use this file except in compliance with the License.
55
// You may obtain a copy of the License at
@@ -121,6 +121,12 @@ const (
121121
// read-write. Automounted configmaps and secrets are always mounted read-only and this annotation is ignored.
122122
DevWorkspaceMountReadyOnlyAnnotation = "controller.devfile.io/read-only"
123123

124+
// DevWorkspaceMountSubPathAnnotation is an annotation to configure a subPath for a mounted PVC volume.
125+
// When set on a PVC with the automount label, the volume mount will use the specified subPath,
126+
// allowing a subdirectory within the PVC to be mounted instead of the root.
127+
// This annotation is only used for PersistentVolumeClaims.
128+
DevWorkspaceMountSubPathAnnotation = "controller.devfile.io/mount-sub-path"
129+
124130
// DevWorkspaceRestrictedAccessAnnotation marks the intention that devworkspace access is restricted to only the creator; setting this
125131
// annotation will cause devworkspace start to fail if webhooks are disabled.
126132
// Operator also propagates it to the devworkspace-related objects to perform authorization.

pkg/provision/automount/common_test.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Copyright (c) 2019-2025 Red Hat, Inc.
2+
// Copyright (c) 2019-2026 Red Hat, Inc.
33
// Licensed under the Apache License, Version 2.0 (the "License");
44
// you may not use this file except in compliance with the License.
55
// You may obtain a copy of the License at
@@ -51,10 +51,11 @@ const (
5151
type testCase struct {
5252
Name string `json:"name"`
5353
Input struct {
54-
// Secrets and Configmaps are necessary for deserialization from a testcase
55-
Secrets []corev1.Secret `json:"secrets"`
56-
ConfigMaps []corev1.ConfigMap `json:"configmaps"`
57-
// allObjects contains all Secrets and Configmaps defined above, for convenience
54+
// Secrets, Configmaps, and PVCs are necessary for deserialization from a testcase
55+
Secrets []corev1.Secret `json:"secrets"`
56+
ConfigMaps []corev1.ConfigMap `json:"configmaps"`
57+
PVCs []corev1.PersistentVolumeClaim `json:"pvcs"`
58+
// allObjects contains all Secrets, Configmaps, and PVCs defined above, for convenience
5859
allObjects []client.Object
5960
} `json:"input"`
6061
Output struct {
@@ -382,6 +383,9 @@ func loadTestCaseOrPanic(t *testing.T, testPath string) testCase {
382383
for idx := range test.Input.Secrets {
383384
test.Input.allObjects = append(test.Input.allObjects, &test.Input.Secrets[idx])
384385
}
386+
for idx := range test.Input.PVCs {
387+
test.Input.allObjects = append(test.Input.allObjects, &test.Input.PVCs[idx])
388+
}
385389

386390
// Overwrite namespace for convenience
387391
for _, obj := range test.Input.allObjects {

pkg/provision/automount/pvcs.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Copyright (c) 2019-2025 Red Hat, Inc.
2+
// Copyright (c) 2019-2026 Red Hat, Inc.
33
// Licensed under the Apache License, Version 2.0 (the "License");
44
// you may not use this file except in compliance with the License.
55
// You may obtain a copy of the License at
@@ -41,6 +41,7 @@ func getAutoMountPVCs(namespace string, api sync.ClusterAPI) (*Resources, error)
4141
var volumeMounts []corev1.VolumeMount
4242
for _, pvc := range pvcs.Items {
4343
mountPath := pvc.Annotations[constants.DevWorkspaceMountPathAnnotation]
44+
subPath := pvc.Annotations[constants.DevWorkspaceMountSubPathAnnotation]
4445
if mountPath == "" {
4546
mountPath = path.Join("/tmp/", pvc.Name)
4647
}
@@ -62,6 +63,7 @@ func getAutoMountPVCs(namespace string, api sync.ClusterAPI) (*Resources, error)
6263
volumeMounts = append(volumeMounts, corev1.VolumeMount{
6364
Name: common.AutoMountPVCVolumeName(pvc.Name),
6465
MountPath: mountPath,
66+
SubPath: subPath,
6567
})
6668
}
6769
return &Resources{
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: Provisions automount PVC with subPath
2+
3+
input:
4+
pvcs:
5+
-
6+
apiVersion: v1
7+
kind: PersistentVolumeClaim
8+
metadata:
9+
name: test-pvc
10+
labels:
11+
controller.devfile.io/mount-to-devworkspace: "true"
12+
annotations:
13+
controller.devfile.io/mount-path: /data
14+
controller.devfile.io/mount-sub-path: my/subdirectory
15+
spec:
16+
accessModes:
17+
- ReadWriteOnce
18+
resources:
19+
requests:
20+
storage: 1Gi
21+
22+
output:
23+
volumes:
24+
- name: test-pvc
25+
persistentVolumeClaim:
26+
claimName: test-pvc
27+
volumeMounts:
28+
- name: test-pvc
29+
mountPath: /data
30+
subPath: my/subdirectory
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: Provisions automount PVC without subPath
2+
3+
input:
4+
pvcs:
5+
-
6+
apiVersion: v1
7+
kind: PersistentVolumeClaim
8+
metadata:
9+
name: test-pvc
10+
labels:
11+
controller.devfile.io/mount-to-devworkspace: "true"
12+
annotations:
13+
controller.devfile.io/mount-path: /data
14+
spec:
15+
accessModes:
16+
- ReadWriteOnce
17+
resources:
18+
requests:
19+
storage: 1Gi
20+
21+
output:
22+
volumes:
23+
- name: test-pvc
24+
persistentVolumeClaim:
25+
claimName: test-pvc
26+
volumeMounts:
27+
- name: test-pvc
28+
mountPath: /data

0 commit comments

Comments
 (0)