Build intel device plugin images

Currently, app-intel-device-plugins uses upstream images.
As a result, bug fix patches cannot be applied and must
wait for an upstream release.

In this commit, support has been added to build the images using
the upstream source code after applying the required patches.

The following fix has been applied over the Intel Device Plugins
upstream version v0.32.1:
https://github.com/intel/intel-device-plugins-for-kubernetes/pull/2074

Note: This review only introduces the build mechanism. Other changes,
      such as tagging the newly built images and updating Helm charts,
      will be done in separate reviews.

TEST PLAN:

PASS: Build the images using build-stx-images.sh script successfully.
      Invoked this script to build images as follows.
      ./build-stx-images.sh --base msheikh/stx-debian:DEV --no-pull-base \
      --wheels $MY_WORKSPACE/std/build-wheels-debian-stable/stx-debian-stable-wheels.tar \
      --only image_name

Story: 2011407
Task: 52420

Change-Id: Ia482ea893206a0ef6c067dbf347ea00a4d0e5190
Signed-off-by: Md Irshad Sheikh <mdirshad.sheikh@windriver.com>
This commit is contained in:
Md Irshad Sheikh
2025-06-24 03:12:28 -04:00
parent cf1c9c2463
commit 731631f43d
9 changed files with 1019 additions and 0 deletions

View File

@@ -0,0 +1 @@
intel-device-plugins-images

View File

@@ -0,0 +1,167 @@
#!/bin/sh
#
# Copyright (c) 2025 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
IMAGE=$1
IMAGE_TAG=$2
export CONTAINER_TOOL=docker
BUILD_TAG=dev-debian-stable-build
INTEL=intel
INTEL_OPERATOR=intel-deviceplugin-operator
INTEL_QAT=intel-qat-plugin
INTEL_GPU=intel-gpu-plugin
INTEL_GPU_INIT=intel-gpu-initcontainer
INTEL_DSA=intel-dsa-plugin
INTEL_IDXD_INIT=intel-idxd-config-initcontainer
echo "=============== build script ================"
echo image: "${IMAGE}"
echo image_tag: "${IMAGE_TAG}"
pwd
if [ -z "${IMAGE_TAG}" ]; then
echo "Image tag must be specified. build ${IMAGE} Aborting..." >&2
exit 1
fi
build_intel_operator_image() {
export INTEL_OPERATOR_IMAGE=$1
echo "intel_operator_image: ${INTEL_OPERATOR_IMAGE}"
pwd
make $INTEL_OPERATOR TAG=$BUILD_TAG
docker tag $INTEL/$INTEL_OPERATOR:$BUILD_TAG $IMAGE_TAG
docker rmi $INTEL/$INTEL_OPERATOR:$BUILD_TAG
if [ $? -ne 0 ]; then
echo "${INTEL_OPERATOR_IMAGE} image build failed"
exit 1
fi
echo "${INTEL_OPERATOR_IMAGE} image build done"
return 0
}
build_intel_qat_image() {
export INTEL_QAT_IMAGE=$1
echo "intel_qat_image: ${INTEL_QAT_IMAGE}"
pwd
make $INTEL_QAT TAG=$BUILD_TAG
docker tag $INTEL/$INTEL_QAT:$BUILD_TAG $IMAGE_TAG
docker rmi $INTEL/$INTEL_QAT:$BUILD_TAG
if [ $? -ne 0 ]; then
echo "${INTEL_QAT_IMAGE} image build failed"
exit 1
fi
echo "${INTEL_QAT_IMAGE} image build done"
return 0
}
build_intel_gpu_image() {
export INTEL_GPU_IMAGE=$1
echo "intel_gpu_image: ${INTEL_GPU_IMAGE}"
pwd
make $INTEL_GPU TAG=$BUILD_TAG
docker tag $INTEL/$INTEL_GPU:$BUILD_TAG $IMAGE_TAG
docker rmi $INTEL/$INTEL_GPU:$BUILD_TAG
if [ $? -ne 0 ]; then
echo "${INTEL_GPU_IMAGE} image build failed"
exit 1
fi
echo "${INTEL_GPU_IMAGE} image build done"
return 0
}
build_intel_gpu_init_image() {
export INTEL_GPU_INIT_IMAGE=$1
echo "intel_gpu_init_image: ${INTEL_GPU_INIT_IMAGE}"
pwd
make $INTEL_GPU_INIT TAG=$BUILD_TAG
docker tag $INTEL/$INTEL_GPU_INIT:$BUILD_TAG $IMAGE_TAG
docker rmi $INTEL/$INTEL_GPU_INIT:$BUILD_TAG
if [ $? -ne 0 ]; then
echo "${INTEL_GPU_INIT_IMAGE} image build failed"
exit 1
fi
echo "${INTEL_GPU_INIT_IMAGE} image build done"
return 0
}
build_intel_dsa_image() {
export INTEL_DSA_IMAGE=$1
echo "intel_dsa_image: ${INTEL_DSA_IMAGE}"
pwd
make $INTEL_DSA TAG=$BUILD_TAG
docker tag $INTEL/$INTEL_DSA:$BUILD_TAG $IMAGE_TAG
docker rmi $INTEL/$INTEL_DSA:$BUILD_TAG
if [ $? -ne 0 ]; then
echo "${INTEL_DSA_IMAGE} image build failed"
exit 1
fi
echo "${INTEL_DSA_IMAGE} image build done"
return 0
}
build_intel_idxd_config_init_image() {
export INTEL_IDXD_IMAGE=$1
echo "intel_idxd_config_init_image: ${INTEL_IDXD_IMAGE}"
pwd
make $INTEL_IDXD_INIT TAG=$BUILD_TAG
docker tag $INTEL/$INTEL_IDXD_INIT:$BUILD_TAG $IMAGE_TAG
docker rmi $INTEL/$INTEL_IDXD_INIT:$BUILD_TAG
if [ $? -ne 0 ]; then
echo "${INTEL_IDXD_IMAGE} image build failed"
exit 1
fi
echo "${INTEL_IDXD_IMAGE} image build done"
return 0
}
case ${IMAGE} in
intel_operator)
echo "Build image: ${INTEL_OPERATOR}"
build_intel_operator_image "${IMAGE_TAG}"
;;
intel_qat)
echo "build image: ${INTEL_QAT}"
build_intel_qat_image "${IMAGE_TAG}"
;;
intel_gpu)
echo "build image: ${INTEL_GPU}"
build_intel_gpu_image "${IMAGE_TAG}"
;;
intel_gpu_init)
echo "build image: ${INTEL_GPU_INIT}"
build_intel_gpu_init_image "${IMAGE_TAG}"
;;
intel_dsa)
echo "build image: ${INTEL_DSA}"
build_intel_dsa_image "${IMAGE_TAG}"
;;
intel_idxd_config_init)
echo "build image: ${INTEL_IDXD_INIT}"
build_intel_idxd_config_init_image "${IMAGE_TAG}"
;;
*)
echo "Unsupported ARGS in ${image_build_file}: ${IMAGE}" >&2
exit 1
;;
esac
exit 0

View File

@@ -0,0 +1,8 @@
BUILDER=script
LABEL=intel-deviceplugin-operator
SOURCE_REPO=https://github.com/intel/intel-device-plugins-for-kubernetes.git
SOURCE_REF=v0.32.1
SOURCE_PATCHES="../files/0001-operator-add-possibility-to-use-a-secret-for-plugin.patch"
COMMAND=bash
SCRIPT=build-intel-device-plugins-image.sh
ARGS=intel_operator

View File

@@ -0,0 +1,8 @@
BUILDER=script
LABEL=intel-dsa-plugin
SOURCE_REPO=https://github.com/intel/intel-device-plugins-for-kubernetes.git
SOURCE_REF=v0.32.1
SOURCE_PATCHES="../files/0001-operator-add-possibility-to-use-a-secret-for-plugin.patch"
COMMAND=bash
SCRIPT=build-intel-device-plugins-image.sh
ARGS=intel_dsa

View File

@@ -0,0 +1,8 @@
BUILDER=script
LABEL=intel-gpu-initcontainer
SOURCE_REPO=https://github.com/intel/intel-device-plugins-for-kubernetes.git
SOURCE_REF=v0.32.1
SOURCE_PATCHES="../files/0001-operator-add-possibility-to-use-a-secret-for-plugin.patch"
COMMAND=bash
SCRIPT=build-intel-device-plugins-image.sh
ARGS=intel_gpu_init

View File

@@ -0,0 +1,8 @@
BUILDER=script
LABEL=intel-gpu-plugin
SOURCE_REPO=https://github.com/intel/intel-device-plugins-for-kubernetes.git
SOURCE_REF=v0.32.1
SOURCE_PATCHES="../files/0001-operator-add-possibility-to-use-a-secret-for-plugin.patch"
COMMAND=bash
SCRIPT=build-intel-device-plugins-image.sh
ARGS=intel_gpu

View File

@@ -0,0 +1,8 @@
BUILDER=script
LABEL=intel-idxd-config-initcontainer
SOURCE_REPO=https://github.com/intel/intel-device-plugins-for-kubernetes.git
SOURCE_REF=v0.32.1
SOURCE_PATCHES="../files/0001-operator-add-possibility-to-use-a-secret-for-plugin.patch"
COMMAND=bash
SCRIPT=build-intel-device-plugins-image.sh
ARGS=intel_idxd_config_init

View File

@@ -0,0 +1,8 @@
BUILDER=script
LABEL=intel-qat-plugin
SOURCE_REPO=https://github.com/intel/intel-device-plugins-for-kubernetes.git
SOURCE_REF=v0.32.1
SOURCE_PATCHES="../files/0001-operator-add-possibility-to-use-a-secret-for-plugin.patch"
COMMAND=bash
SCRIPT=build-intel-device-plugins-image.sh
ARGS=intel_qat

View File

@@ -0,0 +1,803 @@
From edafd4d1265921ad001a9cff22a58dfcb6b9c6ae Mon Sep 17 00:00:00 2001
From: Tuomas Katila <tuomas.katila@intel.com>
Date: Mon, 16 Jun 2025 09:11:05 +0300
Subject: [PATCH] operator: add possibility to use a secret for plugin images
Also, pack controller options into a struct.
Signed-off-by: Tuomas Katila <tuomas.katila@intel.com>
---
cmd/operator/main.go | 15 ++++++++------
pkg/controllers/dlb/controller.go | 16 ++++++++++-----
pkg/controllers/dlb/controller_test.go | 16 ++++++++++++++-
pkg/controllers/dsa/controller.go | 16 ++++++++++-----
pkg/controllers/dsa/controller_test.go | 16 ++++++++++++++-
pkg/controllers/fpga/controller.go | 17 +++++++++++-----
pkg/controllers/fpga/controller_test.go | 20 ++++++++++++++++--
pkg/controllers/gpu/controller.go | 22 ++++++++++++--------
pkg/controllers/gpu/controller_test.go | 27 ++++++++++++++++++++++++-
pkg/controllers/iaa/controller.go | 16 ++++++++++-----
pkg/controllers/iaa/controller_test.go | 17 +++++++++++++++-
pkg/controllers/qat/controller.go | 16 ++++++++++-----
pkg/controllers/qat/controller_test.go | 17 +++++++++++++++-
pkg/controllers/reconciler.go | 6 ++++++
pkg/controllers/sgx/controller.go | 16 ++++++++++-----
pkg/controllers/sgx/controller_test.go | 17 +++++++++++++++-
test/envtest/suite_test.go | 16 +++++++--------
17 files changed, 226 insertions(+), 60 deletions(-)
diff --git a/cmd/operator/main.go b/cmd/operator/main.go
index 2fca03da..7c5ac2a7 100644
--- a/cmd/operator/main.go
+++ b/cmd/operator/main.go
@@ -34,6 +34,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"
"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"
@@ -61,7 +62,7 @@ func init() {
// +kubebuilder:scaffold:scheme
}
-type devicePluginControllerAndWebhook map[string](func(ctrl.Manager, string, bool) error)
+type devicePluginControllerAndWebhook map[string](func(ctrl.Manager, controllers.ControllerOptions) error)
type flagList []string
@@ -208,15 +209,17 @@ func main() {
os.Exit(1)
}
- ns := os.Getenv("DEVICEPLUGIN_NAMESPACE")
- if ns == "" {
- ns = devicePluginNamespace
+ cargs := controllers.ControllerOptions{WithWebhook: true}
+
+ cargs.Namespace = os.Getenv("DEVICEPLUGIN_NAMESPACE")
+ if cargs.Namespace == "" {
+ cargs.Namespace = devicePluginNamespace
}
- withWebhook := true
+ cargs.ImagePullSecretName = os.Getenv("DEVICEPLUGIN_SECRET")
for _, device := range devices {
- if err = setupControllerAndWebhook[device](mgr, ns, withWebhook); err != nil {
+ if err = setupControllerAndWebhook[device](mgr, cargs); err != nil {
setupLog.Error(err, "unable to initialize controller", "controller", device)
os.Exit(1)
}
diff --git a/pkg/controllers/dlb/controller.go b/pkg/controllers/dlb/controller.go
index ba770a52..27b6461b 100644
--- a/pkg/controllers/dlb/controller.go
+++ b/pkg/controllers/dlb/controller.go
@@ -43,13 +43,13 @@ var defaultNodeSelector map[string]string = deployments.DLBPluginDaemonSet().Spe
// +kubebuilder:rbac:groups=deviceplugin.intel.com,resources=dlbdeviceplugins/finalizers,verbs=update
// 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}
+func SetupReconciler(mgr ctrl.Manager, args controllers.ControllerOptions) error {
+ c := &controller{scheme: mgr.GetScheme(), args: args}
if err := controllers.SetupWithManager(mgr, c, devicepluginv1.GroupVersion.String(), "DlbDevicePlugin", ownerKey); err != nil {
return err
}
- if withWebhook {
+ if args.WithWebhook {
return (&devicepluginv1.DlbDevicePlugin{}).SetupWebhookWithManager(mgr)
}
@@ -59,7 +59,7 @@ func SetupReconciler(mgr ctrl.Manager, namespace string, withWebhook bool) error
type controller struct {
controllers.DefaultServiceAccountFactory
scheme *runtime.Scheme
- ns string
+ args controllers.ControllerOptions
}
func (c *controller) CreateEmptyObject() client.Object {
@@ -92,7 +92,13 @@ func (c *controller) NewDaemonSet(rawObj client.Object) *apps.DaemonSet {
setInitContainer(&ds.Spec.Template.Spec, devicePlugin.Spec)
}
- ds.ObjectMeta.Namespace = c.ns
+ ds.ObjectMeta.Namespace = c.args.Namespace
+
+ if len(c.args.ImagePullSecretName) > 0 {
+ ds.Spec.Template.Spec.ImagePullSecrets = []v1.LocalObjectReference{
+ {Name: c.args.ImagePullSecretName},
+ }
+ }
ds.Spec.Template.Spec.Containers[0].Args = getPodArgs(devicePlugin)
ds.Spec.Template.Spec.Containers[0].Image = devicePlugin.Spec.Image
diff --git a/pkg/controllers/dlb/controller_test.go b/pkg/controllers/dlb/controller_test.go
index 34770861..af1cdb23 100644
--- a/pkg/controllers/dlb/controller_test.go
+++ b/pkg/controllers/dlb/controller_test.go
@@ -45,7 +45,7 @@ func (c *controller) newDaemonSetExpected(rawObj client.Object) *apps.DaemonSet
APIVersion: "apps/v1",
},
ObjectMeta: metav1.ObjectMeta{
- Namespace: c.ns,
+ Namespace: c.args.Namespace,
Name: appLabel + "-" + devicePlugin.Name,
Labels: map[string]string{
"app": appLabel,
@@ -155,6 +155,12 @@ func (c *controller) newDaemonSetExpected(rawObj client.Object) *apps.DaemonSet
},
}
+ if len(c.args.ImagePullSecretName) > 0 {
+ daemonSet.Spec.Template.Spec.ImagePullSecrets = []v1.LocalObjectReference{
+ {Name: c.args.ImagePullSecretName},
+ }
+ }
+
return &daemonSet
}
@@ -171,4 +177,12 @@ func TestNewDaemonSetDLB(t *testing.T) {
if !reflect.DeepEqual(expected, actual) {
t.Errorf("expected and actuall daemonsets differ: %+s", diff.ObjectGoPrintDiff(expected, actual))
}
+
+ c.args.ImagePullSecretName = "mysecret"
+
+ expected = c.newDaemonSetExpected(plugin)
+ actual = c.NewDaemonSet(plugin)
+ if !reflect.DeepEqual(expected, actual) {
+ t.Errorf("expected and actual daemonsets with secret differ: %+s", diff.ObjectGoPrintDiff(expected, actual))
+ }
}
diff --git a/pkg/controllers/dsa/controller.go b/pkg/controllers/dsa/controller.go
index fd7f6078..19f6b61f 100644
--- a/pkg/controllers/dsa/controller.go
+++ b/pkg/controllers/dsa/controller.go
@@ -47,13 +47,13 @@ var defaultNodeSelector = deployments.DSAPluginDaemonSet().Spec.Template.Spec.No
// +kubebuilder:rbac:groups=deviceplugin.intel.com,resources=dsadeviceplugins/finalizers,verbs=update
// SetupReconciler creates a new reconciler for DsaDevicePlugin objects.
-func SetupReconciler(mgr ctrl.Manager, namespace string, withWebhook bool) error {
- c := &controller{scheme: mgr.GetScheme(), ns: namespace}
+func SetupReconciler(mgr ctrl.Manager, args controllers.ControllerOptions) error {
+ c := &controller{scheme: mgr.GetScheme(), args: args}
if err := controllers.SetupWithManager(mgr, c, devicepluginv1.GroupVersion.String(), "DsaDevicePlugin", ownerKey); err != nil {
return err
}
- if withWebhook {
+ if args.WithWebhook {
return (&devicepluginv1.DsaDevicePlugin{}).SetupWebhookWithManager(mgr)
}
@@ -63,7 +63,7 @@ func SetupReconciler(mgr ctrl.Manager, namespace string, withWebhook bool) error
type controller struct {
controllers.DefaultServiceAccountFactory
scheme *runtime.Scheme
- ns string
+ args controllers.ControllerOptions
}
func (c *controller) CreateEmptyObject() client.Object {
@@ -200,7 +200,7 @@ func (c *controller) NewDaemonSet(rawObj client.Object) *apps.DaemonSet {
daemonSet.Spec.Template.Spec.Tolerations = devicePlugin.Spec.Tolerations
}
- daemonSet.ObjectMeta.Namespace = c.ns
+ daemonSet.ObjectMeta.Namespace = c.args.Namespace
daemonSet.Spec.Template.Spec.Containers[0].Args = getPodArgs(devicePlugin)
daemonSet.Spec.Template.Spec.Containers[0].Image = devicePlugin.Spec.Image
@@ -208,6 +208,12 @@ func (c *controller) NewDaemonSet(rawObj client.Object) *apps.DaemonSet {
addInitContainer(daemonSet, devicePlugin)
}
+ if len(c.args.ImagePullSecretName) > 0 {
+ daemonSet.Spec.Template.Spec.ImagePullSecrets = []v1.LocalObjectReference{
+ {Name: c.args.ImagePullSecretName},
+ }
+ }
+
return daemonSet
}
diff --git a/pkg/controllers/dsa/controller_test.go b/pkg/controllers/dsa/controller_test.go
index 4181e42b..46872f60 100644
--- a/pkg/controllers/dsa/controller_test.go
+++ b/pkg/controllers/dsa/controller_test.go
@@ -47,7 +47,7 @@ func (c *controller) newDaemonSetExpected(rawObj client.Object) *apps.DaemonSet
APIVersion: "apps/v1",
},
ObjectMeta: metav1.ObjectMeta{
- Namespace: c.ns,
+ Namespace: c.args.Namespace,
Name: appLabel + "-" + devicePlugin.Name,
Labels: map[string]string{
"app": appLabel,
@@ -177,6 +177,12 @@ func (c *controller) newDaemonSetExpected(rawObj client.Object) *apps.DaemonSet
addInitContainer(&daemonSet, devicePlugin)
}
+ if len(c.args.ImagePullSecretName) > 0 {
+ daemonSet.Spec.Template.Spec.ImagePullSecrets = []v1.LocalObjectReference{
+ {Name: c.args.ImagePullSecretName},
+ }
+ }
+
return &daemonSet
}
@@ -193,4 +199,12 @@ func TestNewDaemonSetDSA(t *testing.T) {
if !reflect.DeepEqual(expected, actual) {
t.Errorf("expected and actuall daemonsets differ: %+s", diff.ObjectGoPrintDiff(expected, actual))
}
+
+ c.args.ImagePullSecretName = "mysecret"
+
+ expected = c.newDaemonSetExpected(plugin)
+ actual = c.NewDaemonSet(plugin)
+ if !reflect.DeepEqual(expected, actual) {
+ t.Errorf("expected and actual daemonsets with secret differ: %+s", diff.ObjectGoPrintDiff(expected, actual))
+ }
}
diff --git a/pkg/controllers/fpga/controller.go b/pkg/controllers/fpga/controller.go
index 3614fb16..3a96032e 100644
--- a/pkg/controllers/fpga/controller.go
+++ b/pkg/controllers/fpga/controller.go
@@ -22,6 +22,7 @@ import (
"strings"
apps "k8s.io/api/apps/v1"
+ v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/tools/reference"
ctrl "sigs.k8s.io/controller-runtime"
@@ -42,13 +43,13 @@ var defaultNodeSelector = deployments.FPGAPluginDaemonSet().Spec.Template.Spec.N
// +kubebuilder:rbac:groups=deviceplugin.intel.com,resources=fpgadeviceplugins/finalizers,verbs=update
// SetupReconciler creates a new reconciler for FpgaDevicePlugin objects.
-func SetupReconciler(mgr ctrl.Manager, namespace string, withWebhook bool) error {
- c := &controller{scheme: mgr.GetScheme(), ns: namespace}
+func SetupReconciler(mgr ctrl.Manager, args controllers.ControllerOptions) error {
+ c := &controller{scheme: mgr.GetScheme(), args: args}
if err := controllers.SetupWithManager(mgr, c, devicepluginv1.GroupVersion.String(), "FpgaDevicePlugin", ownerKey); err != nil {
return err
}
- if withWebhook {
+ if args.WithWebhook {
return (&devicepluginv1.FpgaDevicePlugin{}).SetupWebhookWithManager(mgr)
}
@@ -58,7 +59,7 @@ func SetupReconciler(mgr ctrl.Manager, namespace string, withWebhook bool) error
type controller struct {
controllers.DefaultServiceAccountFactory
scheme *runtime.Scheme
- ns string
+ args controllers.ControllerOptions
}
func (c *controller) CreateEmptyObject() client.Object {
@@ -84,7 +85,13 @@ func (c *controller) NewDaemonSet(rawObj client.Object) *apps.DaemonSet {
daemonSet.Spec.Template.Spec.Tolerations = devicePlugin.Spec.Tolerations
}
- daemonSet.ObjectMeta.Namespace = c.ns
+ daemonSet.ObjectMeta.Namespace = c.args.Namespace
+
+ if len(c.args.ImagePullSecretName) > 0 {
+ daemonSet.Spec.Template.Spec.ImagePullSecrets = []v1.LocalObjectReference{
+ {Name: c.args.ImagePullSecretName},
+ }
+ }
daemonSet.Spec.Template.Spec.Containers[0].Args = getPodArgs(devicePlugin)
daemonSet.Spec.Template.Spec.Containers[0].Image = devicePlugin.Spec.Image
diff --git a/pkg/controllers/fpga/controller_test.go b/pkg/controllers/fpga/controller_test.go
index b0ca45b8..5a389833 100644
--- a/pkg/controllers/fpga/controller_test.go
+++ b/pkg/controllers/fpga/controller_test.go
@@ -42,13 +42,13 @@ func (c *controller) newDaemonSetExpected(rawObj client.Object) *apps.DaemonSet
maxUnavailable := intstr.FromInt(1)
maxSurge := intstr.FromInt(0)
- return &apps.DaemonSet{
+ ds := &apps.DaemonSet{
TypeMeta: metav1.TypeMeta{
Kind: "DaemonSet",
APIVersion: "apps/v1",
},
ObjectMeta: metav1.ObjectMeta{
- Namespace: c.ns,
+ Namespace: c.args.Namespace,
Name: appLabel + "-" + devicePlugin.Name,
Labels: map[string]string{
"app": appLabel,
@@ -198,6 +198,14 @@ func (c *controller) newDaemonSetExpected(rawObj client.Object) *apps.DaemonSet
},
},
}
+
+ if len(c.args.ImagePullSecretName) > 0 {
+ ds.Spec.Template.Spec.ImagePullSecrets = []v1.LocalObjectReference{
+ {Name: c.args.ImagePullSecretName},
+ }
+ }
+
+ return ds
}
// Test that FPGA daemonset created by using go:embed is
@@ -218,4 +226,12 @@ func TestNewDaemonSetFPGA(t *testing.T) {
if !reflect.DeepEqual(expected, actual) {
t.Errorf("expected and actuall daemonsets differ: %+s", diff.ObjectGoPrintDiff(expected, actual))
}
+
+ c.args.ImagePullSecretName = "mysecret"
+
+ expected = c.newDaemonSetExpected(plugin)
+ actual = c.NewDaemonSet(plugin)
+ if !reflect.DeepEqual(expected, actual) {
+ t.Errorf("expected and actual daemonsets with secret differ: %+s", diff.ObjectGoPrintDiff(expected, actual))
+ }
}
diff --git a/pkg/controllers/gpu/controller.go b/pkg/controllers/gpu/controller.go
index 3c943f52..09e52675 100644
--- a/pkg/controllers/gpu/controller.go
+++ b/pkg/controllers/gpu/controller.go
@@ -49,13 +49,13 @@ var defaultNodeSelector = deployments.GPUPluginDaemonSet().Spec.Template.Spec.No
// +kubebuilder:rbac:groups=deviceplugin.intel.com,resources=gpudeviceplugins/finalizers,verbs=update
// SetupReconciler creates a new reconciler for GpuDevicePlugin objects.
-func SetupReconciler(mgr ctrl.Manager, namespace string, withWebhook bool) error {
- c := &controller{scheme: mgr.GetScheme(), ns: namespace}
+func SetupReconciler(mgr ctrl.Manager, args controllers.ControllerOptions) error {
+ c := &controller{scheme: mgr.GetScheme(), args: args}
if err := controllers.SetupWithManager(mgr, c, devicepluginv1.GroupVersion.String(), "GpuDevicePlugin", ownerKey); err != nil {
return err
}
- if withWebhook {
+ if args.WithWebhook {
return (&devicepluginv1.GpuDevicePlugin{}).SetupWebhookWithManager(mgr)
}
@@ -64,7 +64,7 @@ func SetupReconciler(mgr ctrl.Manager, namespace string, withWebhook bool) error
type controller struct {
scheme *runtime.Scheme
- ns string
+ args controllers.ControllerOptions
}
func (c *controller) CreateEmptyObject() client.Object {
@@ -80,7 +80,7 @@ func (c *controller) NewSharedServiceAccount() *v1.ServiceAccount {
return &v1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{
Name: serviceAccountName,
- Namespace: c.ns,
+ Namespace: c.args.Namespace,
},
}
}
@@ -89,13 +89,13 @@ func (c *controller) NewSharedClusterRoleBinding() *rbacv1.ClusterRoleBinding {
return &rbacv1.ClusterRoleBinding{
ObjectMeta: metav1.ObjectMeta{
Name: roleBindingName,
- Namespace: c.ns,
+ Namespace: c.args.Namespace,
},
Subjects: []rbacv1.Subject{
{
Kind: "ServiceAccount",
Name: serviceAccountName,
- Namespace: c.ns,
+ Namespace: c.args.Namespace,
},
},
RoleRef: rbacv1.RoleRef{
@@ -140,10 +140,16 @@ func (c *controller) NewDaemonSet(rawObj client.Object) *apps.DaemonSet {
daemonSet.Spec.Template.Spec.Tolerations = devicePlugin.Spec.Tolerations
}
- daemonSet.ObjectMeta.Namespace = c.ns
+ daemonSet.ObjectMeta.Namespace = c.args.Namespace
daemonSet.Spec.Template.Spec.Containers[0].Args = getPodArgs(devicePlugin)
daemonSet.Spec.Template.Spec.Containers[0].Image = devicePlugin.Spec.Image
+ if len(c.args.ImagePullSecretName) > 0 {
+ daemonSet.Spec.Template.Spec.ImagePullSecrets = []v1.LocalObjectReference{
+ {Name: c.args.ImagePullSecretName},
+ }
+ }
+
if devicePlugin.Spec.InitImage == "" {
daemonSet.Spec.Template.Spec.InitContainers = nil
daemonSet.Spec.Template.Spec.Volumes = removeVolume(daemonSet.Spec.Template.Spec.Volumes, "nfd-features")
diff --git a/pkg/controllers/gpu/controller_test.go b/pkg/controllers/gpu/controller_test.go
index 994f0d88..aad31697 100644
--- a/pkg/controllers/gpu/controller_test.go
+++ b/pkg/controllers/gpu/controller_test.go
@@ -29,6 +29,7 @@ import (
"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"
)
const appLabel = "intel-gpu-plugin"
@@ -50,7 +51,7 @@ func (c *controller) newDaemonSetExpected(rawObj client.Object) *apps.DaemonSet
APIVersion: "apps/v1",
},
ObjectMeta: metav1.ObjectMeta{
- Namespace: c.ns,
+ Namespace: c.args.Namespace,
Name: appLabel + "-" + devicePlugin.Name,
Labels: map[string]string{
"app": appLabel,
@@ -196,6 +197,12 @@ func (c *controller) newDaemonSetExpected(rawObj client.Object) *apps.DaemonSet
addVolumeMountIfMissing(&daemonSet.Spec.Template.Spec, "sysfsdevices", "/sys/devices", true)
}
+ if len(c.args.ImagePullSecretName) > 0 {
+ daemonSet.Spec.Template.Spec.ImagePullSecrets = []v1.LocalObjectReference{
+ {Name: c.args.ImagePullSecretName},
+ }
+ }
+
return &daemonSet
}
@@ -272,6 +279,24 @@ func TestNewDamonSetGPU(t *testing.T) {
}
}
+func TestNewDamonSetGPUWithSecret(t *testing.T) {
+ c := &controller{
+ args: controllers.ControllerOptions{
+ ImagePullSecretName: "mysecret",
+ },
+ }
+
+ plugin := &devicepluginv1.GpuDevicePlugin{}
+ plugin.Name = "new-gpu-cr-testing"
+
+ expected := c.newDaemonSetExpected(plugin)
+ actual := c.NewDaemonSet(plugin)
+
+ if !reflect.DeepEqual(expected, actual) {
+ t.Errorf("expected and actual daemonsets with secret differ: %+s", diff.ObjectGoPrintDiff(expected, actual))
+ }
+}
+
func TestUpdateDamonSetGPU(t *testing.T) {
tcases := []struct {
name string
diff --git a/pkg/controllers/iaa/controller.go b/pkg/controllers/iaa/controller.go
index bf2ce865..0fe99678 100644
--- a/pkg/controllers/iaa/controller.go
+++ b/pkg/controllers/iaa/controller.go
@@ -45,13 +45,13 @@ const (
// +kubebuilder:rbac:groups=deviceplugin.intel.com,resources=iaadeviceplugins/finalizers,verbs=update
// SetupReconciler creates a new reconciler for IaaDevicePlugin objects.
-func SetupReconciler(mgr ctrl.Manager, namespace string, withWebhook bool) error {
- c := &controller{scheme: mgr.GetScheme(), ns: namespace}
+func SetupReconciler(mgr ctrl.Manager, args controllers.ControllerOptions) error {
+ c := &controller{scheme: mgr.GetScheme(), args: args}
if err := controllers.SetupWithManager(mgr, c, devicepluginv1.GroupVersion.String(), "IaaDevicePlugin", ownerKey); err != nil {
return err
}
- if withWebhook {
+ if args.WithWebhook {
return (&devicepluginv1.IaaDevicePlugin{}).SetupWebhookWithManager(mgr)
}
@@ -61,7 +61,7 @@ func SetupReconciler(mgr ctrl.Manager, namespace string, withWebhook bool) error
type controller struct {
controllers.DefaultServiceAccountFactory
scheme *runtime.Scheme
- ns string
+ args controllers.ControllerOptions
}
func (c *controller) CreateEmptyObject() client.Object {
@@ -199,7 +199,7 @@ func (c *controller) NewDaemonSet(rawObj client.Object) *apps.DaemonSet {
daemonSet.Spec.Template.Spec.Tolerations = devicePlugin.Spec.Tolerations
}
- daemonSet.ObjectMeta.Namespace = c.ns
+ daemonSet.ObjectMeta.Namespace = c.args.Namespace
daemonSet.Spec.Template.Spec.Containers[0].Args = getPodArgs(devicePlugin)
daemonSet.Spec.Template.Spec.Containers[0].Image = devicePlugin.Spec.Image
@@ -208,6 +208,12 @@ func (c *controller) NewDaemonSet(rawObj client.Object) *apps.DaemonSet {
addInitContainer(daemonSet, devicePlugin)
}
+ if len(c.args.ImagePullSecretName) > 0 {
+ daemonSet.Spec.Template.Spec.ImagePullSecrets = []v1.LocalObjectReference{
+ {Name: c.args.ImagePullSecretName},
+ }
+ }
+
return daemonSet
}
diff --git a/pkg/controllers/iaa/controller_test.go b/pkg/controllers/iaa/controller_test.go
index e74ae955..73b7f04c 100644
--- a/pkg/controllers/iaa/controller_test.go
+++ b/pkg/controllers/iaa/controller_test.go
@@ -47,7 +47,7 @@ func (c *controller) newDaemonSetExpected(rawObj client.Object) *apps.DaemonSet
APIVersion: "apps/v1",
},
ObjectMeta: metav1.ObjectMeta{
- Namespace: c.ns,
+ Namespace: c.args.Namespace,
Name: appLabel + "-" + devicePlugin.Name,
Labels: map[string]string{
"app": appLabel,
@@ -177,6 +177,12 @@ func (c *controller) newDaemonSetExpected(rawObj client.Object) *apps.DaemonSet
addInitContainer(&daemonSet, devicePlugin)
}
+ if len(c.args.ImagePullSecretName) > 0 {
+ daemonSet.Spec.Template.Spec.ImagePullSecrets = []v1.LocalObjectReference{
+ {Name: c.args.ImagePullSecretName},
+ }
+ }
+
return &daemonSet
}
@@ -193,4 +199,13 @@ func TestNewDaemonSetIAA(t *testing.T) {
if !reflect.DeepEqual(expected, actual) {
t.Errorf("expected and actuall daemonsets differ: %+s", diff.ObjectGoPrintDiff(expected, actual))
}
+
+ c.args.ImagePullSecretName = "mysecret"
+
+ expected = c.newDaemonSetExpected(plugin)
+ actual = c.NewDaemonSet(plugin)
+
+ if !reflect.DeepEqual(expected, actual) {
+ t.Errorf("expected and actual daemonsets with secret differ: %+s", diff.ObjectGoPrintDiff(expected, actual))
+ }
}
diff --git a/pkg/controllers/qat/controller.go b/pkg/controllers/qat/controller.go
index 36153d86..bcc45a95 100644
--- a/pkg/controllers/qat/controller.go
+++ b/pkg/controllers/qat/controller.go
@@ -47,13 +47,13 @@ var defaultNodeSelector = deployments.QATPluginDaemonSet().Spec.Template.Spec.No
// +kubebuilder:rbac:groups=deviceplugin.intel.com,resources=qatdeviceplugins/finalizers,verbs=update
// SetupReconciler creates a new reconciler for QatDevicePlugin objects.
-func SetupReconciler(mgr ctrl.Manager, namespace string, withWebhook bool) error {
- c := &controller{scheme: mgr.GetScheme(), ns: namespace}
+func SetupReconciler(mgr ctrl.Manager, args controllers.ControllerOptions) error {
+ c := &controller{scheme: mgr.GetScheme(), args: args}
if err := controllers.SetupWithManager(mgr, c, devicepluginv1.GroupVersion.String(), "QatDevicePlugin", ownerKey); err != nil {
return err
}
- if withWebhook {
+ if args.WithWebhook {
return (&devicepluginv1.QatDevicePlugin{}).SetupWebhookWithManager(mgr)
}
@@ -63,7 +63,7 @@ func SetupReconciler(mgr ctrl.Manager, namespace string, withWebhook bool) error
type controller struct {
controllers.DefaultServiceAccountFactory
scheme *runtime.Scheme
- ns string
+ args controllers.ControllerOptions
}
func (c *controller) CreateEmptyObject() client.Object {
@@ -93,7 +93,13 @@ func (c *controller) NewDaemonSet(rawObj client.Object) *apps.DaemonSet {
setInitContainer(&daemonSet.Spec.Template.Spec, devicePlugin.Spec)
}
- daemonSet.ObjectMeta.Namespace = c.ns
+ if len(c.args.ImagePullSecretName) > 0 {
+ daemonSet.Spec.Template.Spec.ImagePullSecrets = []v1.LocalObjectReference{
+ {Name: c.args.ImagePullSecretName},
+ }
+ }
+
+ daemonSet.ObjectMeta.Namespace = c.args.Namespace
daemonSet.Spec.Template.Spec.Containers[0].Args = getPodArgs(devicePlugin)
daemonSet.Spec.Template.Spec.Containers[0].Image = devicePlugin.Spec.Image
diff --git a/pkg/controllers/qat/controller_test.go b/pkg/controllers/qat/controller_test.go
index 4d81ca61..3b12647d 100644
--- a/pkg/controllers/qat/controller_test.go
+++ b/pkg/controllers/qat/controller_test.go
@@ -48,7 +48,7 @@ func (c *controller) newDaemonSetExpected(rawObj client.Object) *apps.DaemonSet
APIVersion: "apps/v1",
},
ObjectMeta: metav1.ObjectMeta{
- Namespace: c.ns,
+ Namespace: c.args.Namespace,
Name: appLabel + "-" + devicePlugin.Name,
Labels: map[string]string{
"app": appLabel,
@@ -176,6 +176,12 @@ func (c *controller) newDaemonSetExpected(rawObj client.Object) *apps.DaemonSet
setInitContainer(&daemonSet.Spec.Template.Spec, devicePlugin.Spec)
}
+ if len(c.args.ImagePullSecretName) > 0 {
+ daemonSet.Spec.Template.Spec.ImagePullSecrets = []v1.LocalObjectReference{
+ {Name: c.args.ImagePullSecretName},
+ }
+ }
+
return &daemonSet
}
@@ -194,4 +200,13 @@ func TestNewDaemonSetQAT(t *testing.T) {
if !reflect.DeepEqual(expected, actual) {
t.Errorf("expected and actuall daemonsets differ: %+s", diff.ObjectGoPrintDiff(expected, actual))
}
+
+ c.args.ImagePullSecretName = "mysecret"
+
+ expected = c.newDaemonSetExpected(plugin)
+ actual = c.NewDaemonSet(plugin)
+
+ if !reflect.DeepEqual(expected, actual) {
+ t.Errorf("expected and actual daemonsets with secret differ: %+s", diff.ObjectGoPrintDiff(expected, actual))
+ }
}
diff --git a/pkg/controllers/reconciler.go b/pkg/controllers/reconciler.go
index 86879cb3..ded2b7f0 100644
--- a/pkg/controllers/reconciler.go
+++ b/pkg/controllers/reconciler.go
@@ -94,6 +94,12 @@ type DevicePluginController interface {
Upgrade(ctx context.Context, obj client.Object) (upgrade bool)
}
+type ControllerOptions struct {
+ Namespace string
+ ImagePullSecretName string
+ WithWebhook bool
+}
+
type reconciler struct {
controller DevicePluginController
client.Client
diff --git a/pkg/controllers/sgx/controller.go b/pkg/controllers/sgx/controller.go
index 05a7f163..2804ceac 100644
--- a/pkg/controllers/sgx/controller.go
+++ b/pkg/controllers/sgx/controller.go
@@ -43,13 +43,13 @@ var defaultNodeSelector = deployments.SGXPluginDaemonSet().Spec.Template.Spec.No
// +kubebuilder:rbac:groups=deviceplugin.intel.com,resources=sgxdeviceplugins/finalizers,verbs=update
// SetupReconciler creates a new reconciler for SgxDevicePlugin objects.
-func SetupReconciler(mgr ctrl.Manager, namespace string, withWebhook bool) error {
- c := &controller{scheme: mgr.GetScheme(), ns: namespace}
+func SetupReconciler(mgr ctrl.Manager, args controllers.ControllerOptions) error {
+ c := &controller{scheme: mgr.GetScheme(), args: args}
if err := controllers.SetupWithManager(mgr, c, devicepluginv1.GroupVersion.String(), "SgxDevicePlugin", ownerKey); err != nil {
return err
}
- if withWebhook {
+ if args.WithWebhook {
return (&devicepluginv1.SgxDevicePlugin{}).SetupWebhookWithManager(mgr)
}
@@ -59,7 +59,7 @@ func SetupReconciler(mgr ctrl.Manager, namespace string, withWebhook bool) error
type controller struct {
controllers.DefaultServiceAccountFactory
scheme *runtime.Scheme
- ns string
+ args controllers.ControllerOptions
}
func (c *controller) Upgrade(ctx context.Context, obj client.Object) bool {
@@ -126,7 +126,7 @@ func (c *controller) NewDaemonSet(rawObj client.Object) *apps.DaemonSet {
daemonSet.Spec.Template.Spec.NodeSelector = devicePlugin.Spec.NodeSelector
}
- daemonSet.ObjectMeta.Namespace = c.ns
+ daemonSet.ObjectMeta.Namespace = c.args.Namespace
daemonSet.Spec.Template.Spec.Containers[0].Args = getPodArgs(devicePlugin)
daemonSet.Spec.Template.Spec.Containers[0].Image = devicePlugin.Spec.Image
@@ -136,6 +136,12 @@ func (c *controller) NewDaemonSet(rawObj client.Object) *apps.DaemonSet {
setInitContainer(&daemonSet.Spec.Template.Spec, devicePlugin.Spec.InitImage)
}
+ if len(c.args.ImagePullSecretName) > 0 {
+ daemonSet.Spec.Template.Spec.ImagePullSecrets = []v1.LocalObjectReference{
+ {Name: c.args.ImagePullSecretName},
+ }
+ }
+
return daemonSet
}
diff --git a/pkg/controllers/sgx/controller_test.go b/pkg/controllers/sgx/controller_test.go
index 47f653ed..78c9f4d0 100644
--- a/pkg/controllers/sgx/controller_test.go
+++ b/pkg/controllers/sgx/controller_test.go
@@ -49,7 +49,7 @@ func (c *controller) newDaemonSetExpected(rawObj client.Object) *apps.DaemonSet
APIVersion: "apps/v1",
},
ObjectMeta: metav1.ObjectMeta{
- Namespace: c.ns,
+ Namespace: c.args.Namespace,
Name: appLabel + "-" + devicePlugin.Name,
Labels: map[string]string{
"app": appLabel,
@@ -157,6 +157,12 @@ func (c *controller) newDaemonSetExpected(rawObj client.Object) *apps.DaemonSet
setInitContainer(&daemonSet.Spec.Template.Spec, devicePlugin.Spec.InitImage)
}
+ if len(c.args.ImagePullSecretName) > 0 {
+ daemonSet.Spec.Template.Spec.ImagePullSecrets = []v1.LocalObjectReference{
+ {Name: c.args.ImagePullSecretName},
+ }
+ }
+
return &daemonSet
}
@@ -173,4 +179,13 @@ func TestNewDaemonSetSGX(t *testing.T) {
if !reflect.DeepEqual(expected, actual) {
t.Errorf("expected and actuall daemonsets differ: %+s", diff.ObjectGoPrintDiff(expected, actual))
}
+
+ c.args.ImagePullSecretName = "mysecret"
+
+ expected = c.newDaemonSetExpected(plugin)
+ actual = c.NewDaemonSet(plugin)
+
+ if !reflect.DeepEqual(expected, actual) {
+ t.Errorf("expected and actual daemonsets with secret differ: %+s", diff.ObjectGoPrintDiff(expected, actual))
+ }
}
diff --git a/test/envtest/suite_test.go b/test/envtest/suite_test.go
index 44e4e090..f2c6d904 100644
--- a/test/envtest/suite_test.go
+++ b/test/envtest/suite_test.go
@@ -113,21 +113,21 @@ func up() {
k8sManager, managerErr := ctrl.NewManager(cfg, ctrl.Options{Scheme: scheme.Scheme, Metrics: metricsserver.Options{BindAddress: "0"}, Controller: config.Controller{SkipNameValidation: &yes}})
Expect(managerErr).To(BeNil())
- withWebhook := true
+ args := ctr.ControllerOptions{Namespace: ns, WithWebhook: false}
- Expect(dlbctr.SetupReconciler(k8sManager, ns, !withWebhook)).To(BeNil())
+ Expect(dlbctr.SetupReconciler(k8sManager, args)).To(BeNil())
- Expect(dsactr.SetupReconciler(k8sManager, ns, !withWebhook)).To(BeNil())
+ Expect(dsactr.SetupReconciler(k8sManager, args)).To(BeNil())
- Expect(fpgactr.SetupReconciler(k8sManager, ns, !withWebhook)).To(BeNil())
+ Expect(fpgactr.SetupReconciler(k8sManager, args)).To(BeNil())
- Expect(gpuctr.SetupReconciler(k8sManager, ns, !withWebhook)).To(BeNil())
+ Expect(gpuctr.SetupReconciler(k8sManager, args)).To(BeNil())
- Expect(iaactr.SetupReconciler(k8sManager, ns, !withWebhook)).To(BeNil())
+ Expect(iaactr.SetupReconciler(k8sManager, args)).To(BeNil())
- Expect(qatctr.SetupReconciler(k8sManager, ns, !withWebhook)).To(BeNil())
+ Expect(qatctr.SetupReconciler(k8sManager, args)).To(BeNil())
- Expect(sgxctr.SetupReconciler(k8sManager, ns, !withWebhook)).To(BeNil())
+ Expect(sgxctr.SetupReconciler(k8sManager, args)).To(BeNil())
ctx, cancel = context.WithCancel(context.TODO())
--
2.34.1