Skip to content

Commit 0b2fc0e

Browse files
veophimingzhou.swx
and
mingzhou.swx
authored
add controller-revision-hash for imageListPullJob (#1441)
Signed-off-by: mingzhou.swx <[email protected]> Co-authored-by: mingzhou.swx <[email protected]>
1 parent aafd16b commit 0b2fc0e

File tree

2 files changed

+54
-17
lines changed

2 files changed

+54
-17
lines changed

Diff for: pkg/controller/imagelistpulljob/imagelistpulljob_controller.go

+48-14
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,11 @@ package imagelistpulljob
1919
import (
2020
"context"
2121
"fmt"
22+
"hash/fnv"
23+
"reflect"
2224
"time"
2325

26+
appsv1 "k8s.io/api/apps/v1"
2427
corev1 "k8s.io/api/core/v1"
2528
"k8s.io/apimachinery/pkg/api/errors"
2629
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -29,9 +32,11 @@ import (
2932
"k8s.io/apimachinery/pkg/types"
3033
"k8s.io/apimachinery/pkg/util/clock"
3134
utilerrors "k8s.io/apimachinery/pkg/util/errors"
35+
"k8s.io/apimachinery/pkg/util/rand"
3236
"k8s.io/client-go/tools/record"
3337
"k8s.io/client-go/util/retry"
3438
"k8s.io/klog/v2"
39+
hashutil "k8s.io/kubernetes/pkg/util/hash"
3540
"k8s.io/kubernetes/pkg/util/slice"
3641
"sigs.k8s.io/controller-runtime/pkg/client"
3742
"sigs.k8s.io/controller-runtime/pkg/controller"
@@ -40,8 +45,6 @@ import (
4045
"sigs.k8s.io/controller-runtime/pkg/reconcile"
4146
"sigs.k8s.io/controller-runtime/pkg/source"
4247

43-
"reflect"
44-
4548
appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
4649
"github.com/openkruise/kruise/pkg/features"
4750
"github.com/openkruise/kruise/pkg/util"
@@ -141,6 +144,11 @@ func (r *ReconcileImageListPullJob) Reconcile(_ context.Context, request reconci
141144
return reconcile.Result{}, err
142145
}
143146

147+
hash, err := r.refreshJobTemplateHash(job)
148+
if err != nil {
149+
return reconcile.Result{}, fmt.Errorf("refresh job template hash error: %v", err)
150+
}
151+
144152
// The Job has been finished
145153
if job.Status.CompletionTime != nil {
146154
var leftTime time.Duration
@@ -189,7 +197,7 @@ func (r *ReconcileImageListPullJob) Reconcile(_ context.Context, request reconci
189197
newStatus := r.calculateStatus(job, imagePullJobsMap)
190198

191199
// 4. Compute ImagePullJobActions
192-
needToCreate, needToDelete := r.computeImagePullJobActions(job, imagePullJobsMap)
200+
needToCreate, needToDelete := r.computeImagePullJobActions(job, imagePullJobsMap, hash)
193201

194202
// 5. Sync ImagePullJob
195203
err = r.syncImagePullJob(job, needToCreate, needToDelete)
@@ -207,6 +215,25 @@ func (r *ReconcileImageListPullJob) Reconcile(_ context.Context, request reconci
207215
return reconcile.Result{}, nil
208216
}
209217

218+
func (r *ReconcileImageListPullJob) refreshJobTemplateHash(job *appsv1alpha1.ImageListPullJob) (string, error) {
219+
newHash := func(job *appsv1alpha1.ImageListPullJob) string {
220+
jobTemplateHasher := fnv.New32a()
221+
hashutil.DeepHashObject(jobTemplateHasher, job.Spec.ImagePullJobTemplate)
222+
return rand.SafeEncodeString(fmt.Sprint(jobTemplateHasher.Sum32()))
223+
}(job)
224+
225+
oldHash := job.Labels[appsv1.ControllerRevisionHashLabelKey]
226+
if newHash == oldHash {
227+
return newHash, nil
228+
}
229+
230+
emptyJob := &appsv1alpha1.ImageListPullJob{}
231+
emptyJob.SetName(job.Name)
232+
emptyJob.SetNamespace(job.Namespace)
233+
body := fmt.Sprintf(`{"metadata":{"labels":{"%s":"%s"}}}`, appsv1.ControllerRevisionHashLabelKey, newHash)
234+
return newHash, r.Patch(context.TODO(), emptyJob, client.RawPatch(types.MergePatchType, []byte(body)))
235+
}
236+
210237
func (r *ReconcileImageListPullJob) updateStatus(job *appsv1alpha1.ImageListPullJob, newStatus *appsv1alpha1.ImageListPullJobStatus) error {
211238
return retry.RetryOnConflict(retry.DefaultBackoff, func() error {
212239
imageListPullJob := &appsv1alpha1.ImageListPullJob{}
@@ -218,11 +245,11 @@ func (r *ReconcileImageListPullJob) updateStatus(job *appsv1alpha1.ImageListPull
218245
})
219246
}
220247

221-
func (r *ReconcileImageListPullJob) computeImagePullJobActions(job *appsv1alpha1.ImageListPullJob, imagePullJobs map[string]*appsv1alpha1.ImagePullJob) ([]*appsv1alpha1.ImagePullJob, []*appsv1alpha1.ImagePullJob) {
248+
func (r *ReconcileImageListPullJob) computeImagePullJobActions(job *appsv1alpha1.ImageListPullJob, imagePullJobs map[string]*appsv1alpha1.ImagePullJob, hash string) ([]*appsv1alpha1.ImagePullJob, []*appsv1alpha1.ImagePullJob) {
222249
var needToDelete, needToCreate []*appsv1alpha1.ImagePullJob
223250
//1. need to create
224-
images, needToDelete := r.filterImagesAndImagePullJobs(job, imagePullJobs)
225-
needToCreate = r.newImagePullJobs(job, images)
251+
images, needToDelete := r.filterImagesAndImagePullJobs(job, imagePullJobs, hash)
252+
needToCreate = r.newImagePullJobs(job, images, hash)
226253
// some images delete from ImageListPullJob.Spec.Images
227254
for image, imagePullJob := range imagePullJobs {
228255
if !slice.ContainsString(job.Spec.Images, image, nil) {
@@ -333,7 +360,7 @@ func (r *ReconcileImageListPullJob) syncImagePullJob(job *appsv1alpha1.ImageList
333360
return utilerrors.NewAggregate(errs)
334361
}
335362

336-
func (r *ReconcileImageListPullJob) filterImagesAndImagePullJobs(job *appsv1alpha1.ImageListPullJob, imagePullJobs map[string]*appsv1alpha1.ImagePullJob) ([]string, []*appsv1alpha1.ImagePullJob) {
363+
func (r *ReconcileImageListPullJob) filterImagesAndImagePullJobs(job *appsv1alpha1.ImageListPullJob, imagePullJobs map[string]*appsv1alpha1.ImagePullJob, hash string) ([]string, []*appsv1alpha1.ImagePullJob) {
337364
var images, imagesInCurrentImagePullJob []string
338365
var needToDelete []*appsv1alpha1.ImagePullJob
339366

@@ -354,7 +381,7 @@ func (r *ReconcileImageListPullJob) filterImagesAndImagePullJobs(job *appsv1alph
354381
continue
355382
}
356383
// should create new imagePullJob if the template is changed.
357-
if imagePullJobSpecTemplateChanged(imagePullJob, job.Spec.ImagePullJobTemplate) {
384+
if !isConsistentVersion(imagePullJob, &job.Spec.ImagePullJobTemplate, hash) {
358385
images = append(images, image)
359386
// should delete old imagepulljob
360387
needToDelete = append(needToDelete, imagePullJob)
@@ -364,7 +391,7 @@ func (r *ReconcileImageListPullJob) filterImagesAndImagePullJobs(job *appsv1alph
364391
return images, needToDelete
365392
}
366393

367-
func (r *ReconcileImageListPullJob) newImagePullJobs(job *appsv1alpha1.ImageListPullJob, images []string) []*appsv1alpha1.ImagePullJob {
394+
func (r *ReconcileImageListPullJob) newImagePullJobs(job *appsv1alpha1.ImageListPullJob, images []string, hash string) []*appsv1alpha1.ImagePullJob {
368395
var needToCreate []*appsv1alpha1.ImagePullJob
369396
if len(images) <= 0 {
370397
return needToCreate
@@ -374,8 +401,10 @@ func (r *ReconcileImageListPullJob) newImagePullJobs(job *appsv1alpha1.ImageList
374401
ObjectMeta: metav1.ObjectMeta{
375402
Namespace: job.Namespace,
376403
GenerateName: fmt.Sprintf("%s-", job.Name),
377-
Labels: make(map[string]string),
378-
Annotations: make(map[string]string),
404+
Labels: map[string]string{
405+
appsv1.ControllerRevisionHashLabelKey: hash,
406+
},
407+
Annotations: make(map[string]string),
379408
OwnerReferences: []metav1.OwnerReference{
380409
*metav1.NewControllerRef(job, controllerKind),
381410
},
@@ -412,10 +441,15 @@ func (r *ReconcileImageListPullJob) getOwnedImagePullJob(job *appsv1alpha1.Image
412441
return imagePullJobsMap, nil
413442
}
414443

415-
func imagePullJobSpecTemplateChanged(oldImagePullJob *appsv1alpha1.ImagePullJob, newImagePullJobTemplate appsv1alpha1.ImagePullJobTemplate) bool {
416-
if !reflect.DeepEqual(oldImagePullJob.Spec.ImagePullJobTemplate, newImagePullJobTemplate) {
417-
klog.V(3).Infof("imagePullJob(%s/%s) specification changed", oldImagePullJob.Namespace, oldImagePullJob.Name)
444+
func isConsistentVersion(oldImagePullJob *appsv1alpha1.ImagePullJob, newTemplate *appsv1alpha1.ImagePullJobTemplate, hash string) bool {
445+
oldHash, exists := oldImagePullJob.Labels[appsv1.ControllerRevisionHashLabelKey]
446+
if oldHash == hash {
418447
return true
419448
}
449+
if !exists && reflect.DeepEqual(oldImagePullJob.Spec.ImagePullJobTemplate, *newTemplate) {
450+
return true
451+
}
452+
453+
klog.V(4).Infof("imagePullJob(%s/%s) specification changed", oldImagePullJob.Namespace, oldImagePullJob.Name)
420454
return false
421455
}

Diff for: pkg/controller/imagelistpulljob/imagelistpulljob_controller_test.go

+6-3
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ import (
2020
"context"
2121
"testing"
2222

23-
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
24-
2523
"github.com/stretchr/testify/assert"
24+
appsv1 "k8s.io/api/apps/v1"
2625
corev1 "k8s.io/api/core/v1"
2726
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2827
k8sruntime "k8s.io/apimachinery/pkg/runtime"
2928
"k8s.io/apimachinery/pkg/types"
3029
"k8s.io/apimachinery/pkg/util/clock"
30+
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
3131
"k8s.io/client-go/tools/record"
3232
"sigs.k8s.io/controller-runtime/pkg/client"
3333
"sigs.k8s.io/controller-runtime/pkg/client/fake"
@@ -412,7 +412,10 @@ func TestComputeImagePullJobActions(t *testing.T) {
412412
reconcileJob := ReconcileImageListPullJob{}
413413
for _, cs := range cases {
414414
t.Run(cs.name, func(t *testing.T) {
415-
needToCreateImagePullJobs, needToDeleteImagePullJobs := reconcileJob.computeImagePullJobActions(cs.ImageListPullJob, cs.ImagePullJobs)
415+
needToCreateImagePullJobs, needToDeleteImagePullJobs := reconcileJob.computeImagePullJobActions(cs.ImageListPullJob, cs.ImagePullJobs, "v1")
416+
for _, job := range cs.needToCreateImagePullJobs {
417+
job.Labels[appsv1.ControllerRevisionHashLabelKey] = "v1"
418+
}
416419
assert.Equal(t, cs.needToCreateImagePullJobs, needToCreateImagePullJobs)
417420
assert.Equal(t, cs.needToDeleteImagePullJobs, needToDeleteImagePullJobs)
418421
})

0 commit comments

Comments
 (0)