Skip to content

Commit 46affb0

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 2b02ba1 commit 46affb0

File tree

14 files changed

+353
-543
lines changed

14 files changed

+353
-543
lines changed

bindata/manifests/plugins/sriov-device-plugin.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ spec:
2727
hostNetwork: true
2828
nodeSelector:
2929
{{- range $key, $value := .NodeSelectorField }}
30-
{{ $key }}: {{ $value }}
30+
{{ $key }}: "{{ $value }}"
3131
{{- end }}
3232
tolerations:
3333
- operator: Exists

controllers/helper.go

Lines changed: 24 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,10 @@ import (
2222
"encoding/json"
2323
"fmt"
2424
"os"
25-
"sort"
2625
"strings"
2726

2827
errs "github.com/pkg/errors"
2928
appsv1 "k8s.io/api/apps/v1"
30-
corev1 "k8s.io/api/core/v1"
3129
"k8s.io/apimachinery/pkg/api/equality"
3230
"k8s.io/apimachinery/pkg/api/errors"
3331
uns "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
@@ -47,7 +45,7 @@ import (
4745
"github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/vars"
4846
)
4947

50-
var webhooks = map[string](string){
48+
var webhooks = map[string]string{
5149
constants.InjectorWebHookName: constants.InjectorWebHookPath,
5250
constants.OperatorWebHookName: constants.OperatorWebHookPath,
5351
}
@@ -152,29 +150,33 @@ func formatJSON(str string) (string, error) {
152150
return prettyJSON.String(), nil
153151
}
154152

153+
// GetDefaultNodeSelector return a nodeSelector with worker and linux os
155154
func GetDefaultNodeSelector() map[string]string {
156-
return map[string]string{"node-role.kubernetes.io/worker": "",
157-
"kubernetes.io/os": "linux"}
155+
return map[string]string{
156+
"node-role.kubernetes.io/worker": "",
157+
"kubernetes.io/os": "linux",
158+
}
158159
}
159160

160-
// hasNoValidPolicy returns true if no SriovNetworkNodePolicy
161-
// or only the (deprecated) "default" policy is present
162-
func hasNoValidPolicy(pl []sriovnetworkv1.SriovNetworkNodePolicy) bool {
163-
switch len(pl) {
164-
case 0:
165-
return true
166-
case 1:
167-
return pl[0].Name == constants.DefaultPolicyName
168-
default:
169-
return false
161+
// GetDefaultNodeSelectorForDevicePlugin return a nodeSelector with worker linux os
162+
// and the enabled sriov device plugin
163+
func GetNodeSelectorForDevicePlugin(dc *sriovnetworkv1.SriovOperatorConfig) map[string]string {
164+
if len(dc.Spec.ConfigDaemonNodeSelector) == 0 {
165+
return map[string]string{
166+
"kubernetes.io/os": "linux",
167+
constants.SriovDevicePluginLabel: constants.SriovDevicePluginLabelEnabled,
168+
}
170169
}
170+
171+
tmp := dc.Spec.DeepCopy()
172+
tmp.ConfigDaemonNodeSelector[constants.SriovDevicePluginLabel] = constants.SriovDevicePluginLabelEnabled
173+
return tmp.ConfigDaemonNodeSelector
171174
}
172175

173176
func syncPluginDaemonObjs(ctx context.Context,
174177
client k8sclient.Client,
175178
scheme *runtime.Scheme,
176-
dc *sriovnetworkv1.SriovOperatorConfig,
177-
pl *sriovnetworkv1.SriovNetworkNodePolicyList) error {
179+
dc *sriovnetworkv1.SriovOperatorConfig) error {
178180
logger := log.Log.WithName("syncPluginDaemonObjs")
179181
logger.V(1).Info("Start to sync sriov daemons objects")
180182

@@ -185,42 +187,17 @@ func syncPluginDaemonObjs(ctx context.Context,
185187
data.Data["ReleaseVersion"] = os.Getenv("RELEASEVERSION")
186188
data.Data["ResourcePrefix"] = vars.ResourcePrefix
187189
data.Data["ImagePullSecrets"] = GetImagePullSecrets()
188-
data.Data["NodeSelectorField"] = GetDefaultNodeSelector()
190+
data.Data["NodeSelectorField"] = GetNodeSelectorForDevicePlugin(dc)
189191
data.Data["UseCDI"] = dc.Spec.UseCDI
190192
objs, err := renderDsForCR(constants.PluginPath, &data)
191193
if err != nil {
192194
logger.Error(err, "Fail to render SR-IoV manifests")
193195
return err
194196
}
195197

196-
if hasNoValidPolicy(pl.Items) {
197-
for _, obj := range objs {
198-
err := deleteK8sResource(ctx, client, obj)
199-
if err != nil {
200-
return err
201-
}
202-
}
203-
return nil
204-
}
205-
206198
// Sync DaemonSets
207199
for _, obj := range objs {
208-
if obj.GetKind() == constants.DaemonSet && len(dc.Spec.ConfigDaemonNodeSelector) > 0 {
209-
scheme := kscheme.Scheme
210-
ds := &appsv1.DaemonSet{}
211-
err = scheme.Convert(obj, ds, nil)
212-
if err != nil {
213-
logger.Error(err, "Fail to convert to DaemonSet")
214-
return err
215-
}
216-
ds.Spec.Template.Spec.NodeSelector = dc.Spec.ConfigDaemonNodeSelector
217-
err = scheme.Convert(ds, obj, nil)
218-
if err != nil {
219-
logger.Error(err, "Fail to convert to Unstructured")
220-
return err
221-
}
222-
}
223-
err = syncDsObject(ctx, client, scheme, dc, pl, obj)
200+
err = syncDsObject(ctx, client, scheme, dc, obj)
224201
if err != nil {
225202
logger.Error(err, "Couldn't sync SR-IoV daemons objects")
226203
return err
@@ -230,14 +207,7 @@ func syncPluginDaemonObjs(ctx context.Context,
230207
return nil
231208
}
232209

233-
func deleteK8sResource(ctx context.Context, client k8sclient.Client, in *uns.Unstructured) error {
234-
if err := apply.DeleteObject(ctx, client, in); err != nil {
235-
return fmt.Errorf("failed to delete object %v with err: %v", in, err)
236-
}
237-
return nil
238-
}
239-
240-
func syncDsObject(ctx context.Context, client k8sclient.Client, scheme *runtime.Scheme, dc *sriovnetworkv1.SriovOperatorConfig, pl *sriovnetworkv1.SriovNetworkNodePolicyList, obj *uns.Unstructured) error {
210+
func syncDsObject(ctx context.Context, client k8sclient.Client, scheme *runtime.Scheme, dc *sriovnetworkv1.SriovOperatorConfig, obj *uns.Unstructured) error {
241211
logger := log.Log.WithName("syncDsObject")
242212
kind := obj.GetKind()
243213
logger.V(1).Info("Start to sync Objects", "Kind", kind)
@@ -257,7 +227,7 @@ func syncDsObject(ctx context.Context, client k8sclient.Client, scheme *runtime.
257227
logger.Error(err, "Fail to convert to DaemonSet")
258228
return err
259229
}
260-
err = syncDaemonSet(ctx, client, scheme, dc, pl, ds)
230+
err = syncDaemonSet(ctx, client, scheme, dc, ds)
261231
if err != nil {
262232
logger.Error(err, "Fail to sync DaemonSet", "Namespace", ds.Namespace, "Name", ds.Name)
263233
return err
@@ -266,54 +236,6 @@ func syncDsObject(ctx context.Context, client k8sclient.Client, scheme *runtime.
266236
return nil
267237
}
268238

269-
func setDsNodeAffinity(pl *sriovnetworkv1.SriovNetworkNodePolicyList, ds *appsv1.DaemonSet) error {
270-
terms := nodeSelectorTermsForPolicyList(pl.Items)
271-
if len(terms) > 0 {
272-
ds.Spec.Template.Spec.Affinity = &corev1.Affinity{
273-
NodeAffinity: &corev1.NodeAffinity{
274-
RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{
275-
NodeSelectorTerms: terms,
276-
},
277-
},
278-
}
279-
}
280-
return nil
281-
}
282-
283-
func nodeSelectorTermsForPolicyList(policies []sriovnetworkv1.SriovNetworkNodePolicy) []corev1.NodeSelectorTerm {
284-
terms := []corev1.NodeSelectorTerm{}
285-
for _, p := range policies {
286-
// Note(adrianc): default policy is deprecated and ignored.
287-
if p.Name == constants.DefaultPolicyName {
288-
continue
289-
}
290-
291-
if len(p.Spec.NodeSelector) == 0 {
292-
continue
293-
}
294-
expressions := []corev1.NodeSelectorRequirement{}
295-
for k, v := range p.Spec.NodeSelector {
296-
exp := corev1.NodeSelectorRequirement{
297-
Operator: corev1.NodeSelectorOpIn,
298-
Key: k,
299-
Values: []string{v},
300-
}
301-
expressions = append(expressions, exp)
302-
}
303-
// sorting is needed to keep the daemon spec stable.
304-
// the items are popped in a random order from the map
305-
sort.Slice(expressions, func(i, j int) bool {
306-
return expressions[i].Key < expressions[j].Key
307-
})
308-
nodeSelector := corev1.NodeSelectorTerm{
309-
MatchExpressions: expressions,
310-
}
311-
terms = append(terms, nodeSelector)
312-
}
313-
314-
return terms
315-
}
316-
317239
// renderDsForCR returns a busybox pod with the same name/namespace as the cr
318240
func renderDsForCR(path string, data *render.RenderData) ([]*uns.Unstructured, error) {
319241
logger := log.Log.WithName("renderDsForCR")
@@ -326,16 +248,11 @@ func renderDsForCR(path string, data *render.RenderData) ([]*uns.Unstructured, e
326248
return objs, nil
327249
}
328250

329-
func syncDaemonSet(ctx context.Context, client k8sclient.Client, scheme *runtime.Scheme, dc *sriovnetworkv1.SriovOperatorConfig, pl *sriovnetworkv1.SriovNetworkNodePolicyList, in *appsv1.DaemonSet) error {
251+
func syncDaemonSet(ctx context.Context, client k8sclient.Client, scheme *runtime.Scheme, dc *sriovnetworkv1.SriovOperatorConfig, in *appsv1.DaemonSet) error {
330252
logger := log.Log.WithName("syncDaemonSet")
331253
logger.V(1).Info("Start to sync DaemonSet", "Namespace", in.Namespace, "Name", in.Name)
332254
var err error
333255

334-
if pl != nil {
335-
if err = setDsNodeAffinity(pl, in); err != nil {
336-
return err
337-
}
338-
}
339256
if err = controllerutil.SetControllerReference(dc, in, scheme); err != nil {
340257
return err
341258
}

0 commit comments

Comments
 (0)