Skip to content

Commit be8b2d5

Browse files
committed
feat: Use labels on PVCs for better reconciling
Signed-off-by: Mykhailo Kuznietsov <[email protected]>
1 parent 04f5369 commit be8b2d5

File tree

4 files changed

+51
-12
lines changed

4 files changed

+51
-12
lines changed

controllers/workspace/eventhandlers.go

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ package controllers
1515

1616
import (
1717
"context"
18+
"fmt"
1819

1920
dw "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
2021
wkspConfig "github.com/devfile/devworkspace-operator/pkg/config"
@@ -47,7 +48,14 @@ func dwRelatedPodsHandler(obj client.Object) []reconcile.Request {
4748
}
4849

4950
func (r *DevWorkspaceReconciler) dwPVCHandler(obj client.Object) []reconcile.Request {
51+
if obj.GetDeletionTimestamp() == nil {
52+
// Do not reconcile unless PVC is being deleted.
53+
return []reconcile.Request{}
54+
}
55+
5056
// Check if PVC is owned by a DevWorkspace (per-workspace storage case)
57+
// TODO: Ensure all new and existing PVC's get the `controller.devfile.io/devworkspace_pvc_type` label.
58+
// See: https://github.com/devfile/devworkspace-operator/issues/1250
5159
for _, ownerref := range obj.GetOwnerReferences() {
5260
if ownerref.Kind != "DevWorkspace" {
5361
continue
@@ -62,26 +70,49 @@ func (r *DevWorkspaceReconciler) dwPVCHandler(obj client.Object) []reconcile.Req
6270
}
6371
}
6472

65-
// TODO: Label PVCs used for workspace storage so that they can be cleaned up if non-default name is used.
66-
// Otherwise, check if common PVC is deleted to make sure all DevWorkspaces see it happen
67-
if obj.GetName() != wkspConfig.GetGlobalConfig().Workspace.PVCName || obj.GetDeletionTimestamp() == nil {
68-
// We're looking for a deleted common PVC
69-
return []reconcile.Request{}
73+
pvcLabel := obj.GetLabels()[constants.DevWorkspacePVCTypeLabel]
74+
75+
// TODO: This check is for legacy reasons as existing PVCs might not have the `controller.devfile.io/devworkspace_pvc_type` label.
76+
// Remove once https://github.com/devfile/devworkspace-operator/issues/1250 is resolved
77+
if pvcLabel == "" {
78+
if obj.GetName() != wkspConfig.GetGlobalConfig().Workspace.PVCName {
79+
// No need to reconcile if PVC doesn't have a PVC type label
80+
// and it doesn't have a name of PVC from global config.
81+
return []reconcile.Request{}
82+
}
7083
}
84+
7185
dwList := &dw.DevWorkspaceList{}
7286
if err := r.Client.List(context.Background(), dwList, &client.ListOptions{Namespace: obj.GetNamespace()}); err != nil {
7387
return []reconcile.Request{}
7488
}
7589
var reconciles []reconcile.Request
90+
7691
for _, workspace := range dwList.Items {
7792
storageType := workspace.Spec.Template.Attributes.GetString(constants.DevWorkspaceStorageTypeAttribute, nil)
7893
if storageType == constants.CommonStorageClassType || storageType == constants.PerUserStorageClassType || storageType == "" {
79-
reconciles = append(reconciles, reconcile.Request{
80-
NamespacedName: types.NamespacedName{
81-
Name: workspace.GetName(),
82-
Namespace: workspace.GetNamespace(),
83-
},
84-
})
94+
95+
// Determine workspaces to reconcile that use the current common PVC.
96+
// Workspaces can either use the common PVC where the PVC name
97+
// is coming from the global config, or from an external config the workspace might use
98+
workspacePVCName := wkspConfig.GetGlobalConfig().Workspace.PVCName
99+
100+
if workspace.Spec.Template.Attributes.Exists(constants.ExternalDevWorkspaceConfiguration) {
101+
externalConfig, err := wkspConfig.ResolveConfigForWorkspace(&workspace, r.Client)
102+
if err != nil {
103+
r.Log.Info(fmt.Sprintf("Couldn't resolve PVC name for workspace '%s' in namespace '%s', using PVC name '%s' from global config instead: %s.", workspace.Name, workspace.Namespace, workspacePVCName, err.Error()))
104+
} else {
105+
workspacePVCName = externalConfig.Workspace.PVCName
106+
}
107+
}
108+
if obj.GetName() == workspacePVCName {
109+
reconciles = append(reconciles, reconcile.Request{
110+
NamespacedName: types.NamespacedName{
111+
Name: workspace.GetName(),
112+
Namespace: workspace.GetNamespace(),
113+
},
114+
})
115+
}
85116
}
86117
}
87118
return reconciles

pkg/constants/metadata.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ const (
2020
// DevWorkspaceIDLabel is the label key to store workspace identifier
2121
DevWorkspaceIDLabel = "controller.devfile.io/devworkspace_id"
2222

23+
// DevWorkspacePVCTypeLabel is the label key to identify PVCs used by DevWorkspaces and indicate their storage strategy.
24+
DevWorkspacePVCTypeLabel = "controller.devfile.io/devworkspace_pvc_type"
25+
2326
// WorkspaceIdOverrideAnnotation is an annotation that can be applied to DevWorkspaces
2427
// to override the default DevWorkspace ID assigned by the Operator. Is only respected
2528
// when a DevWorkspace is created. Once a DevWorkspace has an ID set, it cannot be changed.

pkg/provision/storage/perWorkspaceStorage.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ func syncPerWorkspacePVC(workspace *common.DevWorkspaceWithConfig, clusterAPI sy
227227
pvc.Labels = map[string]string{}
228228
}
229229
pvc.Labels[constants.DevWorkspaceIDLabel] = workspace.Status.DevWorkspaceId
230+
pvc.Labels[constants.DevWorkspacePVCTypeLabel] = constants.PerWorkspaceStorageClassType
230231

231232
if err := controllerutil.SetControllerReference(workspace.DevWorkspace, pvc, clusterAPI.Scheme); err != nil {
232233
return nil, err

pkg/provision/storage/shared.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ func WorkspaceNeedsStorage(workspace *dw.DevWorkspaceTemplateSpec) bool {
6161
}
6262

6363
func getPVCSpec(name, namespace string, storageClass *string, size resource.Quantity) (*corev1.PersistentVolumeClaim, error) {
64-
64+
6565
return &corev1.PersistentVolumeClaim{
6666
ObjectMeta: metav1.ObjectMeta{
6767
Name: name,
@@ -103,6 +103,10 @@ func syncCommonPVC(namespace string, config *v1alpha1.OperatorConfiguration, clu
103103
if err != nil {
104104
return nil, err
105105
}
106+
if pvc.Labels == nil {
107+
pvc.Labels = map[string]string{}
108+
}
109+
pvc.Labels[constants.DevWorkspacePVCTypeLabel] = constants.PerUserStorageClassType
106110
currObject, err := sync.SyncObjectWithCluster(pvc, clusterAPI)
107111
switch t := err.(type) {
108112
case nil:

0 commit comments

Comments
 (0)