Skip to content

Commit 4a5edbf

Browse files
committed
Do not fail PipelineRun if pvc creation error is because of exceeded quotas
In case of the PVC creation (from volumeclaimtemplate) is due to a quota error (quota exceeded), do not fail with a permanent error, and instead mark the PipelineRun as pending. Once there is some quota available back, it will be able to start. Signed-off-by: Vincent Demeester <vdemeest@redhat.com>
1 parent d504890 commit 4a5edbf

File tree

3 files changed

+23
-5
lines changed

3 files changed

+23
-5
lines changed

pkg/reconciler/pipelinerun/affinity_assistant.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ const (
5050
)
5151

5252
var (
53-
ErrPvcCreationFailed = errors.New("PVC creation error")
53+
ErrPvcCreationFailed = volumeclaim.ErrPvcCreationFailed
54+
ErrPvcCreationFailedRetryable = volumeclaim.ErrPvcCreationFailedRetryable
5455
ErrAffinityAssistantCreationFailed = errors.New("Affinity Assistant creation error")
5556
)
5657

@@ -95,7 +96,7 @@ func (c *Reconciler) createOrUpdateAffinityAssistantsAndPVCs(ctx context.Context
9596
// To support PVC auto deletion at pipelinerun deletion time, the OwnerReference of the PVCs should be set to the owning pipelinerun instead of the StatefulSets,
9697
// so we create PVCs from PipelineRuns' VolumeClaimTemplate and pass the PVCs to the Affinity Assistant StatefulSet for volume scheduling.
9798
if err := c.pvcHandler.CreatePVCFromVolumeClaimTemplate(ctx, workspace, *kmeta.NewControllerRef(pr), pr.Namespace); err != nil {
98-
return fmt.Errorf("%w: %v", ErrPvcCreationFailed, err) //nolint:errorlint
99+
return err
99100
}
100101
aaName := GetAffinityAssistantName(workspace.Name, pr.Name)
101102
if err := c.createOrUpdateAffinityAssistant(ctx, aaName, pr, nil, []string{claimTemplate.Name}, unschedulableNodes); err != nil {
@@ -114,7 +115,7 @@ func (c *Reconciler) createOrUpdateAffinityAssistantsAndPVCs(ctx context.Context
114115
case aa.AffinityAssistantDisabled:
115116
for _, workspace := range claimTemplateToWorkspace {
116117
if err := c.pvcHandler.CreatePVCFromVolumeClaimTemplate(ctx, workspace, *kmeta.NewControllerRef(pr), pr.Namespace); err != nil {
117-
return fmt.Errorf("%w: %v", ErrPvcCreationFailed, err) //nolint:errorlint
118+
return err
118119
}
119120
}
120121
}

pkg/reconciler/pipelinerun/pipelinerun.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,10 @@ func (c *Reconciler) reconcile(ctx context.Context, pr *v1.PipelineRun, getPipel
755755
pr.Status.MarkFailed(volumeclaim.ReasonCouldntCreateWorkspacePVC,
756756
"Failed to create PVC for PipelineRun %s/%s correctly: %s",
757757
pr.Namespace, pr.Name, err)
758+
case errors.Is(err, ErrPvcCreationFailedRetryable):
759+
logger.Errorf("Failed to create PVC for PipelineRun %s: %v", pr.Name, err)
760+
pr.Status.MarkRunning(ReasonPending, "Waiting for PVC creation to succeed: %v", err)
761+
return err // not a permanent error, will requeue
758762
case errors.Is(err, ErrAffinityAssistantCreationFailed):
759763
logger.Errorf("Failed to create affinity assistant StatefulSet for PipelineRun %s: %v", pr.Name, err)
760764
pr.Status.MarkFailed(ReasonCouldntCreateOrUpdateAffinityAssistantStatefulSet,

pkg/reconciler/volumeclaim/pvchandler.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ import (
2121
"crypto/sha256"
2222
"encoding/hex"
2323
"encoding/json"
24+
"errors"
2425
"fmt"
26+
"strings"
2527

2628
v1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1"
2729
"go.uber.org/zap"
@@ -39,6 +41,11 @@ const (
3941
ReasonCouldntCreateWorkspacePVC = "CouldntCreateWorkspacePVC"
4042
)
4143

44+
var (
45+
ErrPvcCreationFailed = errors.New("PVC creation error")
46+
ErrPvcCreationFailedRetryable = errors.New("PVC creation error, retryable")
47+
)
48+
4249
// PvcHandler is used to create PVCs for workspaces
4350
type PvcHandler interface {
4451
CreatePVCFromVolumeClaimTemplate(ctx context.Context, wb v1.WorkspaceBinding, ownerReference metav1.OwnerReference, namespace string) error
@@ -73,14 +80,20 @@ func (c *defaultPVCHandler) CreatePVCFromVolumeClaimTemplate(ctx context.Context
7380
if apierrors.IsAlreadyExists(err) {
7481
c.logger.Infof("Tried to create PersistentVolumeClaim %s in namespace %s, but it already exists",
7582
claim.Name, claim.Namespace)
83+
} else if apierrors.IsForbidden(err) {
84+
if strings.Contains(err.Error(), "exceeded quota") {
85+
// This is a retry-able error
86+
return fmt.Errorf("%w: %v", ErrPvcCreationFailedRetryable, err)
87+
}
88+
return fmt.Errorf("%w for %s: %w", ErrPvcCreationFailed, claim.Name, err)
7689
} else {
77-
return fmt.Errorf("failed to create PVC %s: %w", claim.Name, err)
90+
return fmt.Errorf("%w for %s: %w", ErrPvcCreationFailed, claim.Name, err)
7891
}
7992
} else {
8093
c.logger.Infof("Created PersistentVolumeClaim %s in namespace %s", claim.Name, claim.Namespace)
8194
}
8295
case err != nil:
83-
return fmt.Errorf("failed to retrieve PVC %s: %w", claim.Name, err)
96+
return fmt.Errorf("%w: failed to retrieve PVC %s: %w", ErrPvcCreationFailed, claim.Name, err)
8497
}
8598

8699
return nil

0 commit comments

Comments
 (0)