Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,31 @@ func (r *ClusterPodPlacementConfigReconciler) handleDelete(ctx context.Context,
// We execute the update here because this function returns multiple times before the whole deletion process is completed.
// Executing it here ensures that the conditions are updated throughout the deletion process.
_ = r.updateStatus(ctx, clusterPodPlacementConfig)

// Prevent deletion while PodPlacementConfig resources still exist
// Check this BEFORE tearing down webhook/operand resources to prevent orphaning PPCs
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

could there be a unit test?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

There was an integration test. I updated it to look at the webhook as well

if controllerutil.ContainsFinalizer(clusterPodPlacementConfig, utils.CPPCNoPPCObjectFinalizer) {
log.V(1).Info("Checking for existing PodPlacementConfig resources before deletion")
ppcList := &multiarchv1beta1.PodPlacementConfigList{}
if err := r.List(ctx, ppcList); err != nil {
log.Error(err, "Unable to list PodPlacementConfigs during deletion")
return err
}
if len(ppcList.Items) > 0 {
// Block deletion - PPCs still exist
err := errors.New(RemainingPodPlacementConfig)
log.Error(err, "Deletion blocked due to existing PodPlacementConfig resources")
return err
}
// All PPCs are gone, remove the finalizer and continue with deletion
log.V(1).Info("No PodPlacementConfig resources found, removing no-pod-placement-config finalizer")
controllerutil.RemoveFinalizer(clusterPodPlacementConfig, utils.CPPCNoPPCObjectFinalizer)
if err := r.Update(ctx, clusterPodPlacementConfig); err != nil {
log.Error(err, "Unable to remove no-pod-placement-config finalizer from ClusterPodPlacementConfig")
return err
}
}

objsToDelete := []utils.ToDeleteRef{
{
NamespacedTypedClient: r.ClientSet.AdmissionregistrationV1().MutatingWebhookConfigurations(),
Expand Down Expand Up @@ -384,29 +409,6 @@ func (r *ClusterPodPlacementConfigReconciler) handleDelete(ctx context.Context,
return errors.New(waitingForWebhookSInterruptionError)
}

// Prevent deletion while PodPlacementConfig resources still exist
if controllerutil.ContainsFinalizer(clusterPodPlacementConfig, utils.CPPCNoPPCObjectFinalizer) {
log.V(1).Info("Checking for existing PodPlacementConfig resources before deletion")
ppcList := &multiarchv1beta1.PodPlacementConfigList{}
if err := r.List(ctx, ppcList); err != nil {
log.Error(err, "Unable to list PodPlacementConfigs during deletion")
return err
}
if len(ppcList.Items) > 0 {
err := errors.New(RemainingPodPlacementConfig)
log.Error(err, "Deletion blocked due to existing PodPlacementConfig resources")
return err
}
// All PPCs are gone, remove the finalizer
log.V(1).Info("No PodPlacementConfig resources found, removing no-pod-placement-config finalizer")
controllerutil.RemoveFinalizer(clusterPodPlacementConfig, utils.CPPCNoPPCObjectFinalizer)
if err := r.Update(ctx, clusterPodPlacementConfig); err != nil {
log.Error(err, "Unable to remove no-pod-placement-config finalizer from ClusterPodPlacementConfig")
return err
}
return nil
}

log.Info("Looking for pods with the scheduling gate")
// get pending pods as we cannot query for the scheduling gate
pods, err := r.ClientSet.CoreV1().Pods("").List(ctx, metav1.ListOptions{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,20 @@ var _ = Describe("internal/Controller/ClusterPodPlacementConfig/ClusterPodPlacem
By("Attempting to delete ClusterPodPlacementConfig")
err = k8sClient.Delete(ctx, builder.NewClusterPodPlacementConfig().WithName(common.SingletonResourceObjectName).Build())
Expect(err).To(HaveOccurred(), "the ClusterPodPlacementConfig should not be able to deleted when local PodPlacementConfigs exist", err)
By("Verifying webhook resources still exist after blocked deletion")
Eventually(func(g Gomega) {
mwc := &admissionv1.MutatingWebhookConfiguration{}
err = k8sClient.Get(ctx, crclient.ObjectKey{Name: utils.PodMutatingWebhookConfigurationName}, mwc)
g.Expect(err).NotTo(HaveOccurred(), "webhook configuration should still exist")

svc := &corev1.Service{}
err = k8sClient.Get(ctx, crclient.ObjectKey{Name: utils.PodPlacementWebhookName, Namespace: utils.Namespace()}, svc)
g.Expect(err).NotTo(HaveOccurred(), "webhook service should still exist")

deployment := &appsv1.Deployment{}
err = k8sClient.Get(ctx, crclient.ObjectKey{Name: utils.PodPlacementWebhookName, Namespace: utils.Namespace()}, deployment)
g.Expect(err).NotTo(HaveOccurred(), "webhook deployment should still exist")
}).Should(Succeed(), "webhook resources should remain intact when deletion is blocked")
By("Deleting the local PodPlacementConfig")
err = k8sClient.Delete(ctx, builder.NewPodPlacementConfig().
WithName("test-ppc").
Expand Down