Skip to content

Commit a73ab1e

Browse files
authored
fix: bound pv failed when doing rebuild-instance with multi times (#9629)
1 parent a42c227 commit a73ab1e

1 file changed

Lines changed: 51 additions & 35 deletions

File tree

pkg/operations/rebuild_instance_inplace.go

Lines changed: 51 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ func (inPlaceHelper *inplaceRebuildHelper) rebuildSourcePVCsAndRecreateInstance(
353353
tmpPVC := &corev1.PersistentVolumeClaim{}
354354
_ = cli.Get(reqCtx.Ctx, types.NamespacedName{Name: v.Name, Namespace: v.Namespace}, tmpPVC)
355355
if tmpPVC.UID == "" {
356-
// if the tmp pvc not exists in k8s, replace with v.
356+
// if the tmp pvc not exists in k8s, replace with the built pvc.
357357
tmpPVC = v
358358
}
359359
// 1. get the restored pv
@@ -369,25 +369,26 @@ func (inPlaceHelper *inplaceRebuildHelper) rebuildSourcePVCsAndRecreateInstance(
369369
if _, ok := pv.Annotations[rebuildFromAnnotation]; !ok {
370370
if pv.Labels[rebuildTmpPVCNameLabel] != tmpPVC.Name {
371371
// 2. retain and label the pv with 'rebuildTmpPVCNameLabel'
372-
if err = inPlaceHelper.retainAndLabelPV(reqCtx, cli, pv, tmpPVC); err != nil {
372+
if err = inPlaceHelper.retainAndAnnotatePV(reqCtx, cli, opsRequest.Name, pv, tmpPVC, sourcePvc); err != nil {
373373
return err
374374
}
375375
}
376-
// 3. cleanup the tmp pvc firstly.
377-
if err = inPlaceHelper.cleanupTmpPVC(reqCtx, cli, tmpPVC); err != nil {
378-
return err
379-
}
380-
// 4. release and annotate the pv with ['rebuildFromAnnotation', 'sourcePVReclaimPolicyAnnotation'].
381-
if err = inPlaceHelper.releasePV(reqCtx, cli, sourcePvc, pv, opsRequest.Name); err != nil {
382-
return err
383-
}
376+
}
377+
// 3. cleanup the tmp pvc firstly.
378+
if err = inPlaceHelper.cleanupTmpPVC(reqCtx, cli, tmpPVC); err != nil {
379+
return err
384380
}
385381
// set volumeName to tmp pvc, it will be used when recreating the source pvc.
386382
tmpPVC.Spec.VolumeName = pv.Name
387-
// 5. recreate the source pvc.
383+
// 4. recreate the source pvc.
388384
if err = inPlaceHelper.recreateSourcePVC(reqCtx, cli, tmpPVC, sourcePvc, opsRequest.Name); err != nil {
389385
return err
390386
}
387+
388+
// 5. rebound the pv to the source pvc.
389+
if err = inPlaceHelper.reboundPV(reqCtx, cli, sourcePvc, pv, opsRequest.Name); err != nil {
390+
return err
391+
}
391392
// 6. revert the reclaim policy of the pv.
392393
if err = inPlaceHelper.revertReclaimPolicy(reqCtx, cli, pv); err != nil {
393394
return err
@@ -442,10 +443,12 @@ func (inPlaceHelper *inplaceRebuildHelper) getRestoredPV(reqCtx intctrlutil.Requ
442443
return pv, nil
443444
}
444445

445-
func (inPlaceHelper *inplaceRebuildHelper) retainAndLabelPV(reqCtx intctrlutil.RequestCtx,
446+
func (inPlaceHelper *inplaceRebuildHelper) retainAndAnnotatePV(reqCtx intctrlutil.RequestCtx,
446447
cli client.Client,
448+
opsRequestName string,
447449
pv *corev1.PersistentVolume,
448-
tmpPVC *corev1.PersistentVolumeClaim) error {
450+
tmpPVC *corev1.PersistentVolumeClaim,
451+
sourcePvc *corev1.PersistentVolumeClaim) error {
449452
patchPV := client.MergeFrom(pv.DeepCopy())
450453
// Examine the claimRef for the PV and see if it's bound to the correct PVC
451454
claimRef := pv.Spec.ClaimRef
@@ -459,12 +462,29 @@ func (inPlaceHelper *inplaceRebuildHelper) retainAndLabelPV(reqCtx intctrlutil.R
459462
}
460463
// record the tmp pvc name to the pv labels. used for idempotent reentry if occurs error.
461464
pv.Labels[rebuildTmpPVCNameLabel] = tmpPVC.Name
465+
466+
// annotate the pv with ['rebuildFromAnnotation', 'sourcePVReclaimPolicyAnnotation'].
467+
if pv.Annotations == nil {
468+
pv.Annotations = map[string]string{}
469+
}
470+
pv.Annotations[rebuildFromAnnotation] = opsRequestName
471+
if pv.Annotations[sourcePVReclaimPolicyAnnotation] == "" {
472+
// obtain the reclaim policy from the source pv.
473+
sourcePV := &corev1.PersistentVolume{}
474+
if err := cli.Get(reqCtx.Ctx, client.ObjectKey{Name: sourcePvc.Spec.VolumeName}, sourcePV); err != nil {
475+
return err
476+
}
477+
pv.Annotations[sourcePVReclaimPolicyAnnotation] = string(sourcePV.Spec.PersistentVolumeReclaimPolicy)
478+
}
462479
return cli.Patch(reqCtx.Ctx, pv, patchPV)
463480
}
464481

465482
func (inPlaceHelper *inplaceRebuildHelper) cleanupTmpPVC(reqCtx intctrlutil.RequestCtx,
466483
cli client.Client,
467484
tmpPVC *corev1.PersistentVolumeClaim) error {
485+
if tmpPVC.UID == "" || tmpPVC.DeletionTimestamp != nil {
486+
return nil
487+
}
468488
// if the tmp pvc exists, delete it.
469489
if err := intctrlutil.BackgroundDeleteObject(cli, reqCtx.Ctx, tmpPVC); err != nil {
470490
return err
@@ -478,6 +498,7 @@ func (inPlaceHelper *inplaceRebuildHelper) recreateSourcePVC(reqCtx intctrlutil.
478498
tmpPVC,
479499
sourcePvc *corev1.PersistentVolumeClaim,
480500
opsRequestName string) error {
501+
481502
// if the pvc is rebuilt by current opsRequest, return.
482503
if sourcePvc.Annotations[rebuildFromAnnotation] == opsRequestName {
483504
return nil
@@ -495,41 +516,36 @@ func (inPlaceHelper *inplaceRebuildHelper) recreateSourcePVC(reqCtx intctrlutil.
495516
// 3. recreate the pvc with restored PV.
496517
newPVC := &corev1.PersistentVolumeClaim{
497518
ObjectMeta: metav1.ObjectMeta{
498-
Name: sourcePvc.Name,
499-
Namespace: tmpPVC.Namespace,
500-
Labels: tmpPVC.Labels,
501-
Annotations: map[string]string{
502-
rebuildFromAnnotation: opsRequestName,
503-
},
519+
Name: sourcePvc.Name,
520+
Namespace: tmpPVC.Namespace,
521+
Labels: tmpPVC.Labels,
522+
Annotations: sourcePvc.Annotations,
504523
},
505524
Spec: tmpPVC.Spec,
506525
}
507526
// merge the annotations of the source pvc.
508-
intctrlutil.MergeMetadataMapInplace(sourcePvc.Annotations, &newPVC.Annotations)
527+
if newPVC.Annotations == nil {
528+
newPVC.Annotations = map[string]string{}
529+
}
530+
newPVC.Annotations[rebuildFromAnnotation] = opsRequestName
509531
return cli.Create(reqCtx.Ctx, newPVC)
510532
}
511533

512-
// releasePV releases the persistentVolume by resetting `claimRef`.
513-
func (inPlaceHelper *inplaceRebuildHelper) releasePV(reqCtx intctrlutil.RequestCtx,
534+
// reboundPV rebounds the PV to the source PVC if it is bound to another PVC.
535+
func (inPlaceHelper *inplaceRebuildHelper) reboundPV(reqCtx intctrlutil.RequestCtx,
514536
cli client.Client,
515537
sourcePvc *corev1.PersistentVolumeClaim,
516538
pv *corev1.PersistentVolume,
517539
opsRequestName string) error {
518-
patchPV := client.MergeFrom(pv.DeepCopy())
519-
pv.Spec.ClaimRef = nil
520-
if pv.Annotations == nil {
521-
pv.Annotations = map[string]string{}
540+
// if the pvc is not rebuilt by current opsRequest, return.
541+
if sourcePvc.Annotations[rebuildFromAnnotation] != opsRequestName {
542+
return nil
522543
}
523-
pv.Annotations[rebuildFromAnnotation] = opsRequestName
524-
if pv.Annotations[sourcePVReclaimPolicyAnnotation] == "" {
525-
// obtain the reclaim policy from the source pv.
526-
sourcePV := &corev1.PersistentVolume{}
527-
if err := cli.Get(reqCtx.Ctx, client.ObjectKey{Name: sourcePvc.Spec.VolumeName}, sourcePV); err != nil {
528-
return err
529-
}
530-
pv.Annotations[sourcePVReclaimPolicyAnnotation] = string(sourcePV.Spec.PersistentVolumeReclaimPolicy)
544+
if pv.Spec.ClaimRef == nil || pv.Spec.ClaimRef.UID == sourcePvc.UID {
545+
return nil
531546
}
532-
return cli.Patch(reqCtx.Ctx, pv, patchPV)
547+
pv.Spec.ClaimRef = nil
548+
return cli.Update(reqCtx.Ctx, pv)
533549
}
534550

535551
func (inPlaceHelper *inplaceRebuildHelper) revertReclaimPolicy(reqCtx intctrlutil.RequestCtx,

0 commit comments

Comments
 (0)