diff --git a/pkg/controller/imagelistpulljob/imagelistpulljob_controller.go b/pkg/controller/imagelistpulljob/imagelistpulljob_controller.go index 3d8169fa6a..c0f9aad3fd 100644 --- a/pkg/controller/imagelistpulljob/imagelistpulljob_controller.go +++ b/pkg/controller/imagelistpulljob/imagelistpulljob_controller.go @@ -64,7 +64,8 @@ var ( // Add creates a new ImageListPullJob Controller and adds it to the Manager with default RBAC. The Manager will set fields on the Controller // and Start it when the Manager is Started. func Add(mgr manager.Manager) error { - if !utildiscovery.DiscoverGVK(controllerKind) || !utilfeature.DefaultFeatureGate.Enabled(features.KruiseDaemon) { + if !utildiscovery.DiscoverGVK(controllerKind) || !utilfeature.DefaultFeatureGate.Enabled(features.KruiseDaemon) || + !utilfeature.DefaultFeatureGate.Enabled(features.ImagePullJobGate) { return nil } return add(mgr, newReconciler(mgr)) diff --git a/pkg/controller/imagepulljob/imagepulljob_controller.go b/pkg/controller/imagepulljob/imagepulljob_controller.go index 0b97adf482..d118b9c054 100644 --- a/pkg/controller/imagepulljob/imagepulljob_controller.go +++ b/pkg/controller/imagepulljob/imagepulljob_controller.go @@ -66,7 +66,8 @@ const ( // Add creates a new ImagePullJob Controller and adds it to the Manager with default RBAC. The Manager will set fields on the Controller // and Start it when the Manager is Started. func Add(mgr manager.Manager) error { - if !utildiscovery.DiscoverGVK(controllerKind) || !utilfeature.DefaultFeatureGate.Enabled(features.KruiseDaemon) { + if !utildiscovery.DiscoverGVK(controllerKind) || !utilfeature.DefaultFeatureGate.Enabled(features.KruiseDaemon) || + !utilfeature.DefaultFeatureGate.Enabled(features.ImagePullJobGate) { return nil } return add(mgr, newReconciler(mgr)) diff --git a/pkg/features/kruise_features.go b/pkg/features/kruise_features.go index 3edbd36358..325f738e34 100644 --- a/pkg/features/kruise_features.go +++ b/pkg/features/kruise_features.go @@ -105,6 +105,9 @@ const ( // PreparingUpdateAsUpdate enable CloneSet/Advanced StatefulSet controller to regard preparing-update Pod // as updated when calculating update/current revision during scaling. PreparingUpdateAsUpdate featuregate.Feature = "PreparingUpdateAsUpdate" + + // ImagePullJobGate enable imagepulljob-controller execute ImagePullJob. + ImagePullJobGate featuregate.Feature = "ImagePullJobGate" ) var defaultFeatureGates = map[featuregate.Feature]featuregate.FeatureSpec{ @@ -129,6 +132,7 @@ var defaultFeatureGates = map[featuregate.Feature]featuregate.FeatureSpec{ PreDownloadImageForDaemonSetUpdate: {Default: false, PreRelease: featuregate.Alpha}, CloneSetEventHandlerOptimization: {Default: false, PreRelease: featuregate.Alpha}, PreparingUpdateAsUpdate: {Default: false, PreRelease: featuregate.Alpha}, + ImagePullJobGate: {Default: false, PreRelease: featuregate.Alpha}, } func init() { @@ -164,5 +168,9 @@ func SetDefaultFeatureGates() { _ = utilfeature.DefaultMutableFeatureGate.Set(fmt.Sprintf("%s=false", PreDownloadImageForDaemonSetUpdate)) _ = utilfeature.DefaultMutableFeatureGate.Set(fmt.Sprintf("%s=false", PodProbeMarkerGate)) _ = utilfeature.DefaultMutableFeatureGate.Set(fmt.Sprintf("%s=false", SidecarTerminator)) + _ = utilfeature.DefaultMutableFeatureGate.Set(fmt.Sprintf("%s=false", ImagePullJobGate)) + } + if utilfeature.DefaultFeatureGate.Enabled(PreDownloadImageForInPlaceUpdate) || utilfeature.DefaultFeatureGate.Enabled(PreDownloadImageForDaemonSetUpdate) { + _ = utilfeature.DefaultMutableFeatureGate.Set(fmt.Sprintf("%s=true", ImagePullJobGate)) } } diff --git a/pkg/webhook/imagelistpulljob/validating/imagelistpulljob_create_update_handler.go b/pkg/webhook/imagelistpulljob/validating/imagelistpulljob_create_update_handler.go index 9c62494352..c22a42e35e 100644 --- a/pkg/webhook/imagelistpulljob/validating/imagelistpulljob_create_update_handler.go +++ b/pkg/webhook/imagelistpulljob/validating/imagelistpulljob_create_update_handler.go @@ -51,6 +51,9 @@ func (h *ImageListPullJobCreateUpdateHandler) Handle(ctx context.Context, req ad if !utilfeature.DefaultFeatureGate.Enabled(features.KruiseDaemon) { return admission.Errored(http.StatusForbidden, fmt.Errorf("feature-gate %s is not enabled", features.KruiseDaemon)) } + if !utilfeature.DefaultFeatureGate.Enabled(features.ImagePullJobGate) { + return admission.Errored(http.StatusForbidden, fmt.Errorf("feature-gate %s is not enabled", features.ImagePullJobGate)) + } if err := validate(obj); err != nil { klog.Warningf("Error validate ImageListPullJob %s/%s: %v", obj.Namespace, obj.Name, err) diff --git a/pkg/webhook/imagepulljob/validating/imagepulljob_create_update_handler.go b/pkg/webhook/imagepulljob/validating/imagepulljob_create_update_handler.go index eaf3de8346..7c711933a1 100644 --- a/pkg/webhook/imagepulljob/validating/imagepulljob_create_update_handler.go +++ b/pkg/webhook/imagepulljob/validating/imagepulljob_create_update_handler.go @@ -51,6 +51,9 @@ func (h *ImagePullJobCreateUpdateHandler) Handle(ctx context.Context, req admiss if !utilfeature.DefaultFeatureGate.Enabled(features.KruiseDaemon) { return admission.Errored(http.StatusForbidden, fmt.Errorf("feature-gate %s is not enabled", features.KruiseDaemon)) } + if !utilfeature.DefaultFeatureGate.Enabled(features.ImagePullJobGate) { + return admission.Errored(http.StatusForbidden, fmt.Errorf("feature-gate %s is not enabled", features.ImagePullJobGate)) + } if err := validate(obj); err != nil { klog.Warningf("Error validate ImagePullJob %s/%s: %v", obj.Namespace, obj.Name, err) diff --git a/test/e2e/apps/pullimages.go b/test/e2e/apps/pullimages.go index 7d61c0057f..c32e212e97 100644 --- a/test/e2e/apps/pullimages.go +++ b/test/e2e/apps/pullimages.go @@ -17,6 +17,7 @@ limitations under the License. package apps import ( + "context" "fmt" "time" @@ -108,11 +109,23 @@ var _ = SIGDescribe("PullImage", func() { ActiveDeadlineSeconds: utilpointer.Int64Ptr(50), TTLSecondsAfterFinished: utilpointer.Int32Ptr(20), }, + PullSecrets: []string{"test-pull-secret"}, }, } - err := testerForImagePullJob.CreateJob(job) + secret := &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: ns, + Name: "test-pull-secret", + }, + Type: v1.SecretTypeDockercfg, + Data: map[string][]byte{ + v1.DockerConfigKey: []byte(`{"auths":{"docker.io/library/nginx":{"username":"echoserver","password":"test","auth":"ZWNob3NlcnZlcjp0ZXN0"}}}`), + }, + } + _, err := c.CoreV1().Secrets(ns).Create(context.TODO(), secret, metav1.CreateOptions{}) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + err = testerForImagePullJob.CreateJob(job) gomega.Expect(err).NotTo(gomega.HaveOccurred()) - ginkgo.By("Desired should be equal to number of nodes") gomega.Eventually(func() int32 { job, err = testerForImagePullJob.GetJob(job)