Skip to content

Commit 2b770a2

Browse files
authored
Merge pull request #6715 from zhzhuang-zju/automated-cherry-pick-of-#6674-upstream-release-1.12
Automated cherry pick of #6674: fix the issue that the relevant fields in rb and pp are
2 parents f2b85a6 + 752f870 commit 2b770a2

File tree

3 files changed

+152
-15
lines changed

3 files changed

+152
-15
lines changed

pkg/detector/detector.go

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -337,13 +337,26 @@ func (d *ResourceDetector) OnUpdate(oldObj, newObj interface{}) {
337337
return
338338
}
339339

340-
resourceChangeByKarmada := eventfilter.ResourceChangeByKarmada(unstructuredOldObj, unstructuredNewObj)
340+
isLazyActivation, err := d.isClaimedByLazyPolicy(unstructuredNewObj)
341+
if err != nil {
342+
// should never come here
343+
klog.Errorf("Failed to check if the object (kind=%s, %s/%s) is bound by lazy policy. err: %v", unstructuredNewObj.GetKind(), unstructuredNewObj.GetNamespace(), unstructuredNewObj.GetName(), err)
344+
}
341345

342-
resourceItem := ResourceItem{
343-
Obj: newRuntimeObj,
344-
ResourceChangeByKarmada: resourceChangeByKarmada,
346+
if isLazyActivation {
347+
resourceItem := ResourceItem{
348+
Obj: newRuntimeObj,
349+
ResourceChangeByKarmada: eventfilter.ResourceChangeByKarmada(unstructuredOldObj, unstructuredNewObj),
350+
}
351+
352+
d.Processor.Enqueue(resourceItem)
353+
return
345354
}
346355

356+
// For non-lazy policies, it is no need to distinguish whether the change is from Karmada or not.
357+
resourceItem := ResourceItem{
358+
Obj: newRuntimeObj,
359+
}
347360
d.Processor.Enqueue(resourceItem)
348361
}
349362

@@ -1228,7 +1241,7 @@ func (d *ResourceDetector) HandlePropagationPolicyCreationOrUpdate(policy *polic
12281241
if err != nil {
12291242
return err
12301243
}
1231-
d.Processor.Add(keys.ClusterWideKeyWithConfig{ClusterWideKey: resourceKey, ResourceChangeByKarmada: true})
1244+
d.enqueueResourceTemplateForPolicyChange(resourceKey, policy.Spec.ActivationPreference)
12321245
}
12331246

12341247
// check whether there are matched RT in waiting list, is so, add it to processor
@@ -1246,7 +1259,7 @@ func (d *ResourceDetector) HandlePropagationPolicyCreationOrUpdate(policy *polic
12461259

12471260
for _, key := range matchedKeys {
12481261
d.RemoveWaiting(key)
1249-
d.Processor.Add(keys.ClusterWideKeyWithConfig{ClusterWideKey: key, ResourceChangeByKarmada: true})
1262+
d.enqueueResourceTemplateForPolicyChange(key, policy.Spec.ActivationPreference)
12501263
}
12511264

12521265
// If preemption is enabled, handle the preemption process.
@@ -1295,14 +1308,14 @@ func (d *ResourceDetector) HandleClusterPropagationPolicyCreationOrUpdate(policy
12951308
if err != nil {
12961309
return err
12971310
}
1298-
d.Processor.Add(keys.ClusterWideKeyWithConfig{ClusterWideKey: resourceKey, ResourceChangeByKarmada: true})
1311+
d.enqueueResourceTemplateForPolicyChange(resourceKey, policy.Spec.ActivationPreference)
12991312
}
13001313
for _, crb := range clusterResourceBindings.Items {
13011314
resourceKey, err := helper.ConstructClusterWideKey(crb.Spec.Resource)
13021315
if err != nil {
13031316
return err
13041317
}
1305-
d.Processor.Add(keys.ClusterWideKeyWithConfig{ClusterWideKey: resourceKey, ResourceChangeByKarmada: true})
1318+
d.enqueueResourceTemplateForPolicyChange(resourceKey, policy.Spec.ActivationPreference)
13061319
}
13071320

13081321
matchedKeys := d.GetMatching(policy.Spec.ResourceSelectors)
@@ -1319,7 +1332,7 @@ func (d *ResourceDetector) HandleClusterPropagationPolicyCreationOrUpdate(policy
13191332

13201333
for _, key := range matchedKeys {
13211334
d.RemoveWaiting(key)
1322-
d.Processor.Add(keys.ClusterWideKeyWithConfig{ClusterWideKey: key, ResourceChangeByKarmada: true})
1335+
d.enqueueResourceTemplateForPolicyChange(key, policy.Spec.ActivationPreference)
13231336
}
13241337

13251338
// If preemption is enabled, handle the preemption process.
@@ -1462,3 +1475,21 @@ func (d *ResourceDetector) CleanupClusterResourceBindingClaimMetadata(crbName st
14621475
return updateErr
14631476
})
14641477
}
1478+
1479+
// enqueueResourceTemplateForPolicyChange enqueues a resource template key for reconciliation in response to a
1480+
// PropagationPolicy or ClusterPropagationPolicy change. If the policy's ActivationPreference is set to Lazy,
1481+
// the ResourceChangeByKarmada flag is set to true, indicating that the resource template is being enqueued
1482+
// due to a policy change and should not be propagated to member clusters. For non-lazy policies, this flag
1483+
// is omitted as the distinction is unnecessary.
1484+
//
1485+
// Note: Setting ResourceChangeByKarmada changes the effective queue key. Mixing both true/false for the same
1486+
// resource may result in two different queue keys being processed concurrently, which can cause race conditions.
1487+
// Therefore, only set ResourceChangeByKarmada in lazy activation mode.
1488+
// For more details, see: https://github.com/karmada-io/karmada/issues/5996.
1489+
func (d *ResourceDetector) enqueueResourceTemplateForPolicyChange(key keys.ClusterWideKey, pref policyv1alpha1.ActivationPreference) {
1490+
if util.IsLazyActivationEnabled(pref) {
1491+
d.Processor.Add(keys.ClusterWideKeyWithConfig{ClusterWideKey: key, ResourceChangeByKarmada: true})
1492+
return
1493+
}
1494+
d.Processor.Add(keys.ClusterWideKeyWithConfig{ClusterWideKey: key})
1495+
}

pkg/detector/detector_test.go

Lines changed: 67 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,6 @@ func TestOnUpdate(t *testing.T) {
431431
oldObj interface{}
432432
newObj interface{}
433433
expectedEnqueue bool
434-
expectedChangeByKarmada bool
435434
expectToUnstructuredError bool
436435
}{
437436
{
@@ -462,8 +461,7 @@ func TestOnUpdate(t *testing.T) {
462461
},
463462
},
464463
},
465-
expectedEnqueue: true,
466-
expectedChangeByKarmada: false,
464+
expectedEnqueue: true,
467465
},
468466
{
469467
name: "update without changes",
@@ -526,8 +524,7 @@ func TestOnUpdate(t *testing.T) {
526524
},
527525
},
528526
},
529-
expectedEnqueue: true,
530-
expectedChangeByKarmada: true,
527+
expectedEnqueue: true,
531528
},
532529
{
533530
name: "core v1 object",
@@ -567,7 +564,6 @@ func TestOnUpdate(t *testing.T) {
567564
assert.IsType(t, ResourceItem{}, mockProcessor.lastEnqueued, "Enqueued item should be of type ResourceItem")
568565
enqueued := mockProcessor.lastEnqueued.(ResourceItem)
569566
assert.Equal(t, tt.newObj, enqueued.Obj, "Enqueued object should match the new object")
570-
assert.Equal(t, tt.expectedChangeByKarmada, enqueued.ResourceChangeByKarmada, "ResourceChangeByKarmada flag should match expected value")
571567
} else {
572568
assert.Equal(t, 0, mockProcessor.enqueueCount, "Object should not be enqueued")
573569
}
@@ -1023,6 +1019,71 @@ func TestApplyClusterPolicy(t *testing.T) {
10231019
}
10241020
}
10251021

1022+
func TestEnqueueResourceKeyWithActivationPref(t *testing.T) {
1023+
testClusterWideKey := keys.ClusterWideKey{
1024+
Group: "foo",
1025+
Version: "foo",
1026+
Kind: "foo",
1027+
Namespace: "foo",
1028+
Name: "foo",
1029+
}
1030+
tests := []struct {
1031+
name string
1032+
key keys.ClusterWideKey
1033+
pref policyv1alpha1.ActivationPreference
1034+
want keys.ClusterWideKeyWithConfig
1035+
}{
1036+
{
1037+
name: "lazy pp and resourceChangeByKarmada is true",
1038+
key: testClusterWideKey,
1039+
pref: policyv1alpha1.LazyActivation,
1040+
want: keys.ClusterWideKeyWithConfig{
1041+
ClusterWideKey: testClusterWideKey,
1042+
ResourceChangeByKarmada: true,
1043+
},
1044+
},
1045+
{
1046+
name: "non-lazy ignores ResourceChangeByKarmada",
1047+
key: testClusterWideKey,
1048+
pref: "",
1049+
want: keys.ClusterWideKeyWithConfig{
1050+
ClusterWideKey: testClusterWideKey,
1051+
ResourceChangeByKarmada: false,
1052+
},
1053+
},
1054+
}
1055+
for _, tt := range tests {
1056+
t.Run(tt.name, func(t *testing.T) {
1057+
ctx, cancel := context.WithCancel(context.Background())
1058+
detector := ResourceDetector{
1059+
Processor: util.NewAsyncWorker(util.Options{
1060+
Name: "resource detector",
1061+
KeyFunc: ResourceItemKeyFunc,
1062+
ReconcileFunc: func(key util.QueueKey) (err error) {
1063+
defer cancel()
1064+
defer func() {
1065+
assert.NoError(t, err)
1066+
}()
1067+
clusterWideKeyWithConfig, ok := key.(keys.ClusterWideKeyWithConfig)
1068+
if !ok {
1069+
err = fmt.Errorf("invalid key")
1070+
return err
1071+
}
1072+
if clusterWideKeyWithConfig != tt.want {
1073+
err = fmt.Errorf("unexpected key. want:%+v, got:%+v", tt.want, clusterWideKeyWithConfig)
1074+
return err
1075+
}
1076+
return nil
1077+
},
1078+
}),
1079+
}
1080+
detector.Processor.Run(1, ctx.Done())
1081+
detector.enqueueResourceTemplateForPolicyChange(tt.key, tt.pref)
1082+
<-ctx.Done()
1083+
})
1084+
}
1085+
}
1086+
10261087
//Helper Functions
10271088

10281089
// setupTestScheme creates a runtime scheme with necessary types for testing

pkg/detector/policy.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,51 @@ func (d *ResourceDetector) listCPPDerivedCRBs(policyID, policyName string) (*wor
373373
return bindings, nil
374374
}
375375

376+
func (d *ResourceDetector) isClaimedByLazyPolicy(obj *unstructured.Unstructured) (bool, error) {
377+
policyAnnotations := obj.GetAnnotations()
378+
policyLabels := obj.GetLabels()
379+
policyNamespace := util.GetAnnotationValue(policyAnnotations, policyv1alpha1.PropagationPolicyNamespaceAnnotation)
380+
policyName := util.GetAnnotationValue(policyAnnotations, policyv1alpha1.PropagationPolicyNameAnnotation)
381+
claimedID := util.GetLabelValue(policyLabels, policyv1alpha1.PropagationPolicyPermanentIDLabel)
382+
if policyNamespace != "" && policyName != "" && claimedID != "" {
383+
policyObject, err := d.propagationPolicyLister.ByNamespace(policyNamespace).Get(policyName)
384+
if err != nil {
385+
if apierrors.IsNotFound(err) {
386+
return false, nil
387+
}
388+
389+
return false, err
390+
}
391+
matchedPropagationPolicy := &policyv1alpha1.PropagationPolicy{}
392+
if err = helper.ConvertToTypedObject(policyObject, matchedPropagationPolicy); err != nil {
393+
return false, err
394+
}
395+
396+
return util.IsLazyActivationEnabled(matchedPropagationPolicy.Spec.ActivationPreference), nil
397+
}
398+
399+
policyName = util.GetAnnotationValue(policyAnnotations, policyv1alpha1.ClusterPropagationPolicyAnnotation)
400+
claimedID = util.GetLabelValue(policyLabels, policyv1alpha1.ClusterPropagationPolicyPermanentIDLabel)
401+
if policyName != "" && claimedID != "" {
402+
policyObject, err := d.clusterPropagationPolicyLister.Get(policyName)
403+
if err != nil {
404+
if apierrors.IsNotFound(err) {
405+
return false, nil
406+
}
407+
408+
return false, err
409+
}
410+
matchedClusterPropagationPolicy := &policyv1alpha1.ClusterPropagationPolicy{}
411+
if err = helper.ConvertToTypedObject(policyObject, matchedClusterPropagationPolicy); err != nil {
412+
return false, err
413+
}
414+
415+
return util.IsLazyActivationEnabled(matchedClusterPropagationPolicy.Spec.ActivationPreference), nil
416+
}
417+
418+
return false, nil
419+
}
420+
376421
// excludeClusterPolicy excludes cluster propagation policy.
377422
// If propagation policy was claimed, cluster propagation policy should not exist.
378423
func excludeClusterPolicy(obj metav1.Object) (hasClaimedClusterPolicy bool) {

0 commit comments

Comments
 (0)