Skip to content

Commit

Permalink
handle preserveResourceOnDeletion with dependencise distributor
Browse files Browse the repository at this point in the history
Signed-off-by: changzhen <[email protected]>
  • Loading branch information
XiShanYongYe-Chang committed Oct 21, 2024
1 parent aca83a7 commit c2d9eaf
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 16 deletions.
73 changes: 60 additions & 13 deletions pkg/dependenciesdistributor/dependencies_distributor.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,14 @@ import (
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/tools/record"
"k8s.io/client-go/util/retry"
"k8s.io/klog/v2"
"k8s.io/utils/ptr"
controllerruntime "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller"
Expand All @@ -47,6 +49,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/source"

configv1alpha1 "github.com/karmada-io/karmada/pkg/apis/config/v1alpha1"
policyv1alpha1 "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1"
workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2"
"github.com/karmada-io/karmada/pkg/events"
"github.com/karmada-io/karmada/pkg/resourceinterpreter"
Expand Down Expand Up @@ -250,7 +253,7 @@ func (d *DependenciesDistributor) Reconcile(ctx context.Context, request reconci

// in case users set PropagateDeps field from "true" to "false"
if !bindingObject.Spec.PropagateDeps || !bindingObject.DeletionTimestamp.IsZero() {
err = d.handleIndependentBindingDeletion(bindingObject.Labels[workv1alpha2.ResourceBindingPermanentIDLabel], request.Namespace, request.Name)
err = d.handleIndependentBindingDeletion(ctx, bindingObject.Labels[workv1alpha2.ResourceBindingPermanentIDLabel], request.Namespace, request.Name)
if err != nil {
klog.Errorf("Failed to cleanup attached bindings for independent binding(%s): %v", request.NamespacedName, err)
return reconcile.Result{}, err
Expand Down Expand Up @@ -297,13 +300,13 @@ func (d *DependenciesDistributor) removeFinalizer(ctx context.Context, independe
return nil
}

func (d *DependenciesDistributor) handleIndependentBindingDeletion(id, namespace, name string) error {
attachedBindings, err := d.listAttachedBindings(id, namespace, name)
func (d *DependenciesDistributor) handleIndependentBindingDeletion(ctx context.Context, id, namespace, name string) error {
attachedBindings, err := d.listAttachedBindings(ctx, id, namespace, name)
if err != nil {
return err
}

return d.removeScheduleResultFromAttachedBindings(namespace, name, attachedBindings)
return d.removeScheduleResultFromAttachedBindings(ctx, namespace, name, attachedBindings)
}

func (d *DependenciesDistributor) removeOrphanAttachedBindings(ctx context.Context, independentBinding *workv1alpha2.ResourceBinding, dependencies []configv1alpha1.DependentObjectReference) error {
Expand All @@ -314,7 +317,7 @@ func (d *DependenciesDistributor) removeOrphanAttachedBindings(ctx context.Conte
independentBinding.GetNamespace(), independentBinding.GetName(), err)
return err
}
err = d.removeScheduleResultFromAttachedBindings(independentBinding.Namespace, independentBinding.Name, orphanBindings)
err = d.removeScheduleResultFromAttachedBindings(ctx, independentBinding.Namespace, independentBinding.Name, orphanBindings)
if err != nil {
klog.Errorf("Failed to remove orphan attached bindings by resourceBinding(%s/%s). Error: %v.",
independentBinding.GetNamespace(), independentBinding.GetName(), err)
Expand Down Expand Up @@ -445,7 +448,7 @@ func (d *DependenciesDistributor) recordDependencies(ctx context.Context, indepe
}

func (d *DependenciesDistributor) findOrphanAttachedBindings(ctx context.Context, independentBinding *workv1alpha2.ResourceBinding, dependencies []configv1alpha1.DependentObjectReference) ([]*workv1alpha2.ResourceBinding, error) {
attachedBindings, err := d.listAttachedBindings(independentBinding.Labels[workv1alpha2.ResourceBindingPermanentIDLabel],
attachedBindings, err := d.listAttachedBindings(ctx, independentBinding.Labels[workv1alpha2.ResourceBindingPermanentIDLabel],
independentBinding.Namespace, independentBinding.Name)
if err != nil {
return nil, err
Expand Down Expand Up @@ -518,23 +521,26 @@ func (d *DependenciesDistributor) isOrphanAttachedBindings(
return true, nil
}

func (d *DependenciesDistributor) listAttachedBindings(bindingID, bindingNamespace, bindingName string) (res []*workv1alpha2.ResourceBinding, err error) {
labelSet := generateBindingDependedLabels(bindingID, bindingNamespace, bindingName)
selector := labels.SelectorFromSet(labelSet)
func (d *DependenciesDistributor) listAttachedBindings(ctx context.Context, bindingID, bindingNamespace, bindingName string) ([]*workv1alpha2.ResourceBinding, error) {
bindingList := &workv1alpha2.ResourceBindingList{}
err = d.Client.List(context.TODO(), bindingList, &client.ListOptions{
err := d.Client.List(ctx, bindingList, &client.ListOptions{
Namespace: bindingNamespace,
LabelSelector: selector})
LabelSelector: labels.SelectorFromSet(generateBindingDependedLabels(bindingID, bindingNamespace, bindingName)),
})
if err != nil {
klog.Errorf("Failed to list attached bindings with independent binding(%s/%s): %v",
bindingNamespace, bindingName, err)
return nil, err
}

var res []*workv1alpha2.ResourceBinding
for i := range bindingList.Items {
res = append(res, &bindingList.Items[i])
}
return res, nil
}

func (d *DependenciesDistributor) removeScheduleResultFromAttachedBindings(bindingNamespace, bindingName string, attachedBindings []*workv1alpha2.ResourceBinding) error {
func (d *DependenciesDistributor) removeScheduleResultFromAttachedBindings(ctx context.Context, bindingNamespace, bindingName string, attachedBindings []*workv1alpha2.ResourceBinding) error {
if len(attachedBindings) == 0 {
return nil
}
Expand All @@ -545,7 +551,14 @@ func (d *DependenciesDistributor) removeScheduleResultFromAttachedBindings(bindi
for index, binding := range attachedBindings {
delete(attachedBindings[index].Labels, bindingLabelKey)
updatedSnapshot := deleteBindingFromSnapshot(bindingNamespace, bindingName, attachedBindings[index].Spec.RequiredBy)
preserveResourcesOnDeletion, err := obtainPreserveStrategyFromBinding(ctx, d.Client, binding)
if err != nil {
errs = append(errs, err)
continue
}

attachedBindings[index].Spec.RequiredBy = updatedSnapshot
attachedBindings[index].Spec.PreserveResourcesOnDeletion = preserveResourcesOnDeletion
if err := d.Client.Update(context.TODO(), attachedBindings[index]); err != nil {
klog.Errorf("Failed to update binding(%s/%s): %v", binding.Namespace, binding.Name, err)
errs = append(errs, err)
Expand All @@ -555,6 +568,34 @@ func (d *DependenciesDistributor) removeScheduleResultFromAttachedBindings(bindi
return utilerrors.NewAggregate(errs)
}

func obtainPreserveStrategyFromBinding(ctx context.Context, c client.Client, binding *workv1alpha2.ResourceBinding) (*bool, error) {
var preserveResourcesOnDeletion = false
ppNamespace := binding.Annotations[policyv1alpha1.PropagationPolicyNamespaceAnnotation]
ppName := binding.Annotations[policyv1alpha1.PropagationPolicyNameAnnotation]
cppName := binding.Annotations[policyv1alpha1.ClusterPropagationPolicyAnnotation]
if (ppNamespace == "" && ppName == "") && cppName == "" {
return &preserveResourcesOnDeletion, nil
}

if ppNamespace == "" {
cpp := &policyv1alpha1.ClusterPropagationPolicy{}
err := c.Get(ctx, types.NamespacedName{Name: cppName}, cpp)
if err != nil {
klog.Errorf("Failed to get cpp(%s): %v", cppName, err)
return nil, err
}
return cpp.Spec.PreserveResourcesOnDeletion, nil
}

pp := &policyv1alpha1.PropagationPolicy{}
err := c.Get(ctx, types.NamespacedName{Namespace: ppNamespace, Name: ppName}, pp)
if err != nil {
klog.Errorf("Failed to get pp(%s/%s): %v", ppNamespace, ppName, err)
return nil, err
}
return pp.Spec.PreserveResourcesOnDeletion, nil
}

func (d *DependenciesDistributor) createOrUpdateAttachedBinding(attachedBinding *workv1alpha2.ResourceBinding) error {
existBinding := &workv1alpha2.ResourceBinding{}
bindingKey := client.ObjectKeyFromObject(attachedBinding)
Expand All @@ -563,6 +604,7 @@ func (d *DependenciesDistributor) createOrUpdateAttachedBinding(attachedBinding
existBinding.Spec.RequiredBy = mergeBindingSnapshot(existBinding.Spec.RequiredBy, attachedBinding.Spec.RequiredBy)
existBinding.Labels = util.DedupeAndMergeLabels(existBinding.Labels, attachedBinding.Labels)
existBinding.Spec.Resource = attachedBinding.Spec.Resource
existBinding.Spec.PreserveResourcesOnDeletion = attachedBinding.Spec.PreserveResourcesOnDeletion

if err := d.Client.Update(context.TODO(), existBinding); err != nil {
klog.Errorf("Failed to update resourceBinding(%s): %v", bindingKey, err)
Expand Down Expand Up @@ -685,7 +727,7 @@ func buildAttachedBinding(independentBinding *workv1alpha2.ResourceBinding, obje
Clusters: independentBinding.Spec.Clusters,
})

return &workv1alpha2.ResourceBinding{
attachedBinding := &workv1alpha2.ResourceBinding{
ObjectMeta: metav1.ObjectMeta{
Name: names.GenerateBindingName(object.GetKind(), object.GetName()),
Namespace: independentBinding.GetNamespace(),
Expand All @@ -706,6 +748,11 @@ func buildAttachedBinding(independentBinding *workv1alpha2.ResourceBinding, obje
RequiredBy: result,
},
}

if ptr.Deref(independentBinding.Spec.PreserveResourcesOnDeletion, false) {
attachedBinding.Spec.PreserveResourcesOnDeletion = independentBinding.Spec.PreserveResourcesOnDeletion
}
return attachedBinding
}

func mergeBindingSnapshot(existSnapshot, newSnapshot []workv1alpha2.BindingSnapshot) []workv1alpha2.BindingSnapshot {
Expand Down
6 changes: 3 additions & 3 deletions pkg/dependenciesdistributor/dependencies_distributor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -655,7 +655,7 @@ func Test_handleIndependentBindingDeletion(t *testing.T) {
d := &DependenciesDistributor{
Client: tt.fields.Client,
}
err := d.handleIndependentBindingDeletion(tt.args.id, tt.args.namespace, tt.args.name)
err := d.handleIndependentBindingDeletion(context.Background(), tt.args.id, tt.args.namespace, tt.args.name)
if (err != nil) != tt.wantErr {
t.Errorf("handleIndependentBindingDeletion() error = %v, wantErr %v", err, tt.wantErr)
}
Expand Down Expand Up @@ -1890,7 +1890,7 @@ func Test_listAttachedBindings(t *testing.T) {
d := &DependenciesDistributor{
Client: tt.setupClient(),
}
gotBindings, err := d.listAttachedBindings(tt.bindingID, tt.bindingNamespace, tt.bindingName)
gotBindings, err := d.listAttachedBindings(context.Background(), tt.bindingID, tt.bindingNamespace, tt.bindingName)
if (err != nil) != tt.wantErr {
t.Errorf("listAttachedBindings() error = %v, wantErr %v", err, tt.wantErr)
}
Expand Down Expand Up @@ -2188,7 +2188,7 @@ func Test_removeScheduleResultFromAttachedBindings(t *testing.T) {
d := &DependenciesDistributor{
Client: tt.setupClient(),
}
err := d.removeScheduleResultFromAttachedBindings(tt.bindingNamespace, tt.bindingName, tt.attachedBindings)
err := d.removeScheduleResultFromAttachedBindings(context.Background(), tt.bindingNamespace, tt.bindingName, tt.attachedBindings)
if (err != nil) != tt.wantErr {
t.Errorf("removeScheduleResultFromAttachedBindings() error = %v, wantErr %v", err, tt.wantErr)
}
Expand Down

0 comments on commit c2d9eaf

Please sign in to comment.