Skip to content

Commit 22180f7

Browse files
committed
fix(dp): match target component expressions
1 parent 32020fe commit 22180f7

2 files changed

Lines changed: 62 additions & 3 deletions

File tree

controllers/dataprotection/volumepopulator_controller.go

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import (
3535
apierrors "k8s.io/apimachinery/pkg/api/errors"
3636
"k8s.io/apimachinery/pkg/api/meta"
3737
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
38+
"k8s.io/apimachinery/pkg/labels"
3839
"k8s.io/apimachinery/pkg/runtime"
3940
"k8s.io/apimachinery/pkg/types"
4041
"k8s.io/client-go/tools/record"
@@ -506,11 +507,33 @@ func targetMatchesComponent(target *dpv1alpha1.BackupStatusTarget, componentName
506507
if target.PodSelector == nil || target.PodSelector.LabelSelector == nil {
507508
return true
508509
}
509-
targetComp := target.PodSelector.MatchLabels[constant.KBAppComponentLabelKey]
510-
if targetComp == "" {
510+
componentSelector := componentLabelSelector(target.PodSelector.LabelSelector)
511+
if componentSelector == nil {
511512
return false
512513
}
513-
return targetComp == componentName
514+
selector, err := metav1.LabelSelectorAsSelector(componentSelector)
515+
if err != nil {
516+
return false
517+
}
518+
return selector.Matches(labels.Set{constant.KBAppComponentLabelKey: componentName})
519+
}
520+
521+
func componentLabelSelector(selector *metav1.LabelSelector) *metav1.LabelSelector {
522+
componentSelector := &metav1.LabelSelector{}
523+
if component, ok := selector.MatchLabels[constant.KBAppComponentLabelKey]; ok {
524+
componentSelector.MatchLabels = map[string]string{
525+
constant.KBAppComponentLabelKey: component,
526+
}
527+
}
528+
for _, expression := range selector.MatchExpressions {
529+
if expression.Key == constant.KBAppComponentLabelKey {
530+
componentSelector.MatchExpressions = append(componentSelector.MatchExpressions, expression)
531+
}
532+
}
533+
if len(componentSelector.MatchLabels) == 0 && len(componentSelector.MatchExpressions) == 0 {
534+
return nil
535+
}
536+
return componentSelector
514537
}
515538

516539
func (r *VolumePopulatorReconciler) resolveShardingSourceTarget(reqCtx intctrlutil.RequestCtx,

controllers/dataprotection/volumepopulator_controller_test.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -894,6 +894,42 @@ func TestDecidePVCRestoreNoTargetVolumesTargetComponent(t *testing.T) {
894894
require.Nil(t, decision.sourceTarget)
895895
}
896896

897+
func TestDecidePVCRestoreNoTargetVolumesTargetComponentMatchExpression(t *testing.T) {
898+
reconciler := &VolumePopulatorReconciler{}
899+
backup := newBackupForRestoreDecision(nil, nil)
900+
backup.Status.BackupMethod.TargetVolumes = nil
901+
backup.Status.Target.PodSelector = &dpv1alpha1.PodSelector{
902+
LabelSelector: &metav1.LabelSelector{
903+
MatchLabels: map[string]string{
904+
constant.AppInstanceLabelKey: "source-cluster",
905+
constant.RoleLabelKey: "leader",
906+
},
907+
MatchExpressions: []metav1.LabelSelectorRequirement{{
908+
Key: constant.KBAppComponentLabelKey,
909+
Operator: metav1.LabelSelectorOpIn,
910+
Values: []string{"tidb"},
911+
}},
912+
},
913+
Strategy: dpv1alpha1.PodSelectionStrategyAny,
914+
}
915+
916+
pvc := newPVCForRestoreDecision("data", "tidb", "")
917+
decision, err := reconciler.decidePVCRestore(intctrlutil.RequestCtx{Ctx: context.Background()}, pvc, backup, nil)
918+
require.NoError(t, err)
919+
require.Equal(t, pvcRestoreModeProvisionOnly, decision.mode)
920+
require.False(t, decision.skipPostReady,
921+
"target component selected by MatchExpressions must not skip postReady")
922+
require.NotNil(t, decision.sourceTarget)
923+
924+
pvc = newPVCForRestoreDecision("data", "pd", "")
925+
decision, err = reconciler.decidePVCRestore(intctrlutil.RequestCtx{Ctx: context.Background()}, pvc, backup, nil)
926+
require.NoError(t, err)
927+
require.Equal(t, pvcRestoreModeProvisionOnly, decision.mode)
928+
require.True(t, decision.skipPostReady,
929+
"non-target component must still skip postReady when component expression does not match")
930+
require.Nil(t, decision.sourceTarget)
931+
}
932+
897933
func TestDecidePVCRestoreNoTargetVolumesMultiComponentTargets(t *testing.T) {
898934
reconciler := &VolumePopulatorReconciler{}
899935
backup := newBackupForRestoreDecision(nil, []string{"etcd"})

0 commit comments

Comments
 (0)