Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Restore err in Finalizing PV Patch phase if SC VolumeBindingMode is WaitForFirstConsumer #7869

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelogs/unreleased/7869-shubham-pampattiwar
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add Restore err in Finalizing PV Patch phase if SC VolumeBindingMode is WaitForFirstConsumer
25 changes: 23 additions & 2 deletions pkg/controller/restore_finalizer_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/clock"

storagev1api "k8s.io/api/storage/v1"

"github.com/vmware-tanzu/velero/internal/hook"
"github.com/vmware-tanzu/velero/internal/volume"
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
Expand Down Expand Up @@ -291,10 +293,11 @@

log := ctx.logger.WithField("PVC", volInfo.PVCName).WithField("PVCNamespace", restoredNamespace)
log.Debug("patching dynamic PV is in progress")
pvc := &v1.PersistentVolumeClaim{}
pv := &v1.PersistentVolume{}

err := wait.PollUntilContextTimeout(context.Background(), 10*time.Second, PVPatchMaximumDuration, true, func(context.Context) (bool, error) {
// wait for PVC to be bound
pvc := &v1.PersistentVolumeClaim{}
err := ctx.crClient.Get(context.Background(), client.ObjectKey{Name: volInfo.PVCName, Namespace: restoredNamespace}, pvc)
if apierrors.IsNotFound(err) {
log.Debug("error not finding PVC")
Expand All @@ -311,7 +314,6 @@

// wait for PV to be bound
pvName := pvc.Spec.VolumeName
pv := &v1.PersistentVolume{}
err = ctx.crClient.Get(context.Background(), client.ObjectKey{Name: pvName}, pv)
if apierrors.IsNotFound(err) {
log.Debugf("error not finding PV: %s", pvName)
Expand Down Expand Up @@ -347,6 +349,25 @@
})

if err != nil {
// If a timeout error occurs, check if the PVC is in the pending state and if the storage class used by the PVC
// has VolumeBindingMode set to WaitForFirstConsumer. This situation may arise if the user has excluded pods from the backup.
// In such cases, log a specific error message to inform the user that pods are required for the WaitForFirstConsumer binding mode.
if errors.Is(err, context.DeadlineExceeded) {
// check if pv is not nil and has a pending status after timeout
if pvc != nil && pvc.Status.Phase == v1.ClaimPending {

Check warning on line 357 in pkg/controller/restore_finalizer_controller.go

View check run for this annotation

Codecov / codecov/patch

pkg/controller/restore_finalizer_controller.go#L357

Added line #L357 was not covered by tests
// check if storage class used for the PV has VolumeBindingMode as WaitForFirstConsumer
scName := *pvc.Spec.StorageClassName
sc := &storagev1api.StorageClass{}
err = ctx.crClient.Get(context.Background(), client.ObjectKey{Name: scName}, sc)
if err != nil {
errs.Add(restoredNamespace, err)

Check warning on line 363 in pkg/controller/restore_finalizer_controller.go

View check run for this annotation

Codecov / codecov/patch

pkg/controller/restore_finalizer_controller.go#L359-L363

Added lines #L359 - L363 were not covered by tests
}
if *sc.VolumeBindingMode == storagev1api.VolumeBindingWaitForFirstConsumer {
ctx.logger.WithError(err).Errorf("StorageClass %s used by PV %s has VolumeBindingMode as WaitForFirstConsumer, you may need to be change it to Immediate if pods are excluded from backup", scName, pv.Name)
errs.Add(restoredNamespace, fmt.Errorf("StorageClass %s used by PV %s has VolumeBindingMode as WaitForFirstConsumer, you may need to be change it to Immediate if pods are excluded from backup", scName, pv.Name))

Check warning on line 367 in pkg/controller/restore_finalizer_controller.go

View check run for this annotation

Codecov / codecov/patch

pkg/controller/restore_finalizer_controller.go#L365-L367

Added lines #L365 - L367 were not covered by tests
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not always possible or desirable to change the binding mode of a storage class. Consider local storage which really needs WFFC in order to function correctly. I think it's quite important to ensure that velero works with WaitForFirstConsumer storage.

}
}
}
err = fmt.Errorf("fail to patch dynamic PV, err: %s, PVC: %s, PV: %s", err, volInfo.PVCName, volInfo.PVName)
ctx.logger.WithError(errors.WithStack((err))).Error("err patching dynamic PV using volume info")
resultLock.Lock()
Expand Down
Loading