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

Respect wffc override for blank block disks #2917

Merged
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
4 changes: 4 additions & 0 deletions cmd/cdi-importer/importer.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,10 @@ func handleEmptyImage(contentType string, imageSize string, availableDestSpace i
var preallocationApplied bool

if contentType == string(cdiv1.DataVolumeKubeVirt) {
if volumeMode == v1.PersistentVolumeBlock && !preallocation {
klog.V(1).Infoln("Blank block without preallocation is exactly an empty PVC, done populating")
return nil
}
createBlankImage(imageSize, availableDestSpace, preallocation, volumeMode, filesystemOverhead)
preallocationApplied = preallocation
} else {
Expand Down
14 changes: 0 additions & 14 deletions pkg/controller/import-controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,20 +215,6 @@ func (r *ImportReconciler) Reconcile(_ context.Context, req reconcile.Request) (
return reconcile.Result{}, nil
}

// In case this is a request to create a blank disk on a block device, we do not create a pod.
// we just mark the DV as successful
volumeMode := cc.GetVolumeMode(pvc)
if volumeMode == corev1.PersistentVolumeBlock && pvc.GetAnnotations()[cc.AnnSource] == cc.SourceNone && pvc.GetAnnotations()[cc.AnnPreallocationRequested] != "true" {
log.V(1).Info("attempting to create blank disk for block mode, this is a no-op, marking pvc with pod-phase succeeded")
if pvc.GetAnnotations() == nil {
pvc.SetAnnotations(make(map[string]string, 0))
}
pvc.GetAnnotations()[cc.AnnPodPhase] = string(corev1.PodSucceeded)
if err := r.updatePVC(pvc, log); err != nil {
return reconcile.Result{}, errors.WithMessage(err, fmt.Sprintf("could not update pvc %q annotation and/or label", pvc.Name))
}
return reconcile.Result{}, nil
}
Copy link

Choose a reason for hiding this comment

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

I don't get why this is not needed any more from looking at the CL. Could you please clarify why?
Does this logic work for both populator case and non-populator case?

Copy link
Member

Choose a reason for hiding this comment

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

Essentially this was a short cut for one particular case (blank disk, no preallocation) and removing it will cause a pod to be created, but per the rest of this PR, that pod won't do anything. What it will do is follow the rest of the logic when creating a population pod, which should work for both populator and non populator cases, as well as HonorWaitForFirstConsumer set or not.

return r.reconcilePvc(pvc, log)
}

Expand Down
17 changes: 16 additions & 1 deletion pkg/controller/import-controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,22 @@ var _ = Describe("ImportConfig Controller reconcile loop", func() {
})

It("Should succeed and be marked complete, if creating a block PVC with source none", func() {
reconciler = createImportReconciler(createBlockPvc("testPvc1", "block", map[string]string{cc.AnnSource: cc.SourceNone}, nil))
pvc := createBlockPvc("testPvc1", "block", map[string]string{cc.AnnSource: cc.SourceNone}, nil)
pod := cc.CreateImporterTestPod(pvc, "testPvc1", nil)
pod.Status = corev1.PodStatus{
Phase: corev1.PodSucceeded,
ContainerStatuses: []v1.ContainerStatus{
{
State: v1.ContainerState{
Terminated: &v1.ContainerStateTerminated{
Message: "Import Completed",
Reason: "Reason",
},
},
},
},
}
reconciler = createImportReconciler(pvc, pod)
_, err := reconciler.Reconcile(context.TODO(), reconcile.Request{NamespacedName: types.NamespacedName{Name: "testPvc1", Namespace: "block"}})
Expect(err).ToNot(HaveOccurred())
resultPvc := &corev1.PersistentVolumeClaim{}
Expand Down
21 changes: 12 additions & 9 deletions tests/import_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -587,31 +587,34 @@ var _ = Describe("Importer Test Suite-Block_device", func() {

})

It("[test_id:4972]Should create blank raw image for block PV", func() {
DescribeTable("Should create blank raw image for block PV", func(consumer bool) {
if !f.IsBlockVolumeStorageClassAvailable() {
Skip("Storage Class for block volume is not available")
}
dv := utils.NewDataVolumeForBlankRawImageBlock("create-blank-image-to-block-pvc", "500Mi", f.BlockSCName)
if !consumer {
controller.AddAnnotation(dv, controller.AnnImmediateBinding, "true")
}
dv, err = utils.CreateDataVolumeFromDefinition(f.CdiClient, f.Namespace.Name, dv)
Expect(err).ToNot(HaveOccurred())

By("verifying pvc was created")
pvc, err := utils.WaitForPVC(f.K8sClient, dv.Namespace, dv.Name)
Expect(err).ToNot(HaveOccurred())
f.ForceBindIfWaitForFirstConsumer(pvc)
if consumer {
f.ForceBindIfWaitForFirstConsumer(pvc)
}

By("Waiting for import to be completed")
err = utils.WaitForDataVolumePhase(f, f.Namespace.Name, cdiv1.Succeeded, dv.Name)
Expect(err).ToNot(HaveOccurred(), "Datavolume not in phase succeeded in time")

By("Verifying a message was printed to indicate a request for a blank disk on a block device")
Eventually(func() bool {
log, err := f.RunKubectlCommand("logs", f.ControllerPod.Name, "-n", f.CdiInstallNs)
Expect(err).NotTo(HaveOccurred())
return strings.Contains(log, "attempting to create blank disk for block mode")
}, controllerSkipPVCCompleteTimeout, assertionPollInterval).Should(BeTrue())
err = utils.WaitForPersistentVolumeClaimPhase(f.K8sClient, pvc.Namespace, v1.ClaimBound, pvc.Name)
Expect(err).ToNot(HaveOccurred())
})
},
Entry("[test_id:4972] with first consumer", true),
Entry("with bind immediate annotation", false),
)

It("Should perform fsync syscall after qemu-img convert to raw", func() {
if !f.IsBlockVolumeStorageClassAvailable() {
Expand Down