Merge pull request #753 from hj-johannes-lee/dlb-operator

operator: Add DLB support
This commit is contained in:
Dmitry Rozhkov 2021-11-18 10:23:16 +02:00 committed by GitHub
commit 471549c11d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 860 additions and 1 deletions

View File

@ -30,6 +30,7 @@ import (
devicepluginv1 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/apis/deviceplugin/v1"
fpgav2 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/apis/fpga/v2"
"github.com/intel/intel-device-plugins-for-kubernetes/pkg/controllers/dlb"
"github.com/intel/intel-device-plugins-for-kubernetes/pkg/controllers/dsa"
"github.com/intel/intel-device-plugins-for-kubernetes/pkg/controllers/fpga"
"github.com/intel/intel-device-plugins-for-kubernetes/pkg/controllers/gpu"
@ -58,7 +59,7 @@ type devicePluginControllerAndWebhook map[string](func(ctrl.Manager, string, boo
type flagList []string
var supportedDevices = flagList{"dsa", "fpga", "gpu", "qat", "sgx"}
var supportedDevices = flagList{"dsa", "dlb", "fpga", "gpu", "qat", "sgx"}
var devices flagList
func (flag *flagList) String() string {
@ -110,6 +111,7 @@ func main() {
}
setupControllerAndWebhook := devicePluginControllerAndWebhook{
"dlb": dlb.SetupReconciler,
"dsa": dsa.SetupReconciler,
"gpu": gpu.SetupReconciler,
"fpga": fpga.SetupReconciler,

View File

@ -24,6 +24,7 @@ spec:
imagePullPolicy: IfNotPresent
securityContext:
readOnlyRootFilesystem: true
terminationMessagePath: /tmp/termination-log
volumeMounts:
- name: devfs
mountPath: /dev

View File

@ -0,0 +1,140 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.7.0
creationTimestamp: null
name: dlbdeviceplugins.deviceplugin.intel.com
spec:
group: deviceplugin.intel.com
names:
kind: DlbDevicePlugin
listKind: DlbDevicePluginList
plural: dlbdeviceplugins
singular: dlbdeviceplugin
scope: Cluster
versions:
- additionalPrinterColumns:
- jsonPath: .status.desiredNumberScheduled
name: Desired
type: integer
- jsonPath: .status.numberReady
name: Ready
type: integer
- jsonPath: .spec.nodeSelector
name: Node Selector
type: string
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1
schema:
openAPIV3Schema:
description: DlbDevicePlugin is the Schema for the dlbdeviceplugins API. It
represents the DLB device plugin responsible for advertising Intel DLB hardware
resources to the kubelet.
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: DlbDevicePluginSpec defines the desired state of DlbDevicePlugin.
properties:
image:
description: Image is a container image with DLB device plugin executable.
type: string
logLevel:
description: LogLevel sets the plugin's log level.
minimum: 0
type: integer
nodeSelector:
additionalProperties:
type: string
description: NodeSelector provides a simple way to constrain device
plugin pods to nodes with particular labels.
type: object
type: object
status:
description: DlbDevicePluginStatus defines the observed state of DlbDevicePlugin.
properties:
controlledDaemonSet:
description: ControlledDaemoSet references the DaemonSet controlled
by the operator.
properties:
apiVersion:
description: API version of the referent.
type: string
fieldPath:
description: 'If referring to a piece of an object instead of
an entire object, this string should contain a valid JSON/Go
field access statement, such as desiredState.manifest.containers[2].
For example, if the object reference is to a container within
a pod, this would take on a value like: "spec.containers{name}"
(where "name" refers to the name of the container that triggered
the event) or if no container name is specified "spec.containers[2]"
(container with index 2 in this pod). This syntax is chosen
only to have some well-defined way of referencing a part of
an object. TODO: this design is not final and this field is
subject to change in the future.'
type: string
kind:
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
type: string
namespace:
description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
type: string
resourceVersion:
description: 'Specific resourceVersion to which this reference
is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
type: string
uid:
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
type: string
type: object
desiredNumberScheduled:
description: The total number of nodes that should be running the
device plugin pod (including nodes correctly running the device
plugin pod).
format: int32
type: integer
nodeNames:
description: The list of Node names where the device plugin pods are
running.
items:
type: string
type: array
numberReady:
description: The number of nodes that should be running the device
plugin pod and have one or more of the device plugin pod running
and ready.
format: int32
type: integer
required:
- desiredNumberScheduled
- numberReady
type: object
type: object
served: true
storage: true
subresources:
status: {}
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []

View File

@ -7,6 +7,7 @@ resources:
- bases/deviceplugin.intel.com_fpgadeviceplugins.yaml
- bases/deviceplugin.intel.com_sgxdeviceplugins.yaml
- bases/deviceplugin.intel.com_dsadeviceplugins.yaml
- bases/deviceplugin.intel.com_dlbdeviceplugins.yaml
- bases/fpga.intel.com_acceleratorfunctions.yaml
- bases/fpga.intel.com_fpgaregions.yaml
# +kubebuilder:scaffold:crdkustomizeresource

View File

@ -0,0 +1,14 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: inteldeviceplugins-controller-manager
namespace: inteldeviceplugins-system
spec:
template:
spec:
containers:
- args:
- --metrics-addr=127.0.0.1:8080
- --enable-leader-election
- --devices=dlb
name: manager

View File

@ -0,0 +1,5 @@
bases:
- ../../default
patchesStrategicMerge:
- dlb.yaml

View File

@ -51,6 +51,26 @@ rules:
verbs:
- get
- update
- apiGroups:
- deviceplugin.intel.com
resources:
- dlbdeviceplugins
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- deviceplugin.intel.com
resources:
- dlbdeviceplugins/status
verbs:
- get
- patch
- update
- apiGroups:
- deviceplugin.intel.com
resources:

View File

@ -0,0 +1,15 @@
apiVersion: deviceplugin.intel.com/v1
kind: DlbDevicePlugin
metadata:
name: dlbdeviceplugin-sample
# example apparmor annotation
# see more details here:
# - https://kubernetes.io/docs/tutorials/clusters/apparmor/#securing-a-pod
# - https://github.com/intel/intel-device-plugins-for-kubernetes/issues/381
# annotations:
# container.apparmor.security.beta.kubernetes.io/intel-dlb-plugin: unconfined
spec:
image: intel/intel-dlb-plugin:0.22.0
logLevel: 4
nodeSelector:
feature.node.kubernetes.io/dlb: 'true'

View File

@ -4,4 +4,5 @@ resources:
- deviceplugin_v1_gpudeviceplugin.yaml
- deviceplugin_v1_qatdeviceplugin.yaml
- deviceplugin_v1_sgxdeviceplugin.yaml
- deviceplugin_v1_dlbdeviceplugin.yaml
- mappings-collection.yaml

View File

@ -6,6 +6,26 @@ metadata:
creationTimestamp: null
name: mutating-webhook-configuration
webhooks:
- admissionReviewVersions:
- v1
clientConfig:
service:
name: webhook-service
namespace: system
path: /mutate-deviceplugin-intel-com-v1-dlbdeviceplugin
failurePolicy: Fail
name: mdlbdeviceplugin.kb.io
rules:
- apiGroups:
- deviceplugin.intel.com
apiVersions:
- v1
operations:
- CREATE
- UPDATE
resources:
- dlbdeviceplugins
sideEffects: None
- admissionReviewVersions:
- v1
clientConfig:
@ -155,6 +175,26 @@ metadata:
creationTimestamp: null
name: validating-webhook-configuration
webhooks:
- admissionReviewVersions:
- v1
clientConfig:
service:
name: webhook-service
namespace: system
path: /validate-deviceplugin-intel-com-v1-dlbdeviceplugin
failurePolicy: Fail
name: vdlbdeviceplugin.kb.io
rules:
- apiGroups:
- deviceplugin.intel.com
apiVersions:
- v1
operations:
- CREATE
- UPDATE
resources:
- dlbdeviceplugins
sideEffects: None
- admissionReviewVersions:
- v1
clientConfig:

View File

@ -0,0 +1,92 @@
// Copyright 2020-2021 Intel Corporation. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package v1
import (
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
// DlbDevicePluginSpec defines the desired state of DlbDevicePlugin.
type DlbDevicePluginSpec struct {
// Important: Run "make generate" to regenerate code after modifying this file
// NodeSelector provides a simple way to constrain device plugin pods to nodes with particular labels.
NodeSelector map[string]string `json:"nodeSelector,omitempty"`
// Image is a container image with DLB device plugin executable.
Image string `json:"image,omitempty"`
// LogLevel sets the plugin's log level.
// +kubebuilder:validation:Minimum=0
LogLevel int `json:"logLevel,omitempty"`
}
// DlbDevicePluginStatus defines the observed state of DlbDevicePlugin.
type DlbDevicePluginStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make generate" to regenerate code after modifying this file
// ControlledDaemoSet references the DaemonSet controlled by the operator.
// +optional
ControlledDaemonSet v1.ObjectReference `json:"controlledDaemonSet,omitempty"`
// The list of Node names where the device plugin pods are running.
// +optional
NodeNames []string `json:"nodeNames,omitempty"`
// The total number of nodes that should be running the device plugin
// pod (including nodes correctly running the device plugin pod).
DesiredNumberScheduled int32 `json:"desiredNumberScheduled"`
// The number of nodes that should be running the device plugin pod and have one
// or more of the device plugin pod running and ready.
NumberReady int32 `json:"numberReady"`
}
// +kubebuilder:object:root=true
// +kubebuilder:resource:path=dlbdeviceplugins,scope=Cluster
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Desired",type=integer,JSONPath=`.status.desiredNumberScheduled`
// +kubebuilder:printcolumn:name="Ready",type=integer,JSONPath=`.status.numberReady`
// +kubebuilder:printcolumn:name="Node Selector",type=string,JSONPath=`.spec.nodeSelector`
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
// +operator-sdk:csv:customresourcedefinitions:displayName="Intel DLB Device Plugin"
// DlbDevicePlugin is the Schema for the dlbdeviceplugins API. It represents
// the DLB device plugin responsible for advertising Intel DLB hardware resources to
// the kubelet.
type DlbDevicePlugin struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec DlbDevicePluginSpec `json:"spec,omitempty"`
Status DlbDevicePluginStatus `json:"status,omitempty"`
}
// +kubebuilder:object:root=true
// DlbDevicePluginList contains a list of DlbDevicePlugin.
type DlbDevicePluginList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []DlbDevicePlugin `json:"items"`
}
func init() {
SchemeBuilder.Register(&DlbDevicePlugin{}, &DlbDevicePluginList{})
}

View File

@ -0,0 +1,90 @@
// Copyright 2020 Intel Corporation. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package v1
import (
"github.com/pkg/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/version"
ctrl "sigs.k8s.io/controller-runtime"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/webhook"
"github.com/intel/intel-device-plugins-for-kubernetes/pkg/controllers"
)
const (
dlbPluginKind = "DlbDevicePlugin"
)
var (
// dlbdevicepluginlog is for logging in this package.
dlbdevicepluginlog = logf.Log.WithName("dlbdeviceplugin-resource")
dlbMinVersion = version.MustParseSemantic(imageMinVersion)
)
// SetupWebhookWithManager sets up a webhook for DlbDevicePlugin custom resources.
func (r *DlbDevicePlugin) SetupWebhookWithManager(mgr ctrl.Manager) error {
return ctrl.NewWebhookManagedBy(mgr).
For(r).
Complete()
}
// +kubebuilder:webhook:path=/mutate-deviceplugin-intel-com-v1-dlbdeviceplugin,mutating=true,failurePolicy=fail,groups=deviceplugin.intel.com,resources=dlbdeviceplugins,verbs=create;update,versions=v1,name=mdlbdeviceplugin.kb.io,sideEffects=None,admissionReviewVersions=v1
var _ webhook.Defaulter = &DlbDevicePlugin{}
// Default implements webhook.Defaulter so a webhook will be registered for the type.
func (r *DlbDevicePlugin) Default() {
dlbdevicepluginlog.Info("default", "name", r.Name)
if len(r.Spec.Image) == 0 {
r.Spec.Image = "intel/intel-dlb-plugin:" + dlbMinVersion.String()
}
}
// +kubebuilder:webhook:verbs=create;update,path=/validate-deviceplugin-intel-com-v1-dlbdeviceplugin,mutating=false,failurePolicy=fail,groups=deviceplugin.intel.com,resources=dlbdeviceplugins,versions=v1,name=vdlbdeviceplugin.kb.io,sideEffects=None,admissionReviewVersions=v1
var _ webhook.Validator = &DlbDevicePlugin{}
// ValidateCreate implements webhook.Validator so a webhook will be registered for the type.
func (r *DlbDevicePlugin) ValidateCreate() error {
dlbdevicepluginlog.Info("validate create", "name", r.Name)
if controllers.GetDevicePluginCount(dlbPluginKind) > 0 {
return errors.Errorf("an instance of %q already exists in the cluster", dlbPluginKind)
}
return r.validatePlugin()
}
// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type.
func (r *DlbDevicePlugin) ValidateUpdate(old runtime.Object) error {
dlbdevicepluginlog.Info("validate update", "name", r.Name)
return r.validatePlugin()
}
// ValidateDelete implements webhook.Validator so a webhook will be registered for the type.
func (r *DlbDevicePlugin) ValidateDelete() error {
dlbdevicepluginlog.Info("validate delete", "name", r.Name)
return nil
}
func (r *DlbDevicePlugin) validatePlugin() error {
return validatePluginImage(r.Spec.Image, "intel-dlb-plugin", dlbMinVersion)
}

View File

@ -23,6 +23,108 @@ import (
"k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *DlbDevicePlugin) DeepCopyInto(out *DlbDevicePlugin) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DlbDevicePlugin.
func (in *DlbDevicePlugin) DeepCopy() *DlbDevicePlugin {
if in == nil {
return nil
}
out := new(DlbDevicePlugin)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *DlbDevicePlugin) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *DlbDevicePluginList) DeepCopyInto(out *DlbDevicePluginList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]DlbDevicePlugin, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DlbDevicePluginList.
func (in *DlbDevicePluginList) DeepCopy() *DlbDevicePluginList {
if in == nil {
return nil
}
out := new(DlbDevicePluginList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *DlbDevicePluginList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *DlbDevicePluginSpec) DeepCopyInto(out *DlbDevicePluginSpec) {
*out = *in
if in.NodeSelector != nil {
in, out := &in.NodeSelector, &out.NodeSelector
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DlbDevicePluginSpec.
func (in *DlbDevicePluginSpec) DeepCopy() *DlbDevicePluginSpec {
if in == nil {
return nil
}
out := new(DlbDevicePluginSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *DlbDevicePluginStatus) DeepCopyInto(out *DlbDevicePluginStatus) {
*out = *in
out.ControlledDaemonSet = in.ControlledDaemonSet
if in.NodeNames != nil {
in, out := &in.NodeNames, &out.NodeNames
*out = make([]string, len(*in))
copy(*out, *in)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DlbDevicePluginStatus.
func (in *DlbDevicePluginStatus) DeepCopy() *DlbDevicePluginStatus {
if in == nil {
return nil
}
out := new(DlbDevicePluginStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *DsaDevicePlugin) DeepCopyInto(out *DsaDevicePlugin) {
*out = *in

View File

@ -0,0 +1,235 @@
// Copyright 2020 Intel Corporation. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package dlb contains DLB specific reconciliation logic.
package dlb
import (
"context"
"reflect"
"strconv"
"strings"
apps "k8s.io/api/apps/v1"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/tools/reference"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
devicepluginv1 "github.com/intel/intel-device-plugins-for-kubernetes/pkg/apis/deviceplugin/v1"
"github.com/intel/intel-device-plugins-for-kubernetes/pkg/controllers"
"github.com/pkg/errors"
)
const (
ownerKey = ".metadata.controller.dlb"
appLabel = "intel-dlb-plugin"
)
// +kubebuilder:rbac:groups=deviceplugin.intel.com,resources=dlbdeviceplugins,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=deviceplugin.intel.com,resources=dlbdeviceplugins/status,verbs=get;update;patch
// SetupReconciler creates a new reconciler for DlbDevicePlugin objects.
func SetupReconciler(mgr ctrl.Manager, namespace string, withWebhook bool) error {
c := &controller{scheme: mgr.GetScheme(), ns: namespace}
if err := controllers.SetupWithManager(mgr, c, devicepluginv1.GroupVersion.String(), "DlbDevicePlugin", ownerKey); err != nil {
return err
}
if withWebhook {
return (&devicepluginv1.DlbDevicePlugin{}).SetupWebhookWithManager(mgr)
}
return nil
}
type controller struct {
controllers.DefaultServiceAccountFactory
scheme *runtime.Scheme
ns string
}
func (c *controller) CreateEmptyObject() client.Object {
return &devicepluginv1.DlbDevicePlugin{}
}
func (c *controller) GetTotalObjectCount(ctx context.Context, clnt client.Client) (int, error) {
var list devicepluginv1.DlbDevicePluginList
if err := clnt.List(ctx, &list); err != nil {
return 0, err
}
return len(list.Items), nil
}
func (c *controller) NewDaemonSet(rawObj client.Object) *apps.DaemonSet {
devicePlugin := rawObj.(*devicepluginv1.DlbDevicePlugin)
yes := true
var nodeSelector map[string]string
daemonSet := apps.DaemonSet{
ObjectMeta: metav1.ObjectMeta{
Namespace: c.ns,
GenerateName: devicePlugin.Name + "-",
Labels: map[string]string{
"app": appLabel,
},
},
Spec: apps.DaemonSetSpec{
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{
"app": appLabel,
},
},
Template: v1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{
"app": appLabel,
},
},
Spec: v1.PodSpec{
Containers: []v1.Container{
{
Name: appLabel,
Env: []v1.EnvVar{
{
Name: "NODE_NAME",
ValueFrom: &v1.EnvVarSource{
FieldRef: &v1.ObjectFieldSelector{
FieldPath: "spec.nodeName",
},
},
},
},
TerminationMessagePath: "/tmp/termination-log",
Args: getPodArgs(devicePlugin),
Image: devicePlugin.Spec.Image,
ImagePullPolicy: "IfNotPresent",
SecurityContext: &v1.SecurityContext{
ReadOnlyRootFilesystem: &yes,
},
VolumeMounts: []v1.VolumeMount{
{
Name: "devfs",
MountPath: "/dev",
ReadOnly: true,
},
{
Name: "sysfs",
MountPath: "/sys/class/dlb2",
ReadOnly: true,
},
{
Name: "kubeletsockets",
MountPath: "/var/lib/kubelet/device-plugins",
},
},
},
},
NodeSelector: nodeSelector,
Volumes: []v1.Volume{
{
Name: "devfs",
VolumeSource: v1.VolumeSource{
HostPath: &v1.HostPathVolumeSource{
Path: "/dev",
},
},
},
{
Name: "sysfs",
VolumeSource: v1.VolumeSource{
HostPath: &v1.HostPathVolumeSource{
Path: "/sys/class/dlb2",
},
},
},
{
Name: "kubeletsockets",
VolumeSource: v1.VolumeSource{
HostPath: &v1.HostPathVolumeSource{
Path: "/var/lib/kubelet/device-plugins",
},
},
},
},
},
},
},
}
return &daemonSet
}
func (c *controller) UpdateDaemonSet(rawObj client.Object, ds *apps.DaemonSet) (updated bool) {
dp := rawObj.(*devicepluginv1.DlbDevicePlugin)
if ds.Spec.Template.Spec.Containers[0].Image != dp.Spec.Image {
ds.Spec.Template.Spec.Containers[0].Image = dp.Spec.Image
updated = true
}
if !reflect.DeepEqual(ds.Spec.Template.Spec.NodeSelector, dp.Spec.NodeSelector) {
ds.Spec.Template.Spec.NodeSelector = dp.Spec.NodeSelector
updated = true
}
newargs := getPodArgs(dp)
if strings.Join(ds.Spec.Template.Spec.Containers[0].Args, " ") != strings.Join(newargs, " ") {
ds.Spec.Template.Spec.Containers[0].Args = newargs
updated = true
}
return updated
}
func (c *controller) UpdateStatus(rawObj client.Object, ds *apps.DaemonSet, nodeNames []string) (updated bool, err error) {
dp := rawObj.(*devicepluginv1.DlbDevicePlugin)
dsRef, err := reference.GetReference(c.scheme, ds)
if err != nil {
return false, errors.Wrap(err, "unable to make reference to controlled daemon set")
}
if dp.Status.ControlledDaemonSet.UID != dsRef.UID {
dp.Status.ControlledDaemonSet = *dsRef
updated = true
}
if dp.Status.DesiredNumberScheduled != ds.Status.DesiredNumberScheduled {
dp.Status.DesiredNumberScheduled = ds.Status.DesiredNumberScheduled
updated = true
}
if dp.Status.NumberReady != ds.Status.NumberReady {
dp.Status.NumberReady = ds.Status.NumberReady
updated = true
}
if strings.Join(dp.Status.NodeNames, ",") != strings.Join(nodeNames, ",") {
dp.Status.NodeNames = nodeNames
updated = true
}
return updated, nil
}
func getPodArgs(gdp *devicepluginv1.DlbDevicePlugin) []string {
args := make([]string, 0, 4)
args = append(args, "-v", strconv.Itoa(gdp.Spec.LogLevel))
return args
}