Skip to content

Commit

Permalink
get workqueue priority from namespace label
Browse files Browse the repository at this point in the history
  • Loading branch information
shaofan-hs authored and shaofan-hs committed Dec 11, 2023
1 parent 91d29b6 commit 5563492
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 179 deletions.
48 changes: 14 additions & 34 deletions controller/workqueue/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,13 @@ var (
DefaultNumOfPriorityLotteries = []int{1, 2, 4, 8, 16}
)

func DefaultGetPriorityFuncBuilder(cli client.Client, objectGetter func() client.Object) GetPriorityFunc {
return GetPriorityFuncBuilder(cli, objectGetter, DefaultWorkQueuePriorityLabel, DefaultWorkQueuePriority)
func DefaultGetPriorityFuncBuilder(cli client.Client) GetPriorityFunc {
return GetPriorityFuncBuilder(cli, DefaultWorkQueuePriorityLabel, DefaultWorkQueuePriority)
}

// GetPriorityFunc is the function to get the priority of an item
// We use the label to get the priority of an item
// If the label is not set in the item, we will get the priority from the namespace label
func GetPriorityFuncBuilder(cli client.Client, objectGetter func() client.Object, workQueuePriorityLabel string, defaultWorkQueuePriority int) GetPriorityFunc {
// We use the namespace label to get the priority of an item
func GetPriorityFuncBuilder(cli client.Client, workQueuePriorityLabel string, defaultWorkQueuePriority int) GetPriorityFunc {
if cli == nil {
panic("cli is required")
}
Expand All @@ -54,45 +53,26 @@ func GetPriorityFuncBuilder(cli client.Client, objectGetter func() client.Object

return func(item interface{}) int {
req, ok := item.(reconcile.Request)
if !ok {
return defaultWorkQueuePriority
}

object := objectGetter()
err := cli.Get(context.Background(), req.NamespacedName, object)
if err != nil {
klog.Errorf("Failed to get object: %v, error: %v", req.NamespacedName, err)
if !ok || req.Namespace == "" {
return defaultWorkQueuePriority
}

var priorityLableValue string
labels := object.GetLabels()
if len(labels) != 0 {
priorityLableValue = labels[workQueuePriorityLabel]
}

if priorityLableValue == "" {
if req.Namespace == "" {
namespace := &corev1.Namespace{}
if err := cli.Get(context.Background(), client.ObjectKey{Name: req.Namespace}, namespace); err != nil {
klog.Errorf("Failed to get namespace: %v, error: %v", req.Namespace, err)
return defaultWorkQueuePriority
} else {
labels := namespace.GetLabels()
if len(labels) == 0 {
return defaultWorkQueuePriority
}

namespace := &corev1.Namespace{}
if err := cli.Get(context.Background(), client.ObjectKey{Name: req.Namespace}, namespace); err != nil {
klog.Errorf("Failed to get namespace: %v, error: %v", req.Namespace, err)
priorityLableValue, ok = namespace.Labels[workQueuePriorityLabel]
if !ok {
return defaultWorkQueuePriority
} else {
labels := namespace.GetLabels()
if len(labels) == 0 {
return defaultWorkQueuePriority
}
priorityLableValue = namespace.Labels[workQueuePriorityLabel]
}
}

if priorityLableValue == "" {
return defaultWorkQueuePriority
}

priority, err := strconv.Atoi(priorityLableValue)
if err != nil {
klog.Errorf("Failed to convert label value: %q to int, error: %v", priorityLableValue, err)
Expand Down
133 changes: 24 additions & 109 deletions controller/workqueue/defaults_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,142 +32,58 @@ import (

var _ = Describe("Test defaults", func() {
const (
testConfigmap = "configmap1"
testObject = "object1"
testNamespace = "default"
)

var (
objectGetter = func() client.Object {
return &corev1.ConfigMap{}
}
req = reconcile.Request{NamespacedName: client.ObjectKey{
Name: testConfigmap,
Name: testObject,
Namespace: testNamespace,
}}
)

Context("Use default workqueue priority", func() {
It("Should get default workqueue priority if the item has no labels", func() {
err := ensureConfigmap(k8sClient, testNamespace, testConfigmap, DefaultWorkQueuePriorityLabel, "")
Context("Use default workqueue priority label", func() {
It("Should get default priority if default workqueue priority label nil", func() {
err := ensureNamespace(k8sClient, testNamespace, DefaultWorkQueuePriorityLabel, "")
Expect(err).NotTo(HaveOccurred())

getPriorityFunc := DefaultGetPriorityFuncBuilder(k8sClient, objectGetter)
getPriorityFunc := DefaultGetPriorityFuncBuilder(k8sClient)
priority := getPriorityFunc(req)
Expect(priority).To(Equal(DefaultWorkQueuePriority))
})

It("Should get workqueue priority from default item priority label", func() {
err := ensureConfigmap(k8sClient, testNamespace, testConfigmap, DefaultWorkQueuePriorityLabel, "3")
Expect(err).NotTo(HaveOccurred())

getPriorityFunc := DefaultGetPriorityFuncBuilder(k8sClient, objectGetter)
priority := getPriorityFunc(req)
Expect(priority).To(Equal(3))
})

It("Should get workqueue priority from default namesapce priority label", func() {
err := ensureConfigmap(k8sClient, testNamespace, testConfigmap, DefaultWorkQueuePriorityLabel, "")
Expect(err).NotTo(HaveOccurred())

err = ensureNamespace(k8sClient, testNamespace, DefaultWorkQueuePriorityLabel, "4")
It("Should get workqueue priority from default workqueue priority label", func() {
err := ensureNamespace(k8sClient, testNamespace, DefaultWorkQueuePriorityLabel, "4")
Expect(err).NotTo(HaveOccurred())

getPriorityFunc := DefaultGetPriorityFuncBuilder(k8sClient, objectGetter)
getPriorityFunc := DefaultGetPriorityFuncBuilder(k8sClient)
priority := getPriorityFunc(req)
Expect(priority).To(Equal(4))
})
})

Context("Use custom workqueue priority", func() {
It("Should get default workqueue priority if the item has no labels", func() {
err := ensureConfigmap(k8sClient, testNamespace, testConfigmap, "custom-priority", "")
Context("Use custom workqueue priority label", func() {
It("Should get default priority if custom workqueue priority label nil", func() {
err := ensureNamespace(k8sClient, testNamespace, "custom-priority", "4")
Expect(err).NotTo(HaveOccurred())

getPriorityFunc := GetPriorityFuncBuilder(k8sClient, objectGetter, "custom-priority", 1)
getPriorityFunc := GetPriorityFuncBuilder(k8sClient, "custom-priority", 1)
priority := getPriorityFunc(req)
Expect(priority).To(Equal(1))
})

It("Should get workqueue priority from custom item priority label", func() {
err := ensureConfigmap(k8sClient, testNamespace, testConfigmap, "custom-priority", "3")
Expect(err).NotTo(HaveOccurred())

getPriorityFunc := GetPriorityFuncBuilder(k8sClient, objectGetter, "custom-priority", 1)
priority := getPriorityFunc(req)
Expect(priority).To(Equal(3))
Expect(priority).To(Equal(4))
})

It("Should get workqueue priority from custom namesapce priority label", func() {
err := ensureConfigmap(k8sClient, testNamespace, testConfigmap, "custom-priority", "")
It("Should get workqueue priority from custom workqueue priority label", func() {
err := ensureNamespace(k8sClient, testNamespace, "custom-priority", "4")
Expect(err).NotTo(HaveOccurred())

err = ensureNamespace(k8sClient, testNamespace, "custom-priority", "4")
Expect(err).NotTo(HaveOccurred())

getPriorityFunc := GetPriorityFuncBuilder(k8sClient, objectGetter, "custom-priority", 1)
getPriorityFunc := GetPriorityFuncBuilder(k8sClient, "custom-priority", 1)
priority := getPriorityFunc(req)
Expect(priority).To(Equal(4))
})
})
})

func ensureConfigmap(cli client.Client, namespace, name, priorityLabelKey, priorityLabelValue string) error {
// Ensure the configmap exists
configmap := &corev1.ConfigMap{}
err := cli.Get(context.Background(), client.ObjectKey{Name: name, Namespace: namespace}, configmap)
if err != nil {
if errors.IsNotFound(err) {
labels := map[string]string{}
if priorityLabelValue != "" {
labels[priorityLabelKey] = priorityLabelValue
}

err := cli.Create(context.Background(), &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
Labels: labels,
},
})
return err
}
return err
}

// If the label is already set, we don't need to update it
labelValue, ok := configmap.Labels[priorityLabelKey]
if !ok && priorityLabelValue == "" {
return nil
} else if ok && labelValue == priorityLabelValue {
return nil
}

// If the label is not set, we need to set it
if priorityLabelValue == "" {
configmap.Labels = map[string]string{}
} else {
configmap.Labels = map[string]string{
priorityLabelKey: priorityLabelValue,
}
}

// Update the configmap
err = cli.Update(context.Background(), configmap)
if err != nil {
return err
}
Eventually(func() bool {
configmap1 := &corev1.ConfigMap{}
err := cli.Get(context.Background(), client.ObjectKey{Name: name, Namespace: namespace}, configmap1)
if err != nil {
return false
}
return configmap1.ResourceVersion >= configmap.ResourceVersion
}, time.Second*3, time.Millisecond*100).Should(BeTrue())

return nil
}

func ensureNamespace(cli client.Client, name, priorityLabelKey, priorityLabelValue string) error {
// Ensure the namespace exists
namespace := &corev1.Namespace{}
Expand All @@ -190,17 +106,16 @@ func ensureNamespace(cli client.Client, name, priorityLabelKey, priorityLabelVal
}

// If the label is already set, we don't need to update it
labelValue, ok := namespace.Labels[priorityLabelKey]
if !ok && priorityLabelValue == "" {
return nil
} else if ok && labelValue == priorityLabelValue {
return nil
}

// If the label is not set, we need to set it
priority, ok := namespace.Labels[priorityLabelKey]
if priorityLabelValue == "" {
if !ok {
return nil
}
namespace.Labels = map[string]string{}
} else {
if ok && priority == priorityLabelValue {
return nil
}
namespace.Labels = map[string]string{
priorityLabelKey: priorityLabelValue,
}
Expand Down
Loading

0 comments on commit 5563492

Please sign in to comment.