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

[release-v1.43] Bugfix - Correctly handle populated PVC #2325

Merged
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
24 changes: 13 additions & 11 deletions pkg/controller/datavolume-controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,7 @@ func (r *DatavolumeReconciler) Reconcile(_ context.Context, req reconcile.Reques
return reconcile.Result{}, err
}

pvcPopulated := false
// Get the pvc with the name specified in DataVolume.spec
pvc := &corev1.PersistentVolumeClaim{}
if err := r.client.Get(context.TODO(), types.NamespacedName{Namespace: datavolume.Namespace, Name: datavolume.Name}, pvc); err != nil {
Expand All @@ -449,8 +450,9 @@ func (r *DatavolumeReconciler) Reconcile(_ context.Context, req reconcile.Reques
} else {
// If the PVC is not controlled by this DataVolume resource, we should log
// a warning to the event recorder and return
pvcPopulated = pvcIsPopulated(pvc, datavolume)
if !metav1.IsControlledBy(pvc, datavolume) {
if pvcIsPopulated(pvc, datavolume) {
if pvcPopulated {
if err := r.addOwnerRef(pvc, datavolume); err != nil {
return reconcile.Result{}, err
}
Expand Down Expand Up @@ -481,13 +483,13 @@ func (r *DatavolumeReconciler) Reconcile(_ context.Context, req reconcile.Reques
r.sccs.StartController()
}

_, prePopulated := datavolume.Annotations[AnnPrePopulated]
_, dvPrePopulated := datavolume.Annotations[AnnPrePopulated]

if selectedCloneStrategy != NoClone {
return r.reconcileClone(log, datavolume, pvc, pvcSpec, transferName, prePopulated, selectedCloneStrategy)
return r.reconcileClone(log, datavolume, pvc, pvcSpec, transferName, dvPrePopulated, pvcPopulated, selectedCloneStrategy)
}

if !prePopulated {
if !dvPrePopulated {
if pvc == nil {
newPvc, err := r.createPvcForDatavolume(log, datavolume, pvcSpec)
if err != nil {
Expand Down Expand Up @@ -525,7 +527,7 @@ func (r *DatavolumeReconciler) Reconcile(_ context.Context, req reconcile.Reques

// Finally, we update the status block of the DataVolume resource to reflect the
// current state of the world
return r.reconcileDataVolumeStatus(datavolume, pvc)
return r.reconcileDataVolumeStatus(datavolume, pvc, selectedCloneStrategy)
}

func (r *DatavolumeReconciler) reconcileClone(log logr.Logger,
Expand All @@ -534,9 +536,10 @@ func (r *DatavolumeReconciler) reconcileClone(log logr.Logger,
pvcSpec *corev1.PersistentVolumeClaimSpec,
transferName string,
prePopulated bool,
pvcPopulated bool,
selectedCloneStrategy cloneStrategy) (reconcile.Result, error) {

if !prePopulated {
if !prePopulated && !pvcPopulated {
if pvc == nil {
if selectedCloneStrategy == SmartClone {
snapshotClassName, _ := r.getSnapshotClassForSmartClone(datavolume, pvcSpec)
Expand Down Expand Up @@ -606,7 +609,7 @@ func (r *DatavolumeReconciler) reconcileClone(log logr.Logger,

// Finally, we update the status block of the DataVolume resource to reflect the
// current state of the world
return r.reconcileDataVolumeStatus(datavolume, pvc)
return r.reconcileDataVolumeStatus(datavolume, pvc, selectedCloneStrategy)
}

func (r *DatavolumeReconciler) ensureExtendedToken(pvc *corev1.PersistentVolumeClaim) error {
Expand Down Expand Up @@ -2084,7 +2087,7 @@ func (r *DatavolumeReconciler) updateUploadStatusPhase(pvc *corev1.PersistentVol
}
}

func (r *DatavolumeReconciler) reconcileDataVolumeStatus(dataVolume *cdiv1.DataVolume, pvc *corev1.PersistentVolumeClaim) (reconcile.Result, error) {
func (r *DatavolumeReconciler) reconcileDataVolumeStatus(dataVolume *cdiv1.DataVolume, pvc *corev1.PersistentVolumeClaim, selectedCloneStrategy cloneStrategy) (reconcile.Result, error) {
dataVolumeCopy := dataVolume.DeepCopy()
var event DataVolumeEvent
result := reconcile.Result{}
Expand Down Expand Up @@ -2222,9 +2225,8 @@ func (r *DatavolumeReconciler) reconcileDataVolumeStatus(dataVolume *cdiv1.DataV
}
}

if dataVolumeCopy.Spec.Source.PVC != nil {
// XXX should probably be is status
addAnnotation(dataVolumeCopy, annCloneType, "network")
if selectedCloneStrategy != NoClone {
addAnnotation(dataVolumeCopy, annCloneType, cloneStrategyToCloneType(selectedCloneStrategy))
}

currentCond := make([]cdiv1.DataVolumeCondition, len(dataVolumeCopy.Status.Conditions))
Expand Down
14 changes: 7 additions & 7 deletions pkg/controller/datavolume-controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -878,7 +878,7 @@ var _ = Describe("All DataVolume Tests", func() {
dv.Status.Phase = current
err = reconciler.client.Update(context.TODO(), dv)
Expect(err).ToNot(HaveOccurred())
_, err = reconciler.reconcileDataVolumeStatus(dv, nil)
_, err = reconciler.reconcileDataVolumeStatus(dv, nil, NoClone)
Expect(err).ToNot(HaveOccurred())

dv = &cdiv1.DataVolume{}
Expand Down Expand Up @@ -921,7 +921,7 @@ var _ = Describe("All DataVolume Tests", func() {
pvc.Status.Phase = corev1.ClaimPending
err = reconciler.client.Update(context.TODO(), pvc)
Expect(err).ToNot(HaveOccurred())
_, err = reconciler.reconcileDataVolumeStatus(dv, pvc)
_, err = reconciler.reconcileDataVolumeStatus(dv, pvc, NoClone)
Expect(err).ToNot(HaveOccurred())
dv = &cdiv1.DataVolume{}
err = reconciler.client.Get(context.TODO(), types.NamespacedName{Name: "test-dv", Namespace: metav1.NamespaceDefault}, dv)
Expand Down Expand Up @@ -963,7 +963,7 @@ var _ = Describe("All DataVolume Tests", func() {
pvc.Status.Phase = corev1.ClaimPending
err = reconciler.client.Update(context.TODO(), pvc)
Expect(err).ToNot(HaveOccurred())
_, err = reconciler.reconcileDataVolumeStatus(dv, pvc)
_, err = reconciler.reconcileDataVolumeStatus(dv, pvc, NoClone)
Expect(err).ToNot(HaveOccurred())
dv = &cdiv1.DataVolume{}
err = reconciler.client.Get(context.TODO(), types.NamespacedName{Name: "test-dv", Namespace: metav1.NamespaceDefault}, dv)
Expand Down Expand Up @@ -1008,7 +1008,7 @@ var _ = Describe("All DataVolume Tests", func() {
pvc.Status.Phase = corev1.ClaimPending
err = reconciler.client.Update(context.TODO(), pvc)
Expect(err).ToNot(HaveOccurred())
_, err = reconciler.reconcileDataVolumeStatus(dv, pvc)
_, err = reconciler.reconcileDataVolumeStatus(dv, pvc, NoClone)
Expect(err).ToNot(HaveOccurred())
dv = &cdiv1.DataVolume{}
err = reconciler.client.Get(context.TODO(), types.NamespacedName{Name: "test-dv", Namespace: metav1.NamespaceDefault}, dv)
Expand Down Expand Up @@ -1047,7 +1047,7 @@ var _ = Describe("All DataVolume Tests", func() {
pvc.GetAnnotations()[AnnPodPhase] = string(corev1.PodSucceeded)
err = reconciler.client.Update(context.TODO(), pvc)
Expect(err).ToNot(HaveOccurred())
_, err = reconciler.reconcileDataVolumeStatus(dv, pvc)
_, err = reconciler.reconcileDataVolumeStatus(dv, pvc, NoClone)
Expect(err).ToNot(HaveOccurred())
dv = &cdiv1.DataVolume{}
err = reconciler.client.Get(context.TODO(), types.NamespacedName{Name: "test-dv", Namespace: metav1.NamespaceDefault}, dv)
Expand Down Expand Up @@ -1094,7 +1094,7 @@ var _ = Describe("All DataVolume Tests", func() {
pvc.GetAnnotations()[AnnPodPhase] = string(corev1.PodSucceeded)
err = reconciler.client.Update(context.TODO(), pvc)
Expect(err).ToNot(HaveOccurred())
_, err = reconciler.reconcileDataVolumeStatus(dv, pvc)
_, err = reconciler.reconcileDataVolumeStatus(dv, pvc, NoClone)
Expect(err).ToNot(HaveOccurred())
dv = &cdiv1.DataVolume{}
err = reconciler.client.Get(context.TODO(), types.NamespacedName{Name: "test-dv", Namespace: metav1.NamespaceDefault}, dv)
Expand Down Expand Up @@ -1154,7 +1154,7 @@ var _ = Describe("All DataVolume Tests", func() {
pvc.GetAnnotations()[extraAnnotations[i]] = extraAnnotations[i+1]
}

_, err = reconciler.reconcileDataVolumeStatus(dv, pvc)
_, err = reconciler.reconcileDataVolumeStatus(dv, pvc, NoClone)
Expect(err).ToNot(HaveOccurred())

dv = &cdiv1.DataVolume{}
Expand Down
27 changes: 27 additions & 0 deletions tests/cloner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,33 @@ var _ = Describe("all clone tests", func() {
verifyEvent(string(controller.ErrIncompatiblePVC), targetDv.Namespace, f)
})

It("should handle a pre populated PVC during clone", func() {
By(fmt.Sprintf("initializing target PVC %s", dataVolumeName))
sourcePodFillerName := fmt.Sprintf("%s-filler-pod", dataVolumeName)
annotations := map[string]string{"cdi.kubevirt.io/storage.populatedFor": dataVolumeName}
pvcDef := utils.NewPVCDefinition(dataVolumeName, "1G", annotations, nil)
_ = f.CreateAndPopulateSourcePVC(pvcDef, sourcePodFillerName, fillCommand+testFile+"; chmod 660 "+testBaseDir+testFile)

srcPpvcDef := utils.NewPVCDefinition("sourcepvcempty", "1G", nil, nil)
sourcePvc := f.CreateAndPopulateSourcePVC(srcPpvcDef, sourcePodFillerName, fillCommand+testFile+"; chmod 660 "+testBaseDir+testFile)

dataVolume := utils.NewDataVolumeForImageCloning(dataVolumeName, "1G",
sourcePvc.Namespace, sourcePvc.Name, sourcePvc.Spec.StorageClassName, sourcePvc.Spec.VolumeMode)
Expect(dataVolume).ToNot(BeNil())

By(fmt.Sprintf("creating new populated datavolume %s", dataVolume.Name))
dataVolume, err := utils.CreateDataVolumeFromDefinition(f.CdiClient, f.Namespace.Name, dataVolume)
Expect(err).ToNot(HaveOccurred())

Eventually(func() bool {
dv, err := f.CdiClient.CdiV1beta1().DataVolumes(f.Namespace.Name).Get(context.TODO(), dataVolume.Name, metav1.GetOptions{})
Expect(err).ToNot(HaveOccurred())
pvcName := dv.Annotations["cdi.kubevirt.io/storage.prePopulated"]
return pvcName == pvcDef.Name &&
dv.Status.Phase == cdiv1.Succeeded &&
string(dv.Status.Progress) == "N/A"
}, timeout, pollingInterval).Should(BeTrue(), "DV Should succeed with storage.prePopulated==pvcName")
})
}

Context("HostAssisted Clone", func() {
Expand Down
1 change: 1 addition & 0 deletions tests/datavolume_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1176,6 +1176,7 @@ var _ = Describe("[vendor:cnv-qe@redhat.com][level:component]DataVolume tests",
string(dv.Status.Progress) == "N/A"
}, timeout, pollingInterval).Should(BeTrue())
})

})

Describe("[rfe_id:1111][test_id:2001][crit:low][vendor:cnv-qe@redhat.com][level:component]Verify multiple blank disk creations in parallel", func() {
Expand Down