Skip to content

Commit 31c7fee

Browse files
committed
redesign device plugin
always deploy sriov network device plugin and use a label to enable or disable it on the nodes Signed-off-by: Sebastian Sch <[email protected]>
1 parent 823b4d4 commit 31c7fee

File tree

10 files changed

+92
-89
lines changed

10 files changed

+92
-89
lines changed

controllers/sriovnetworknodepolicy_controller.go

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"context"
2121
"encoding/json"
2222
"fmt"
23+
"github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/utils"
2324
"reflect"
2425
"sort"
2526
"strings"
@@ -133,10 +134,6 @@ func (r *SriovNetworkNodePolicyReconciler) Reconcile(ctx context.Context, req ct
133134
if err = r.syncDevicePluginConfigMap(ctx, defaultOpConf, policyList, nodeList); err != nil {
134135
return reconcile.Result{}, err
135136
}
136-
// Render and sync Daemon objects
137-
if err = syncPluginDaemonObjs(ctx, r.Client, r.Scheme, defaultOpConf, policyList); err != nil {
138-
return reconcile.Result{}, err
139-
}
140137

141138
// All was successful. Request that this be re-triggered after ResyncPeriod,
142139
// so we can reconcile state again.
@@ -219,6 +216,30 @@ func (r *SriovNetworkNodePolicyReconciler) syncDevicePluginConfigMap(ctx context
219216
return err
220217
}
221218
configData[node.Name] = string(config)
219+
220+
if data.ResourceList == nil || len(data.ResourceList) == 0 {
221+
// if we don't have policies we should add the disabled label for the device plugin
222+
err = utils.LabelNode(ctx, node.Name, constants.SriovDevicePluginLabel, constants.SriovDevicePluginLabelDisabled, r.Client)
223+
if err != nil {
224+
logger.Error(err, "failed to label node for device plugin label",
225+
"labelKey",
226+
constants.SriovDevicePluginLabel,
227+
"labelValue",
228+
constants.SriovDevicePluginLabelDisabled)
229+
return err
230+
}
231+
} else {
232+
// if we have policies we should add the enabled label for the device plugin
233+
err = utils.LabelNode(ctx, node.Name, constants.SriovDevicePluginLabel, constants.SriovDevicePluginLabelEnabled, r.Client)
234+
if err != nil {
235+
logger.Error(err, "failed to label node for device plugin label",
236+
"labelKey",
237+
constants.SriovDevicePluginLabel,
238+
"labelValue",
239+
constants.SriovDevicePluginLabelEnabled)
240+
return err
241+
}
242+
}
222243
}
223244

224245
cm := &corev1.ConfigMap{

controllers/sriovoperatorconfig_controller.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,12 @@ import (
4444
machinev1 "github.com/openshift/machine-config-operator/pkg/apis/machineconfiguration.openshift.io/v1"
4545

4646
sriovnetworkv1 "github.com/k8snetworkplumbingwg/sriov-network-operator/api/v1"
47-
apply "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/apply"
48-
consts "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/consts"
47+
"github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/apply"
48+
"github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/consts"
4949
"github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/featuregate"
5050
snolog "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/log"
5151
"github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/platforms"
52-
render "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/render"
52+
"github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/render"
5353
"github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/vars"
5454
)
5555

@@ -140,7 +140,7 @@ func (r *SriovOperatorConfigReconciler) Reconcile(ctx context.Context, req ctrl.
140140
return reconcile.Result{}, err
141141
}
142142

143-
if err = syncPluginDaemonObjs(ctx, r.Client, r.Scheme, defaultConfig, policyList); err != nil {
143+
if err = syncPluginDaemonObjs(ctx, r.Client, r.Scheme, defaultConfig); err != nil {
144144
return reconcile.Result{}, err
145145
}
146146

controllers/sriovoperatorconfig_controller_test.go

Lines changed: 2 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package controllers
22

33
import (
44
"context"
5-
"fmt"
65
"os"
76
"strings"
87
"sync"
@@ -30,7 +29,7 @@ import (
3029
mock_platforms "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/platforms/mock"
3130
"github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/platforms/openshift"
3231
"github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/vars"
33-
util "github.com/k8snetworkplumbingwg/sriov-network-operator/test/util"
32+
"github.com/k8snetworkplumbingwg/sriov-network-operator/test/util"
3433
)
3534

3635
var _ = Describe("SriovOperatorConfig controller", Ordered, func() {
@@ -427,7 +426,7 @@ var _ = Describe("SriovOperatorConfig controller", Ordered, func() {
427426
metricsDaemonset := appsv1.DaemonSet{}
428427
err := util.WaitForNamespacedObject(&metricsDaemonset, k8sClient, testNamespace, "sriov-network-metrics-exporter", util.RetryInterval, util.APITimeout)
429428
g.Expect(err).NotTo(HaveOccurred())
430-
g.Expect(metricsDaemonset.Spec.Template.Spec.NodeSelector).To((Equal(nodeSelector)))
429+
g.Expect(metricsDaemonset.Spec.Template.Spec.NodeSelector).To(Equal(nodeSelector))
431430
}).Should(Succeed())
432431
})
433432

@@ -521,53 +520,6 @@ var _ = Describe("SriovOperatorConfig controller", Ordered, func() {
521520
g.Expect(injectorCfg.Webhooks[0].ClientConfig.CABundle).To(Equal([]byte("ca-bundle-2\n")))
522521
}, "1s").Should(Succeed())
523522
})
524-
525-
It("should reconcile to a converging state when multiple node policies are set", func() {
526-
By("Creating a consistent number of node policies")
527-
for i := 0; i < 30; i++ {
528-
p := &sriovnetworkv1.SriovNetworkNodePolicy{
529-
ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace, Name: fmt.Sprintf("p%d", i)},
530-
Spec: sriovnetworkv1.SriovNetworkNodePolicySpec{
531-
Priority: 99,
532-
NodeSelector: map[string]string{"foo": fmt.Sprintf("v%d", i)},
533-
},
534-
}
535-
err := k8sClient.Create(context.Background(), p)
536-
Expect(err).NotTo(HaveOccurred())
537-
}
538-
539-
By("Triggering a the reconcile loop")
540-
config := &sriovnetworkv1.SriovOperatorConfig{}
541-
err := k8sClient.Get(context.Background(), types.NamespacedName{Name: "default", Namespace: testNamespace}, config)
542-
Expect(err).NotTo(HaveOccurred())
543-
if config.ObjectMeta.Labels == nil {
544-
config.ObjectMeta.Labels = make(map[string]string)
545-
}
546-
config.ObjectMeta.Labels["trigger-test"] = "test-reconcile-daemonset"
547-
err = k8sClient.Update(context.Background(), config)
548-
Expect(err).NotTo(HaveOccurred())
549-
550-
By("Wait until device-plugin Daemonset's affinity has been calculated")
551-
var expectedAffinity *corev1.Affinity
552-
553-
Eventually(func(g Gomega) {
554-
daemonSet := &appsv1.DaemonSet{}
555-
err = k8sClient.Get(context.Background(), types.NamespacedName{Name: "sriov-device-plugin", Namespace: testNamespace}, daemonSet)
556-
g.Expect(err).NotTo(HaveOccurred())
557-
// Wait until the last policy (with NodeSelector foo=v29) has been considered at least one time
558-
g.Expect(daemonSet.Spec.Template.Spec.Affinity.String()).To(ContainSubstring("v29"))
559-
expectedAffinity = daemonSet.Spec.Template.Spec.Affinity
560-
}, "3s", "1s").Should(Succeed())
561-
562-
By("Verify device-plugin Daemonset's affinity doesn't change over time")
563-
Consistently(func(g Gomega) {
564-
daemonSet := &appsv1.DaemonSet{}
565-
err = k8sClient.Get(context.Background(), types.NamespacedName{Name: "sriov-device-plugin", Namespace: testNamespace}, daemonSet)
566-
g.Expect(err).NotTo(HaveOccurred())
567-
g.Expect(daemonSet.Spec.Template.Spec.Affinity).
568-
To(Equal(expectedAffinity))
569-
}, "3s", "1s").Should(Succeed())
570-
})
571523
})
572524
})
573525

controllers/suite_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,13 @@ var _ = BeforeSuite(func() {
188188
}
189189
Expect(k8sClient.Create(context.Background(), ns)).Should(Succeed())
190190

191+
sa := &corev1.ServiceAccount{TypeMeta: metav1.TypeMeta{},
192+
ObjectMeta: metav1.ObjectMeta{
193+
Name: "default",
194+
Namespace: testNamespace,
195+
}}
196+
Expect(k8sClient.Create(context.Background(), sa)).Should(Succeed())
197+
191198
// Create openshift Infrastructure
192199
infra := &openshiftconfigv1.Infrastructure{
193200
ObjectMeta: metav1.ObjectMeta{

deploy/clusterrole.yaml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,6 @@ rules:
4545
- apiGroups: [""]
4646
resources: ["nodes"]
4747
verbs: ["get", "list", "watch", "patch", "update"]
48-
- apiGroups: [""]
49-
resources: ["pods"]
50-
verbs: ["*"]
51-
- apiGroups: ["apps"]
52-
resources: ["daemonsets"]
53-
verbs: ["get"]
5448
- apiGroups: [ "config.openshift.io" ]
5549
resources: [ "infrastructures" ]
5650
verbs: [ "get", "list", "watch" ]

deploy/role.yaml

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
apiVersion: rbac.authorization.k8s.io/v1
22
kind: Role
33
metadata:
4-
creationTimestamp: null
54
name: sriov-network-operator
65
rules:
76
- apiGroups:
@@ -76,13 +75,10 @@ rules:
7675
resources:
7776
- pods
7877
verbs:
79-
- '*'
80-
- apiGroups:
81-
- apps
82-
resources:
83-
- daemonsets
84-
verbs:
85-
- '*'
78+
- "get"
79+
- "list"
80+
- "watch"
81+
- "delete"
8682
- apiGroups:
8783
- sriovnetwork.openshift.io
8884
resources:

deployment/sriov-network-operator-chart/templates/clusterrole.yaml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,6 @@ rules:
4949
- apiGroups: [""]
5050
resources: ["nodes"]
5151
verbs: ["get", "list", "watch", "patch", "update"]
52-
- apiGroups: [""]
53-
resources: ["pods"]
54-
verbs: ["*"]
55-
- apiGroups: ["apps"]
56-
resources: ["daemonsets"]
57-
verbs: ["get"]
5852
- apiGroups: [ "config.openshift.io" ]
5953
resources: [ "infrastructures" ]
6054
verbs: [ "get", "list", "watch" ]

deployment/sriov-network-operator-chart/templates/role.yaml

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,10 @@ rules:
8282
resources:
8383
- pods
8484
verbs:
85-
- '*'
86-
- apiGroups:
87-
- apps
88-
resources:
89-
- daemonsets
90-
verbs:
91-
- '*'
85+
- "get"
86+
- "list"
87+
- "watch"
88+
- "delete"
9289
- apiGroups:
9390
- sriovnetwork.openshift.io
9491
resources:

pkg/consts/constants.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ const (
6767
MachineConfigPoolPausedAnnotationIdle = "Idle"
6868
MachineConfigPoolPausedAnnotationPaused = "Paused"
6969

70+
SriovDevicePluginLabel = "sriovnetwork.openshift.io/device-plugin"
71+
SriovDevicePluginLabelEnabled = "Enabled"
72+
SriovDevicePluginLabelDisabled = "Disabled"
73+
7074
NodeDrainAnnotation = "sriovnetwork.openshift.io/state"
7175
NodeStateDrainAnnotation = "sriovnetwork.openshift.io/desired-state"
7276
NodeStateDrainAnnotationCurrent = "sriovnetwork.openshift.io/current-state"

pkg/utils/cluster.go

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,16 +128,17 @@ func ObjectHasAnnotation(obj metav1.Object, annoKey string, value string) bool {
128128

129129
// AnnotateObject adds annotation to a kubernetes object
130130
func AnnotateObject(ctx context.Context, obj client.Object, key, value string, c client.Client) error {
131-
log.Log.V(2).Info("AnnotateObject(): Annotate object",
132-
"objectName", obj.GetName(),
133-
"objectKind", obj.GetObjectKind(),
134-
"annotation", value)
135131
newObj := obj.DeepCopyObject().(client.Object)
136132
if newObj.GetAnnotations() == nil {
137133
newObj.SetAnnotations(map[string]string{})
138134
}
139135

140136
if newObj.GetAnnotations()[key] != value {
137+
log.Log.V(2).Info("AnnotateObject(): Annotate object",
138+
"objectName", obj.GetName(),
139+
"objectKind", obj.GetObjectKind(),
140+
"annotationKey", key,
141+
"annotationValue", value)
141142
newObj.GetAnnotations()[key] = value
142143
patch := client.MergeFrom(obj)
143144
err := c.Patch(ctx,
@@ -161,3 +162,40 @@ func AnnotateNode(ctx context.Context, nodeName string, key, value string, c cli
161162

162163
return AnnotateObject(ctx, node, key, value, c)
163164
}
165+
166+
// LabelObject adds label to a kubernetes object
167+
func LabelObject(ctx context.Context, obj client.Object, key, value string, c client.Client) error {
168+
newObj := obj.DeepCopyObject().(client.Object)
169+
if newObj.GetLabels() == nil {
170+
newObj.SetLabels(map[string]string{})
171+
}
172+
173+
if newObj.GetLabels()[key] != value {
174+
log.Log.V(2).Info("LabelObject(): label object",
175+
"objectName", obj.GetName(),
176+
"objectKind", obj.GetObjectKind(),
177+
"labelKey", key,
178+
"labelValue", value)
179+
newObj.GetLabels()[key] = value
180+
patch := client.MergeFrom(obj)
181+
err := c.Patch(ctx,
182+
newObj, patch)
183+
if err != nil {
184+
log.Log.Error(err, "LabelObject(): Failed to patch object")
185+
return err
186+
}
187+
}
188+
189+
return nil
190+
}
191+
192+
// LabelNode add label to a node
193+
func LabelNode(ctx context.Context, nodeName string, key, value string, c client.Client) error {
194+
node := &corev1.Node{}
195+
err := c.Get(context.TODO(), client.ObjectKey{Name: nodeName}, node)
196+
if err != nil {
197+
return err
198+
}
199+
200+
return LabelObject(ctx, node, key, value, c)
201+
}

0 commit comments

Comments
 (0)