diff --git a/pkg/control/pubcontrol/pub_control.go b/pkg/control/pubcontrol/pub_control.go index 1d529d1ab0..22df9537b9 100644 --- a/pkg/control/pubcontrol/pub_control.go +++ b/pkg/control/pubcontrol/pub_control.go @@ -82,9 +82,9 @@ func (c *commonControl) GetPodsForPub(pub *policyv1alpha1.PodUnavailableBudget) return nil, 0, nil } // get pods for selector - labelSelector, err := util.GetFastLabelSelector(pub.Spec.Selector) + labelSelector, err := util.ValidatedLabelSelectorAsSelector(pub.Spec.Selector) if err != nil { - klog.Warningf("pub(%s/%s) GetFastLabelSelector failed: %s", pub.Namespace, pub.Name, err.Error()) + klog.Warningf("pub(%s/%s) ValidatedLabelSelectorAsSelector failed: %s", pub.Namespace, pub.Name, err.Error()) return nil, 0, nil } listOptions = &client.ListOptions{Namespace: pub.Namespace, LabelSelector: labelSelector} diff --git a/pkg/control/sidecarcontrol/history_control.go b/pkg/control/sidecarcontrol/history_control.go index c8d4f17271..1534ef3ca2 100644 --- a/pkg/control/sidecarcontrol/history_control.go +++ b/pkg/control/sidecarcontrol/history_control.go @@ -141,7 +141,7 @@ func (r *realControl) GetRevisionSelector(s *appsv1alpha1.SidecarSet) labels.Sel SidecarSetKindName: s.GetName(), }, } - selector, err := util.GetFastLabelSelector(labelSelector) + selector, err := util.ValidatedLabelSelectorAsSelector(labelSelector) if err != nil { // static error, just panic panic("Incorrect label selector for ControllerRevision of SidecarSet.") diff --git a/pkg/control/sidecarcontrol/util.go b/pkg/control/sidecarcontrol/util.go index fe07395595..991ec320a0 100644 --- a/pkg/control/sidecarcontrol/util.go +++ b/pkg/control/sidecarcontrol/util.go @@ -82,7 +82,7 @@ func PodMatchedSidecarSet(pod *corev1.Pod, sidecarSet appsv1alpha1.SidecarSet) ( return false, nil } // if selector not matched, then continue - selector, err := metav1.LabelSelectorAsSelector(sidecarSet.Spec.Selector) + selector, err := util.ValidatedLabelSelectorAsSelector(sidecarSet.Spec.Selector) if err != nil { return false, err } @@ -471,7 +471,7 @@ func ValidateSidecarSetPatchMetadataWhitelist(c client.Client, sidecarSet *appsv for _, rule := range whitelist.Rules { if rule.Selector != nil { - selector, err := util.GetFastLabelSelector(rule.Selector) + selector, err := util.ValidatedLabelSelectorAsSelector(rule.Selector) if err != nil { return err } diff --git a/pkg/controller/cloneset/cloneset_controller.go b/pkg/controller/cloneset/cloneset_controller.go index b1362c5109..53b4ebd741 100644 --- a/pkg/controller/cloneset/cloneset_controller.go +++ b/pkg/controller/cloneset/cloneset_controller.go @@ -29,6 +29,7 @@ import ( synccontrol "github.com/openkruise/kruise/pkg/controller/cloneset/sync" clonesetutils "github.com/openkruise/kruise/pkg/controller/cloneset/utils" "github.com/openkruise/kruise/pkg/features" + "github.com/openkruise/kruise/pkg/util" utilclient "github.com/openkruise/kruise/pkg/util/client" utildiscovery "github.com/openkruise/kruise/pkg/util/discovery" "github.com/openkruise/kruise/pkg/util/expectations" @@ -214,7 +215,7 @@ func (r *ReconcileCloneSet) doReconcile(request reconcile.Request) (res reconcil return reconcile.Result{}, nil } - selector, err := metav1.LabelSelectorAsSelector(instance.Spec.Selector) + selector, err := util.ValidatedLabelSelectorAsSelector(instance.Spec.Selector) if err != nil { klog.Errorf("Error converting CloneSet %s selector: %v", request, err) // This is a non-transient error, so don't retry. diff --git a/pkg/controller/daemonset/daemonset_controller.go b/pkg/controller/daemonset/daemonset_controller.go index f59d65e56b..67a8f97844 100644 --- a/pkg/controller/daemonset/daemonset_controller.go +++ b/pkg/controller/daemonset/daemonset_controller.go @@ -319,7 +319,7 @@ func (dsc *ReconcileDaemonSet) Reconcile(ctx context.Context, request reconcile. // Note that returned Pods are pointers to objects in the cache. // If you want to modify one, you need to deep-copy it first. func (dsc *ReconcileDaemonSet) getDaemonPods(ds *appsv1alpha1.DaemonSet) ([]*corev1.Pod, error) { - selector, err := metav1.LabelSelectorAsSelector(ds.Spec.Selector) + selector, err := kruiseutil.ValidatedLabelSelectorAsSelector(ds.Spec.Selector) if err != nil { return nil, err } diff --git a/pkg/controller/daemonset/daemonset_event_handler.go b/pkg/controller/daemonset/daemonset_event_handler.go index 13a94006e4..26a33f3de5 100644 --- a/pkg/controller/daemonset/daemonset_event_handler.go +++ b/pkg/controller/daemonset/daemonset_event_handler.go @@ -35,6 +35,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1" + "github.com/openkruise/kruise/pkg/util" ) var _ handler.EventHandler = &podEventHandler{} @@ -211,7 +212,7 @@ func (e *podEventHandler) getPodDaemonSets(pod *v1.Pod) []*appsv1alpha1.DaemonSe var dsMatched []*appsv1alpha1.DaemonSet for i := range dsList.Items { ds := &dsList.Items[i] - selector, err := metav1.LabelSelectorAsSelector(ds.Spec.Selector) + selector, err := util.ValidatedLabelSelectorAsSelector(ds.Spec.Selector) if err != nil || selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) { continue } diff --git a/pkg/controller/daemonset/daemonset_history.go b/pkg/controller/daemonset/daemonset_history.go index b1606e2f9a..e47a1959f9 100644 --- a/pkg/controller/daemonset/daemonset_history.go +++ b/pkg/controller/daemonset/daemonset_history.go @@ -24,6 +24,7 @@ import ( "reflect" appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1" + "github.com/openkruise/kruise/pkg/util" apps "k8s.io/api/apps/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -96,7 +97,7 @@ func (dsc *ReconcileDaemonSet) constructHistory(ds *appsv1alpha1.DaemonSet) (cur // Note that returned histories are pointers to objects in the cache. // If you want to modify one, you need to deep-copy it first. func (dsc *ReconcileDaemonSet) controlledHistories(ds *appsv1alpha1.DaemonSet) ([]*apps.ControllerRevision, error) { - selector, err := metav1.LabelSelectorAsSelector(ds.Spec.Selector) + selector, err := util.ValidatedLabelSelectorAsSelector(ds.Spec.Selector) if err != nil { return nil, err } diff --git a/pkg/controller/daemonset/daemonset_update.go b/pkg/controller/daemonset/daemonset_update.go index c078a3adbd..17946a6e68 100644 --- a/pkg/controller/daemonset/daemonset_update.go +++ b/pkg/controller/daemonset/daemonset_update.go @@ -24,6 +24,7 @@ import ( appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1" clonesetutils "github.com/openkruise/kruise/pkg/controller/cloneset/utils" + "github.com/openkruise/kruise/pkg/util" "github.com/openkruise/kruise/pkg/util/inplaceupdate" apps "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" @@ -306,7 +307,7 @@ func (dsc *ReconcileDaemonSet) filterDaemonPodsNodeToUpdate(ds *appsv1alpha1.Dae partition = *ds.Spec.UpdateStrategy.RollingUpdate.Partition } if ds.Spec.UpdateStrategy.RollingUpdate != nil && ds.Spec.UpdateStrategy.RollingUpdate.Selector != nil { - if selector, err = metav1.LabelSelectorAsSelector(ds.Spec.UpdateStrategy.RollingUpdate.Selector); err != nil { + if selector, err = util.ValidatedLabelSelectorAsSelector(ds.Spec.UpdateStrategy.RollingUpdate.Selector); err != nil { return nil, err } } diff --git a/pkg/controller/daemonset/daemonset_util.go b/pkg/controller/daemonset/daemonset_util.go index 8f03951055..74b8d96325 100644 --- a/pkg/controller/daemonset/daemonset_util.go +++ b/pkg/controller/daemonset/daemonset_util.go @@ -24,6 +24,7 @@ import ( appspub "github.com/openkruise/kruise/apis/apps/pub" appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1" + kruiseutil "github.com/openkruise/kruise/pkg/util" "github.com/openkruise/kruise/pkg/util/inplaceupdate" "github.com/openkruise/kruise/pkg/util/lifecycle" @@ -156,7 +157,7 @@ func (dsc *ReconcileDaemonSet) GetPodDaemonSets(pod *corev1.Pod) ([]*appsv1alpha var selector labels.Selector var daemonSets []*appsv1alpha1.DaemonSet for _, ds := range dsList { - selector, err = metav1.LabelSelectorAsSelector(ds.Spec.Selector) + selector, err = kruiseutil.ValidatedLabelSelectorAsSelector(ds.Spec.Selector) if err != nil { // this should not happen if the DaemonSet passed validation return nil, err @@ -343,7 +344,7 @@ func NodeShouldUpdateBySelector(node *corev1.Node, ds *appsv1alpha1.DaemonSet) b if ds.Spec.UpdateStrategy.RollingUpdate == nil || ds.Spec.UpdateStrategy.RollingUpdate.Selector == nil { return false } - selector, err := metav1.LabelSelectorAsSelector(ds.Spec.UpdateStrategy.RollingUpdate.Selector) + selector, err := kruiseutil.ValidatedLabelSelectorAsSelector(ds.Spec.UpdateStrategy.RollingUpdate.Selector) if err != nil { // this should not happen if the DaemonSet passed validation return false diff --git a/pkg/controller/ephemeraljob/ephemeraljob_controller.go b/pkg/controller/ephemeraljob/ephemeraljob_controller.go index 50d9edc3e1..45a4c93962 100644 --- a/pkg/controller/ephemeraljob/ephemeraljob_controller.go +++ b/pkg/controller/ephemeraljob/ephemeraljob_controller.go @@ -222,7 +222,7 @@ func (r *ReconcileEphemeralJob) Reconcile(context context.Context, request recon } func (r *ReconcileEphemeralJob) filterPods(job *appsv1alpha1.EphemeralJob) ([]*v1.Pod, error) { - selector, err := util.GetFastLabelSelector(job.Spec.Selector) + selector, err := util.ValidatedLabelSelectorAsSelector(job.Spec.Selector) if err != nil { return nil, err } @@ -265,7 +265,7 @@ func (r *ReconcileEphemeralJob) filterPods(job *appsv1alpha1.EphemeralJob) ([]*v // filterInjectedPods will return pods which has injected ephemeral containers func (r *ReconcileEphemeralJob) filterInjectedPods(job *appsv1alpha1.EphemeralJob) ([]*v1.Pod, error) { - selector, err := util.GetFastLabelSelector(job.Spec.Selector) + selector, err := util.ValidatedLabelSelectorAsSelector(job.Spec.Selector) if err != nil { return nil, err } diff --git a/pkg/controller/ephemeraljob/ephemeraljob_utils.go b/pkg/controller/ephemeraljob/ephemeraljob_utils.go index 16ec38c578..43b111bc46 100644 --- a/pkg/controller/ephemeraljob/ephemeraljob_utils.go +++ b/pkg/controller/ephemeraljob/ephemeraljob_utils.go @@ -4,13 +4,13 @@ import ( "fmt" "time" - "k8s.io/klog/v2" - appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1" "github.com/openkruise/kruise/pkg/controller/ephemeraljob/econtainer" + "github.com/openkruise/kruise/pkg/util" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" + "k8s.io/klog/v2" ) // pastActiveDeadline checks if job has ActiveDeadlineSeconds field set and if it is exceeded. @@ -29,7 +29,7 @@ func podMatchedEphemeralJob(pod *v1.Pod, ejob *appsv1alpha1.EphemeralJob) (bool, if pod.Namespace != ejob.Namespace { return false, nil } - selector, err := metav1.LabelSelectorAsSelector(ejob.Spec.Selector) + selector, err := util.ValidatedLabelSelectorAsSelector(ejob.Spec.Selector) if err != nil { return false, err } diff --git a/pkg/controller/podunavailablebudget/podunavailablebudget_controller.go b/pkg/controller/podunavailablebudget/podunavailablebudget_controller.go index 7c72807a72..2658e02252 100644 --- a/pkg/controller/podunavailablebudget/podunavailablebudget_controller.go +++ b/pkg/controller/podunavailablebudget/podunavailablebudget_controller.go @@ -400,7 +400,7 @@ func (r *ReconcilePodUnavailableBudget) getPodsForPub(pub *policyv1alpha1.PodUna return nil, nil } // get pods for selector - labelSelector, err := util.GetFastLabelSelector(pub.Spec.Selector) + labelSelector, err := util.ValidatedLabelSelectorAsSelector(pub.Spec.Selector) if err != nil { r.recorder.Eventf(pub, corev1.EventTypeWarning, "Selector", fmt.Sprintf("Label selector failed: %s", err.Error())) return nil, nil diff --git a/pkg/controller/podunavailablebudget/pub_pod_event_handler.go b/pkg/controller/podunavailablebudget/pub_pod_event_handler.go index d671ca8f46..fe06d688c6 100644 --- a/pkg/controller/podunavailablebudget/pub_pod_event_handler.go +++ b/pkg/controller/podunavailablebudget/pub_pod_event_handler.go @@ -121,7 +121,7 @@ func GetPubForPod(c client.Client, pod *corev1.Pod) (*policyv1alpha1.PodUnavaila } } else { // This error is irreversible, so continue - labelSelector, err := util.GetFastLabelSelector(pub.Spec.Selector) + labelSelector, err := util.ValidatedLabelSelectorAsSelector(pub.Spec.Selector) if err != nil { continue } @@ -260,7 +260,7 @@ func (e *SetEnqueueRequestForPUB) addSetRequest(object client.Object, q workqueu } } else { // This error is irreversible, so continue - labelSelector, err := util.GetFastLabelSelector(pub.Spec.Selector) + labelSelector, err := util.ValidatedLabelSelectorAsSelector(pub.Spec.Selector) if err != nil { continue } diff --git a/pkg/controller/resourcedistribution/utils.go b/pkg/controller/resourcedistribution/utils.go index 37179ed279..420c028914 100644 --- a/pkg/controller/resourcedistribution/utils.go +++ b/pkg/controller/resourcedistribution/utils.go @@ -79,7 +79,7 @@ func matchViaIncludedNamespaces(namespace *corev1.Namespace, distributor *appsv1 // matchViaLabelSelector return true if namespace matches with target.NamespacesLabelSelectors func matchViaLabelSelector(namespace *corev1.Namespace, distributor *appsv1alpha1.ResourceDistribution) (bool, error) { - selector, err := metav1.LabelSelectorAsSelector(&distributor.Spec.Targets.NamespaceLabelSelector) + selector, err := util.ValidatedLabelSelectorAsSelector(&distributor.Spec.Targets.NamespaceLabelSelector) if err != nil { return false, err } @@ -302,7 +302,7 @@ func listNamespacesForDistributor(handlerClient client.Client, targets *appsv1al if !targets.AllNamespaces && (len(targets.NamespaceLabelSelector.MatchLabels) != 0 || len(targets.NamespaceLabelSelector.MatchExpressions) != 0) { // 3. select the namespaces via targets.NamespaceLabelSelector - selectors, err := util.GetFastLabelSelector(&targets.NamespaceLabelSelector) + selectors, err := util.ValidatedLabelSelectorAsSelector(&targets.NamespaceLabelSelector) if err != nil { return nil, nil, err } diff --git a/pkg/controller/sidecarset/sidecarset_processor.go b/pkg/controller/sidecarset/sidecarset_processor.go index d8dea97781..9cd1d6309f 100644 --- a/pkg/controller/sidecarset/sidecarset_processor.go +++ b/pkg/controller/sidecarset/sidecarset_processor.go @@ -256,7 +256,7 @@ func (p *Processor) updateSidecarSetStatus(sidecarSet *appsv1alpha1.SidecarSet, // If you need update the pod object, you must DeepCopy it func (p *Processor) getMatchingPods(s *appsv1alpha1.SidecarSet) ([]*corev1.Pod, error) { // get more faster selector - selector, err := util.GetFastLabelSelector(s.Spec.Selector) + selector, err := util.ValidatedLabelSelectorAsSelector(s.Spec.Selector) if err != nil { return nil, err } diff --git a/pkg/controller/sidecarset/sidecarset_strategy.go b/pkg/controller/sidecarset/sidecarset_strategy.go index eb81efe0ee..612d8d25ba 100644 --- a/pkg/controller/sidecarset/sidecarset_strategy.go +++ b/pkg/controller/sidecarset/sidecarset_strategy.go @@ -5,10 +5,10 @@ import ( appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1" "github.com/openkruise/kruise/pkg/control/sidecarcontrol" + "github.com/openkruise/kruise/pkg/util" "github.com/openkruise/kruise/pkg/util/updatesort" corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" intstrutil "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/klog/v2" @@ -48,7 +48,7 @@ func (p *spreadingStrategy) GetNextUpgradePods(control sidecarcontrol.SidecarCon return true } // if selector failed, always return false - selector, err := metav1.LabelSelectorAsSelector(strategy.Selector) + selector, err := util.ValidatedLabelSelectorAsSelector(strategy.Selector) if err != nil { klog.Errorf("sidecarSet(%s) rolling selector error, err: %v", sidecarset.Name, err) return false diff --git a/pkg/controller/statefulset/stateful_set_control.go b/pkg/controller/statefulset/stateful_set_control.go index 7eafc6e9a6..f94fffd1b5 100644 --- a/pkg/controller/statefulset/stateful_set_control.go +++ b/pkg/controller/statefulset/stateful_set_control.go @@ -25,7 +25,6 @@ import ( apps "k8s.io/api/apps/v1" v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" utilerrors "k8s.io/apimachinery/pkg/util/errors" intstrutil "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/sets" @@ -38,6 +37,7 @@ import ( appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1" appsv1beta1 "github.com/openkruise/kruise/apis/apps/v1beta1" "github.com/openkruise/kruise/pkg/features" + "github.com/openkruise/kruise/pkg/util" utilfeature "github.com/openkruise/kruise/pkg/util/feature" imagejobutilfunc "github.com/openkruise/kruise/pkg/util/imagejob/utilfunction" "github.com/openkruise/kruise/pkg/util/inplaceupdate" @@ -161,7 +161,7 @@ func (ssc *defaultStatefulSetControl) performUpdate( } func (ssc *defaultStatefulSetControl) ListRevisions(set *appsv1beta1.StatefulSet) ([]*apps.ControllerRevision, error) { - selector, err := metav1.LabelSelectorAsSelector(set.Spec.Selector) + selector, err := util.ValidatedLabelSelectorAsSelector(set.Spec.Selector) if err != nil { return nil, err } @@ -306,7 +306,7 @@ func (ssc *defaultStatefulSetControl) updateStatefulSet( collisionCount int32, pods []*v1.Pod, revisions []*apps.ControllerRevision) (*appsv1beta1.StatefulSetStatus, error) { - selector, err := metav1.LabelSelectorAsSelector(set.Spec.Selector) + selector, err := util.ValidatedLabelSelectorAsSelector(set.Spec.Selector) if err != nil { return set.Status.DeepCopy(), err } diff --git a/pkg/controller/workloadspread/workloadspread_controller.go b/pkg/controller/workloadspread/workloadspread_controller.go index 0bf2877e96..a3fe0308b3 100644 --- a/pkg/controller/workloadspread/workloadspread_controller.go +++ b/pkg/controller/workloadspread/workloadspread_controller.go @@ -232,7 +232,7 @@ func (r *ReconcileWorkloadSpread) getPodJob(ref *appsv1alpha1.TargetReference, n return nil, -1, err } - labelSelector, err := util.GetFastLabelSelector(job.Spec.Selector) + labelSelector, err := util.ValidatedLabelSelectorAsSelector(job.Spec.Selector) if err != nil { klog.Errorf("gets labelSelector failed: %s", err.Error()) return nil, -1, nil diff --git a/pkg/util/controllerfinder/pods_finder.go b/pkg/util/controllerfinder/pods_finder.go index 40e5d2e224..509d761c66 100644 --- a/pkg/util/controllerfinder/pods_finder.go +++ b/pkg/util/controllerfinder/pods_finder.go @@ -19,6 +19,7 @@ package controllerfinder import ( "context" + "github.com/openkruise/kruise/pkg/util" utilclient "github.com/openkruise/kruise/pkg/util/client" "github.com/openkruise/kruise/pkg/util/fieldindex" appsv1 "k8s.io/api/apps/v1" @@ -113,7 +114,7 @@ func (r *ControllerFinder) getReplicaSetsForDeployment(apiVersion, kind, ns, nam } // List ReplicaSets owned by this Deployment rsList := &appsv1.ReplicaSetList{} - selector, err := metav1.LabelSelectorAsSelector(scaleNSelector.Selector) + selector, err := util.ValidatedLabelSelectorAsSelector(scaleNSelector.Selector) if err != nil { klog.Errorf("Deployment (%s/%s) get labelSelector failed: %s", ns, name, err.Error()) return nil, nil diff --git a/pkg/util/history/controller_history_test.go b/pkg/util/history/controller_history_test.go index 61ef09a89d..3be9c12d3e 100644 --- a/pkg/util/history/controller_history_test.go +++ b/pkg/util/history/controller_history_test.go @@ -21,6 +21,7 @@ import ( "testing" appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1" + "github.com/openkruise/kruise/pkg/util" apps "k8s.io/api/apps/v1" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -81,7 +82,7 @@ func TestRevisionHistory(t *testing.T) { t.Fatalf("Expected ControllerRevision name %v, got %v", expectedName, newCR.Name) } - selector, _ := metav1.LabelSelectorAsSelector(parent.Spec.Selector) + selector, _ := util.ValidatedLabelSelectorAsSelector(parent.Spec.Selector) gotRevisions, err := historyControl.ListControllerRevisions(parent, selector) if err != nil { t.Fatalf("Failed to list revisions: %v", err) diff --git a/pkg/util/imagejob/imagejob_reader.go b/pkg/util/imagejob/imagejob_reader.go index ff7c498a2a..3e5b6a2b61 100644 --- a/pkg/util/imagejob/imagejob_reader.go +++ b/pkg/util/imagejob/imagejob_reader.go @@ -72,7 +72,7 @@ func GetNodeImagesForJob(reader client.Reader, job *appsv1alpha1.ImagePullJob) ( }() if job.Spec.PodSelector != nil { - selector, err := util.GetFastLabelSelector(&job.Spec.PodSelector.LabelSelector) + selector, err := util.ValidatedLabelSelectorAsSelector(&job.Spec.PodSelector.LabelSelector) if err != nil { return nil, fmt.Errorf("parse podSelector error: %v", err) } @@ -143,7 +143,7 @@ func GetNodeImagesForJob(reader client.Reader, job *appsv1alpha1.ImagePullJob) ( return nodeImages, nil } - selector, err := util.GetFastLabelSelector(&job.Spec.Selector.LabelSelector) + selector, err := util.ValidatedLabelSelectorAsSelector(&job.Spec.Selector.LabelSelector) if err != nil { return nil, fmt.Errorf("parse selector error: %v", err) } @@ -173,7 +173,7 @@ func GetActiveJobsForNodeImage(reader client.Reader, nodeImage, oldNodeImage *ap var oldMatched bool if job.Spec.PodSelector != nil { - selector, err := util.GetFastLabelSelector(&job.Spec.PodSelector.LabelSelector) + selector, err := util.ValidatedLabelSelectorAsSelector(&job.Spec.PodSelector.LabelSelector) if err != nil { return nil, nil, fmt.Errorf("parse podSelector for %s/%s error: %v", job.Namespace, job.Name, err) } @@ -198,7 +198,7 @@ func GetActiveJobsForNodeImage(reader client.Reader, nodeImage, oldNodeImage *ap oldMatched = true } } else { - selector, err := util.GetFastLabelSelector(&job.Spec.Selector.LabelSelector) + selector, err := util.ValidatedLabelSelectorAsSelector(&job.Spec.Selector.LabelSelector) if err != nil { return nil, nil, fmt.Errorf("parse selector for %s/%s error: %v", job.Namespace, job.Name, err) } @@ -244,7 +244,7 @@ func GetActiveJobsForPod(reader client.Reader, pod, oldPod *v1.Pod) (newJobs, ol job := &jobList.Items[i] if job.Spec.PodSelector != nil { - selector, err := util.GetFastLabelSelector(&job.Spec.PodSelector.LabelSelector) + selector, err := util.ValidatedLabelSelectorAsSelector(&job.Spec.PodSelector.LabelSelector) if err != nil { return nil, nil, fmt.Errorf("parse podSelector for %s/%s error: %v", job.Namespace, job.Name, err) } diff --git a/pkg/util/refmanager/ref_manager.go b/pkg/util/refmanager/ref_manager.go index cbd95f9f9b..9286983ce2 100644 --- a/pkg/util/refmanager/ref_manager.go +++ b/pkg/util/refmanager/ref_manager.go @@ -23,6 +23,7 @@ import ( "reflect" "sync" + "github.com/openkruise/kruise/pkg/util" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" @@ -47,7 +48,7 @@ type RefManager struct { // New returns a RefManager that exposes // methods to manage the controllerRef of pods. func New(client client.Client, selector *metav1.LabelSelector, owner metav1.Object, schema *runtime.Scheme) (*RefManager, error) { - s, err := metav1.LabelSelectorAsSelector(selector) + s, err := util.ValidatedLabelSelectorAsSelector(selector) if err != nil { return nil, err } diff --git a/pkg/util/selector.go b/pkg/util/selector.go index 8b712fb71f..1b41b28044 100644 --- a/pkg/util/selector.go +++ b/pkg/util/selector.go @@ -17,8 +17,13 @@ limitations under the License. package util import ( + "fmt" + "reflect" + "unsafe" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/selection" "k8s.io/kubernetes/pkg/util/slice" ) @@ -115,14 +120,65 @@ func sliceContains(a, b []string) bool { return true } -func GetFastLabelSelector(ps *metav1.LabelSelector) (labels.Selector, error) { - var selector labels.Selector - if len(ps.MatchExpressions) == 0 && len(ps.MatchLabels) != 0 { - selector = labels.SelectorFromValidatedSet(ps.MatchLabels) - return selector, nil +func ValidatedLabelSelectorAsSelector(ps *metav1.LabelSelector) (labels.Selector, error) { + if ps == nil { + return labels.Nothing(), nil + } + if len(ps.MatchLabels)+len(ps.MatchExpressions) == 0 { + return labels.Everything(), nil + } + + selector := labels.NewSelector() + for k, v := range ps.MatchLabels { + r, err := newRequirement(k, selection.Equals, []string{v}) + if err != nil { + return nil, err + } + selector = selector.Add(*r) + } + for _, expr := range ps.MatchExpressions { + var op selection.Operator + switch expr.Operator { + case metav1.LabelSelectorOpIn: + op = selection.In + case metav1.LabelSelectorOpNotIn: + op = selection.NotIn + case metav1.LabelSelectorOpExists: + op = selection.Exists + case metav1.LabelSelectorOpDoesNotExist: + op = selection.DoesNotExist + default: + return nil, fmt.Errorf("%q is not a valid pod selector operator", expr.Operator) + } + r, err := newRequirement(expr.Key, op, append([]string(nil), expr.Values...)) + if err != nil { + return nil, err + } + selector = selector.Add(*r) + } + return selector, nil +} + +func newRequirement(key string, op selection.Operator, vals []string) (*labels.Requirement, error) { + sel := &labels.Requirement{} + selVal := reflect.ValueOf(sel) + val := reflect.Indirect(selVal) + + keyField := val.FieldByName("key") + keyFieldPtr := (*string)(unsafe.Pointer(keyField.UnsafeAddr())) + *keyFieldPtr = key + + opField := val.FieldByName("operator") + opFieldPtr := (*selection.Operator)(unsafe.Pointer(opField.UnsafeAddr())) + *opFieldPtr = op + + if len(vals) > 0 { + valuesField := val.FieldByName("strValues") + valuesFieldPtr := (*[]string)(unsafe.Pointer(valuesField.UnsafeAddr())) + *valuesFieldPtr = vals } - return metav1.LabelSelectorAsSelector(ps) + return sel, nil } // whether selectors overlap (indicates that selector1, selector2 have same key, and there is an certain intersection) diff --git a/pkg/util/selector_test.go b/pkg/util/selector_test.go index 2634ef913a..fb6acc024b 100644 --- a/pkg/util/selector_test.go +++ b/pkg/util/selector_test.go @@ -17,6 +17,7 @@ limitations under the License. package util import ( + "reflect" "testing" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -503,3 +504,79 @@ func TestIsMatchExpOverlap(t *testing.T) { }) } } + +func TestValidatedLabelSelectorAsSelector(t *testing.T) { + labelSelectors := []metav1.LabelSelector{ + { + MatchLabels: map[string]string{"k1": "A", "k2": "B"}, + }, + { + MatchExpressions: []metav1.LabelSelectorRequirement{ + {Key: "k3", Operator: metav1.LabelSelectorOpIn, Values: []string{"C", "D"}}, + {Key: "k4", Operator: metav1.LabelSelectorOpNotIn, Values: []string{"E"}}, + {Key: "k5", Operator: metav1.LabelSelectorOpExists}, + {Key: "k6", Operator: metav1.LabelSelectorOpDoesNotExist}, + }, + }, + { + MatchLabels: map[string]string{"k1": "A", "k2": "B"}, + MatchExpressions: []metav1.LabelSelectorRequirement{ + {Key: "k3", Operator: metav1.LabelSelectorOpIn, Values: []string{"C", "D"}}, + {Key: "k4", Operator: metav1.LabelSelectorOpNotIn, Values: []string{"E"}}, + {Key: "k5", Operator: metav1.LabelSelectorOpExists}, + {Key: "k6", Operator: metav1.LabelSelectorOpDoesNotExist}, + }, + }, + { + MatchExpressions: []metav1.LabelSelectorRequirement{ + {Key: "k7", Operator: metav1.LabelSelectorOpIn, Values: []string{"F", "G"}}, + {Key: "k7", Operator: metav1.LabelSelectorOpNotIn, Values: []string{"H"}}, + }, + }, + } + + for _, ps := range labelSelectors { + sel1, err := metav1.LabelSelectorAsSelector(&ps) + if err != nil { + t.Fatalf("Failed LabelSelectorAsSelector for %v: %v", DumpJSON(ps), err) + } + sel2, err := ValidatedLabelSelectorAsSelector(&ps) + if err != nil { + t.Fatalf("Failed ValidatedLabelSelectorAsSelector for %v: %v", DumpJSON(ps), err) + } + if !reflect.DeepEqual(sel1, sel2) { + t.Fatalf("Expected selector %+v, got %+v", sel1, sel2) + } + } +} + +var ( + benchSelector = &metav1.LabelSelector{ + MatchExpressions: []metav1.LabelSelectorRequirement{ + { + Key: "apps.kruise.io/foo", + Operator: metav1.LabelSelectorOpIn, + Values: []string{"Hello", "World"}, + }, + { + Key: "apps.kruise.io/bar", + Operator: metav1.LabelSelectorOpNotIn, + Values: []string{"Hello", "World"}, + }, + }, + } +) + +func BenchmarkValidatedLabelSelectorAsSelector(b *testing.B) { + b.ReportAllocs() + for n := 0; n < b.N; n++ { + ValidatedLabelSelectorAsSelector(benchSelector) + } +} + +func BenchmarkOriginalLabelSelectorAsSelector(b *testing.B) { + b.ReportAllocs() + for n := 0; n < b.N; n++ { + metav1.LabelSelectorAsSelector(benchSelector) + } +} diff --git a/pkg/util/updatesort/priority_sort.go b/pkg/util/updatesort/priority_sort.go index 0084eba570..9c7a7dd0c3 100644 --- a/pkg/util/updatesort/priority_sort.go +++ b/pkg/util/updatesort/priority_sort.go @@ -21,8 +21,8 @@ import ( "strconv" appspub "github.com/openkruise/kruise/apis/apps/pub" + "github.com/openkruise/kruise/pkg/util" v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" ) @@ -70,7 +70,7 @@ func (ps *prioritySort) compare(podI, podJ map[string]string, defaultVal bool) b func (ps *prioritySort) getPodWeightPriority(podLabels map[string]string) int64 { var weight int64 for _, p := range ps.strategy.WeightPriority { - selector, err := metav1.LabelSelectorAsSelector(&p.MatchSelector) + selector, err := util.ValidatedLabelSelectorAsSelector(&p.MatchSelector) if err != nil { continue } diff --git a/test/e2e/framework/cloneset_util.go b/test/e2e/framework/cloneset_util.go index 5ae4a80ab9..04f4d37ea7 100644 --- a/test/e2e/framework/cloneset_util.go +++ b/test/e2e/framework/cloneset_util.go @@ -131,7 +131,7 @@ func (t *CloneSetTester) DeleteCloneSet(name string) error { } func (s *CloneSetTester) GetSelectorPods(namespace string, selector *metav1.LabelSelector) ([]v1.Pod, error) { - faster, err := util.GetFastLabelSelector(selector) + faster, err := util.ValidatedLabelSelectorAsSelector(selector) if err != nil { return nil, err } diff --git a/test/e2e/framework/deployment_util.go b/test/e2e/framework/deployment_util.go index 754a1f9919..526cd79986 100644 --- a/test/e2e/framework/deployment_util.go +++ b/test/e2e/framework/deployment_util.go @@ -77,7 +77,7 @@ func (t *DeploymentTester) GetDeployment(name string) (*appsv1.Deployment, error } func (t *DeploymentTester) GetSelectorPods(namespace string, selector *metav1.LabelSelector) ([]v1.Pod, error) { - faster, err := util.GetFastLabelSelector(selector) + faster, err := util.ValidatedLabelSelectorAsSelector(selector) if err != nil { return nil, err } diff --git a/test/e2e/framework/resourcedistribution_utils.go b/test/e2e/framework/resourcedistribution_utils.go index f5dc6d7382..bbcd8ada4d 100644 --- a/test/e2e/framework/resourcedistribution_utils.go +++ b/test/e2e/framework/resourcedistribution_utils.go @@ -379,7 +379,7 @@ func (s *ResourceDistributionTester) GetNamespaceForDistributor(targets *appsv1a } } else if len(targets.NamespaceLabelSelector.MatchLabels) != 0 || len(targets.NamespaceLabelSelector.MatchExpressions) != 0 { // 1. select the namespaces via targets.NamespaceLabelSelector - selectors, err := util.GetFastLabelSelector(&targets.NamespaceLabelSelector) + selectors, err := util.ValidatedLabelSelectorAsSelector(&targets.NamespaceLabelSelector) if err != nil { return nil, nil, err } diff --git a/test/e2e/framework/sidecarset_utils.go b/test/e2e/framework/sidecarset_utils.go index 3b5f3a5f8f..ec38759c24 100644 --- a/test/e2e/framework/sidecarset_utils.go +++ b/test/e2e/framework/sidecarset_utils.go @@ -318,7 +318,7 @@ func (s *SidecarSetTester) WaitForSidecarSetDeleted(sidecarSet *appsv1alpha1.Sid } func (s *SidecarSetTester) GetSelectorPods(namespace string, selector *metav1.LabelSelector) ([]*corev1.Pod, error) { - faster, err := util.GetFastLabelSelector(selector) + faster, err := util.ValidatedLabelSelectorAsSelector(selector) if err != nil { return nil, err } @@ -412,7 +412,7 @@ func (t *SidecarSetTester) WaitForCloneSetRunning(cloneset *appsv1alpha1.CloneSe } func (t *SidecarSetTester) ListControllerRevisions(sidecarSet *appsv1alpha1.SidecarSet) []*apps.ControllerRevision { - selector, err := util.GetFastLabelSelector(&metav1.LabelSelector{MatchLabels: map[string]string{ + selector, err := util.ValidatedLabelSelectorAsSelector(&metav1.LabelSelector{MatchLabels: map[string]string{ sidecarcontrol.SidecarSetKindName: sidecarSet.Name, }}) gomega.Expect(err).NotTo(gomega.HaveOccurred()) diff --git a/test/e2e/framework/workloadspread_util.go b/test/e2e/framework/workloadspread_util.go index 80d77e3b7f..745f9361ab 100644 --- a/test/e2e/framework/workloadspread_util.go +++ b/test/e2e/framework/workloadspread_util.go @@ -412,7 +412,7 @@ func (t *WorkloadSpreadTester) WaitJobCompleted(job *batchv1.Job) { } func (t *WorkloadSpreadTester) GetSelectorPods(namespace string, selector *metav1.LabelSelector) ([]corev1.Pod, error) { - faster, err := util.GetFastLabelSelector(selector) + faster, err := util.ValidatedLabelSelectorAsSelector(selector) if err != nil { return nil, err }