Skip to content

Commit 48d6cff

Browse files
Priti Desaipritidesai
authored andcommitted
delete persistent volume claim
PVCs can be specified using volumeClaimTemplates as part of a pipelineRun. The pipelineRun controller creates a new PVC using the specifications from the template. Once the pipelineRun is complete, the PVC exist to faciliate any analysis on the completed pod. Such PVCs are helpful but requires an extra cleanup if not needed. In the cases where pipelineRuns are kept for a long period of time, such PVC can waste resources. This commit introduces an option for the user such that the users can configure pipelineRun controller to delete such PVCs. There is no API change needed to support this cleanup. PipelineRun/TaskRun controller now reads a label from the volumeClaimTemplate to decide whether to delete PVC or not. Set the label " pvc-protection-finalizer" to "remove" to take advantage of this kind of cleanup. kind: PipelineRun metadata: generateName: pipeline-run- spec: workspaces: - name: source volumeClaimTemplate: metadata: labels: pvc-protection-finalizer: remove Closes #5776 Signed-off-by: pritidesai <pdesai@us.ibm.com>
1 parent 77c1698 commit 48d6cff

File tree

3 files changed

+53
-0
lines changed

3 files changed

+53
-0
lines changed

pkg/reconciler/pipelinerun/pipelinerun.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,10 @@ func (c *Reconciler) ReconcileKind(ctx context.Context, pr *v1beta1.PipelineRun)
224224

225225
if pr.IsDone() {
226226
pr.SetDefaults(ctx)
227+
228+
if err := c.pvcHandler.PurgeProtectionFromPersistentVolumeClaimsForWorkspaces(ctx, pr.Spec.Workspaces, *kmeta.NewControllerRef(pr), pr.Namespace); err != nil {
229+
logger.Errorf("Failed to update PersistentVolumeClaim for PipelineRun %s: %v", pr.Name, err)
230+
}
227231
err := c.cleanupAffinityAssistants(ctx, pr)
228232
if err != nil {
229233
logger.Errorf("Failed to delete StatefulSet for PipelineRun %s: %v", pr.Name, err)

pkg/reconciler/taskrun/taskrun.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,10 @@ func (c *Reconciler) ReconcileKind(ctx context.Context, tr *v1beta1.TaskRun) pkg
147147
return err
148148
}
149149

150+
if err := c.pvcHandler.PurgeProtectionFromPersistentVolumeClaimsForWorkspaces(ctx, tr.Spec.Workspaces, *kmeta.NewControllerRef(tr), tr.Namespace); err != nil {
151+
return fmt.Errorf("failed to update PersistentVolumeClaim for TaskRun %s: %v", tr.Name, err)
152+
}
153+
150154
return c.finishReconcileUpdateEmitEvents(ctx, tr, before, nil)
151155
}
152156

pkg/reconciler/volumeclaim/pvchandler.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,16 @@ package volumeclaim
1919
import (
2020
"context"
2121
"crypto/sha256"
22+
"encoding/json"
2223
"fmt"
2324

2425
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
2526
"go.uber.org/zap"
27+
"gomodules.xyz/jsonpatch/v2"
2628
corev1 "k8s.io/api/core/v1"
2729
apierrors "k8s.io/apimachinery/pkg/api/errors"
2830
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
31+
types "k8s.io/apimachinery/pkg/types"
2932
errorutils "k8s.io/apimachinery/pkg/util/errors"
3033
clientset "k8s.io/client-go/kubernetes"
3134
)
@@ -34,11 +37,13 @@ const (
3437
// ReasonCouldntCreateWorkspacePVC indicates that a Pipeline expects a workspace from a
3538
// volumeClaimTemplate but couldn't create a claim.
3639
ReasonCouldntCreateWorkspacePVC = "CouldntCreateWorkspacePVC"
40+
LabelPVCProtectionFinalizer = "pvc-protection-finalizer"
3741
)
3842

3943
// PvcHandler is used to create PVCs for workspaces
4044
type PvcHandler interface {
4145
CreatePersistentVolumeClaimsForWorkspaces(ctx context.Context, wb []v1beta1.WorkspaceBinding, ownerReference metav1.OwnerReference, namespace string) error
46+
PurgeProtectionFromPersistentVolumeClaimsForWorkspaces(ctx context.Context, wb []v1beta1.WorkspaceBinding, ownerReference metav1.OwnerReference, namespace string) error
4247
}
4348

4449
type defaultPVCHandler struct {
@@ -81,6 +86,46 @@ func (c *defaultPVCHandler) CreatePersistentVolumeClaimsForWorkspaces(ctx contex
8186
return errorutils.NewAggregate(errs)
8287
}
8388

89+
func (c *defaultPVCHandler) PurgeProtectionFromPersistentVolumeClaimsForWorkspaces(ctx context.Context, wb []v1beta1.WorkspaceBinding, ownerReference metav1.OwnerReference, namespace string) error {
90+
var errs []error
91+
for _, claim := range getPersistentVolumeClaims(wb, ownerReference, namespace) {
92+
p, err := c.clientset.CoreV1().PersistentVolumeClaims(claim.Namespace).Get(ctx, claim.Name, metav1.GetOptions{})
93+
if err != nil {
94+
errs = append(errs, fmt.Errorf("failed to get the PVC %s: %w", claim.Name, err))
95+
}
96+
// the label to remove PVC protection "pvc-protection-finalizer" is set to "remove"
97+
if err == nil && p != nil && p.Labels[LabelPVCProtectionFinalizer] == "remove" {
98+
err = c.clientset.CoreV1().PersistentVolumeClaims(claim.Namespace).Delete(ctx, claim.Name, metav1.DeleteOptions{})
99+
if err != nil {
100+
errs = append(errs, fmt.Errorf("failed to delete the PVC %s: %w", claim.Name, err))
101+
}
102+
103+
// get the list of existing finalizers and drop `pvc-protection` if exists
104+
var finalizers []string
105+
for _, f := range p.ObjectMeta.Finalizers {
106+
if f == "kubernetes.io/pvc-protection" {
107+
continue
108+
}
109+
finalizers = append(finalizers, f)
110+
}
111+
112+
// prepare data to remove pvc-protection from the list of finalizers
113+
removeFinalizerBytes, err := json.Marshal([]jsonpatch.JsonPatchOperation{{
114+
Path: "/metadata/finalizers",
115+
Operation: "replace",
116+
Value: finalizers,
117+
}})
118+
119+
// patch the existing PVC to update the finalizers
120+
_, err = c.clientset.CoreV1().PersistentVolumeClaims(claim.Namespace).Patch(ctx, claim.Name, types.JSONPatchType, removeFinalizerBytes, metav1.PatchOptions{})
121+
if err != nil {
122+
errs = append(errs, fmt.Errorf("failed to patch the PVC %s: %w", claim.Name, err))
123+
}
124+
}
125+
}
126+
return errorutils.NewAggregate(errs)
127+
}
128+
84129
func getPersistentVolumeClaims(workspaceBindings []v1beta1.WorkspaceBinding, ownerReference metav1.OwnerReference, namespace string) map[string]*corev1.PersistentVolumeClaim {
85130
claims := make(map[string]*corev1.PersistentVolumeClaim)
86131
for _, workspaceBinding := range workspaceBindings {

0 commit comments

Comments
 (0)