Skip to content

Commit ab1c70d

Browse files
committed
Use lazy copy for annotations
1 parent ac28648 commit ab1c70d

8 files changed

Lines changed: 361 additions & 167 deletions

controllers/actions.github.com/autoscalinglistener_controller.go

Lines changed: 110 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,10 @@ package actionsgithubcom
1919
import (
2020
"context"
2121
"fmt"
22-
"maps"
23-
"reflect"
2422
"time"
2523

2624
"github.com/go-logr/logr"
25+
"github.com/google/go-cmp/cmp"
2726
kerrors "k8s.io/apimachinery/pkg/api/errors"
2827
"k8s.io/apimachinery/pkg/runtime"
2928
"k8s.io/apimachinery/pkg/types"
@@ -78,7 +77,6 @@ func (r *AutoscalingListenerReconciler) Reconcile(ctx context.Context, req ctrl.
7877
if err := r.Get(ctx, req.NamespacedName, &autoscalingListener); err != nil {
7978
return ctrl.Result{}, client.IgnoreNotFound(err)
8079
}
81-
var original once[*v1alpha1.AutoscalingListener]
8280

8381
if !autoscalingListener.DeletionTimestamp.IsZero() {
8482
if !controllerutil.ContainsFinalizer(&autoscalingListener, autoscalingListenerFinalizerName) {
@@ -93,15 +91,15 @@ func (r *AutoscalingListenerReconciler) Reconcile(ctx context.Context, req ctrl.
9391
}
9492
if requeue {
9593
log.Info("Waiting for resources to be deleted before removing finalizer")
96-
return ctrl.Result{Requeue: true, RequeueAfter: time.Second}, nil
94+
return ctrl.Result{RequeueAfter: time.Second}, nil
9795
}
9896

99-
removeFinalizer := controllerutil.ContainsFinalizer(&autoscalingListener, autoscalingListenerFinalizerName)
100-
if removeFinalizer {
101-
original.Do(autoscalingListener.DeepCopy)
97+
original := newOnce(autoscalingListener.DeepCopy)
98+
if controllerutil.ContainsFinalizer(&autoscalingListener, autoscalingListenerFinalizerName) {
99+
original.Do()
102100
controllerutil.RemoveFinalizer(&autoscalingListener, autoscalingListenerFinalizerName)
103101
}
104-
if removeFinalizer {
102+
if original.Called() {
105103
log.Info("Removing finalizer")
106104
if err := r.Patch(ctx, &autoscalingListener, client.MergeFrom(original.Get())); err != nil && !kerrors.IsNotFound(err) {
107105
log.Error(err, "Failed to remove finalizer")
@@ -114,19 +112,19 @@ func (r *AutoscalingListenerReconciler) Reconcile(ctx context.Context, req ctrl.
114112
return ctrl.Result{}, nil
115113
}
116114

115+
original := newOnce(autoscalingListener.DeepCopy)
117116
addFinalizer := !controllerutil.ContainsFinalizer(&autoscalingListener, autoscalingListenerFinalizerName)
118117
if addFinalizer {
119-
original.Do(autoscalingListener.DeepCopy)
118+
original.Do()
120119
controllerutil.AddFinalizer(&autoscalingListener, autoscalingListenerFinalizerName)
121120
}
122-
if addFinalizer {
121+
if original.Called() {
123122
if err := r.Patch(ctx, &autoscalingListener, client.MergeFrom(original.Get())); err != nil {
124123
log.Error(err, "Failed to add finalizer")
125124
return ctrl.Result{}, err
126125
}
127126

128127
log.Info("Successfully added finalizer")
129-
return ctrl.Result{}, nil
130128
}
131129

132130
// Check if the AutoscalingRunnerSet exists
@@ -174,28 +172,40 @@ func (r *AutoscalingListenerReconciler) Reconcile(ctx context.Context, req ctrl.
174172
return ctrl.Result{}, err
175173
}
176174

177-
desiredLabels := r.filterAndMergeLabels(serviceAccount.Labels, desiredServiceAccount.Labels)
178-
labelsModified := !maps.Equal(serviceAccount.Labels, desiredLabels)
179-
desiredAnnotations := r.mergeAnnotations(serviceAccount.Annotations, desiredServiceAccount.Annotations)
180-
annotationsModified := !maps.Equal(serviceAccount.Annotations, desiredAnnotations)
181-
var original once[*corev1.ServiceAccount]
175+
desiredLabels, labelsModified := r.mergeLabels(serviceAccount.Labels, desiredServiceAccount.Labels)
176+
original := newOnce(serviceAccount.DeepCopy)
182177
if labelsModified {
183-
original.Do(serviceAccount.DeepCopy)
178+
original.Do()
184179
serviceAccount.Labels = desiredLabels
185180
}
181+
desiredAnnotations, annotationsModified := r.mergeAnnotations(serviceAccount.Annotations, desiredServiceAccount.Annotations)
186182
if annotationsModified {
187-
original.Do(serviceAccount.DeepCopy)
183+
original.Do()
188184
serviceAccount.Annotations = desiredAnnotations
189185
}
190-
if labelsModified || annotationsModified {
186+
secretsModified := !cmp.Equal(serviceAccount.Secrets, desiredServiceAccount.Secrets)
187+
if secretsModified {
188+
original.Do()
189+
serviceAccount.Secrets = desiredServiceAccount.Secrets
190+
}
191+
imagePullSecretsModified := !cmp.Equal(serviceAccount.ImagePullSecrets, desiredServiceAccount.ImagePullSecrets)
192+
if imagePullSecretsModified {
193+
original.Do()
194+
serviceAccount.ImagePullSecrets = desiredServiceAccount.ImagePullSecrets
195+
}
196+
automountServiceAccountTokenModified := !cmp.Equal(serviceAccount.AutomountServiceAccountToken, desiredServiceAccount.AutomountServiceAccountToken)
197+
if automountServiceAccountTokenModified {
198+
original.Do()
199+
serviceAccount.AutomountServiceAccountToken = desiredServiceAccount.AutomountServiceAccountToken
200+
}
201+
202+
if original.Called() {
191203
log.Info("Updating listener service account")
192204

193205
if err := r.Patch(ctx, &serviceAccount, client.MergeFrom(original.Get())); err != nil {
194206
log.Error(err, "Failed to update listener service account")
195207
return ctrl.Result{}, err
196208
}
197-
198-
return ctrl.Result{Requeue: true}, nil
199209
}
200210
case kerrors.IsNotFound(err):
201211
// Create a service account for the listener pod in the controller namespace
@@ -218,32 +228,29 @@ func (r *AutoscalingListenerReconciler) Reconcile(ctx context.Context, req ctrl.
218228
)
219229
switch {
220230
case err == nil:
231+
original := newOnce(listenerRole.DeepCopy)
221232
desiredRole := r.newScaleSetListenerRole(&autoscalingListener)
222-
desiredLabels := r.filterAndMergeLabels(listenerRole.Labels, desiredRole.Labels)
223-
labelsModified := !maps.Equal(listenerRole.Labels, desiredLabels)
224-
desiredAnnotations := r.mergeAnnotations(listenerRole.Annotations, desiredRole.Annotations)
225-
annotationsModified := !maps.Equal(listenerRole.Annotations, desiredAnnotations)
226-
rulesModified := !reflect.DeepEqual(listenerRole.Rules, desiredRole.Rules)
227-
var original once[*rbacv1.Role]
233+
desiredLabels, labelsModified := r.mergeLabels(listenerRole.Labels, desiredRole.Labels)
228234
if labelsModified {
229-
original.Do(listenerRole.DeepCopy)
235+
original.Do()
230236
listenerRole.Labels = desiredLabels
231237
}
238+
desiredAnnotations, annotationsModified := r.mergeAnnotations(listenerRole.Annotations, desiredRole.Annotations)
232239
if annotationsModified {
233-
original.Do(listenerRole.DeepCopy)
240+
original.Do()
234241
listenerRole.Annotations = desiredAnnotations
235242
}
243+
rulesModified := !cmp.Equal(listenerRole.Rules, desiredRole.Rules)
236244
if rulesModified {
237-
original.Do(listenerRole.DeepCopy)
245+
original.Do()
238246
listenerRole.Rules = desiredRole.Rules
239247
}
240-
if labelsModified || annotationsModified || rulesModified {
248+
if original.Called() {
241249
log.Info("Updating listener role")
242250
if err := r.Patch(ctx, &listenerRole, client.MergeFrom(original.Get())); err != nil {
243251
log.Error(err, "Failed to update listener role")
244252
return ctrl.Result{}, err
245253
}
246-
return ctrl.Result{Requeue: true}, nil
247254
}
248255
case kerrors.IsNotFound(err):
249256
// Create a role for the listener pod in the AutoScalingRunnerSet namespace
@@ -259,35 +266,42 @@ func (r *AutoscalingListenerReconciler) Reconcile(ctx context.Context, req ctrl.
259266
err = r.Get(ctx, types.NamespacedName{Namespace: autoscalingListener.Spec.AutoscalingRunnerSetNamespace, Name: autoscalingListener.Name}, &listenerRoleBinding)
260267
switch {
261268
case err == nil:
269+
original := newOnce(listenerRoleBinding.DeepCopy)
262270
desiredRoleBinding := r.newScaleSetListenerRoleBinding(
263271
&autoscalingListener,
264272
&listenerRole,
265273
&serviceAccount,
266274
)
267-
desiredLabels := r.filterAndMergeLabels(listenerRoleBinding.Labels, desiredRoleBinding.Labels)
268-
labelsModified := !maps.Equal(listenerRoleBinding.Labels, desiredLabels)
269-
desiredAnnotations := r.mergeAnnotations(listenerRoleBinding.Annotations, desiredRoleBinding.Annotations)
270-
annotationsModified := !maps.Equal(listenerRoleBinding.Annotations, desiredAnnotations)
271-
var original once[*rbacv1.RoleBinding]
275+
desiredLabels, labelsModified := r.mergeLabels(listenerRoleBinding.Labels, desiredRoleBinding.Labels)
272276
if labelsModified {
273-
original.Do(listenerRoleBinding.DeepCopy)
277+
original.Do()
274278
listenerRoleBinding.Labels = desiredLabels
275279
}
280+
281+
desiredAnnotations, annotationsModified := r.mergeAnnotations(listenerRoleBinding.Annotations, desiredRoleBinding.Annotations)
276282
if annotationsModified {
277-
original.Do(listenerRoleBinding.DeepCopy)
283+
original.Do()
278284
listenerRoleBinding.Annotations = desiredAnnotations
279285
}
280-
if labelsModified || annotationsModified {
286+
rulesModified := !cmp.Equal(listenerRoleBinding.RoleRef, desiredRoleBinding.RoleRef)
287+
if rulesModified {
288+
original.Do()
289+
listenerRoleBinding.RoleRef = desiredRoleBinding.RoleRef
290+
}
291+
292+
subjectsModified := !cmp.Equal(listenerRoleBinding.Subjects, desiredRoleBinding.Subjects)
293+
if subjectsModified {
294+
original.Do()
295+
listenerRoleBinding.Subjects = desiredRoleBinding.Subjects
296+
}
297+
298+
if original.Called() {
281299
log.Info("Updating listener role binding")
282300
if err := r.Patch(ctx, &listenerRoleBinding, client.MergeFrom(original.Get())); err != nil {
283301
log.Error(err, "Failed to update listener role binding")
284302
return ctrl.Result{}, err
285303
}
286-
287-
log.Info("Updated listener role binding")
288-
return ctrl.Result{Requeue: true}, nil
289304
}
290-
291305
case kerrors.IsNotFound(err):
292306
// Create a role binding for the listener pod in the AutoScalingRunnerSet namespace
293307
log.Info("Creating a role binding for the service account and role")
@@ -316,31 +330,47 @@ func (r *AutoscalingListenerReconciler) Reconcile(ctx context.Context, req ctrl.
316330
)
317331
switch {
318332
case err == nil:
333+
original := newOnce(proxySecret.DeepCopy)
319334
desiredListenerProxy, err := r.newAutoscalingListenerProxySecret(&autoscalingListener, proxySecret.Data)
320335
if err != nil {
321336
log.Error(err, "Failed to build desired listener proxy secret")
322337
return ctrl.Result{}, err
323338
}
324-
desiredLabels := r.filterAndMergeLabels(proxySecret.Labels, desiredListenerProxy.Labels)
325-
labelsModified := !maps.Equal(proxySecret.Labels, desiredLabels)
326-
desiredAnnotations := r.mergeAnnotations(proxySecret.Annotations, desiredListenerProxy.Annotations)
327-
annotationsModified := !maps.Equal(proxySecret.Annotations, desiredAnnotations)
328-
var original once[*corev1.Secret]
339+
desiredLabels, labelsModified := r.mergeLabels(proxySecret.Labels, desiredListenerProxy.Labels)
329340
if labelsModified {
330-
original.Do(proxySecret.DeepCopy)
341+
original.Do()
331342
proxySecret.Labels = desiredLabels
332343
}
344+
desiredAnnotations, annotationsModified := r.mergeAnnotations(proxySecret.Annotations, desiredListenerProxy.Annotations)
333345
if annotationsModified {
334-
original.Do(proxySecret.DeepCopy)
346+
original.Do()
335347
proxySecret.Annotations = desiredAnnotations
336348
}
337-
if labelsModified || annotationsModified {
349+
// we set the data so we just need to check other fields are nil
350+
if proxySecret.Immutable != nil {
351+
original.Do()
352+
proxySecret.Immutable = nil
353+
}
354+
if proxySecret.StringData != nil {
355+
original.Do()
356+
proxySecret.StringData = nil
357+
}
358+
if proxySecret.Type != desiredListenerProxy.Type {
359+
original.Do()
360+
proxySecret.Type = desiredListenerProxy.Type
361+
}
362+
dataModified := !cmp.Equal(proxySecret.Data, desiredListenerProxy.Data)
363+
if dataModified {
364+
original.Do()
365+
proxySecret.Data = desiredListenerProxy.Data
366+
}
367+
368+
if original.Called() {
338369
log.Info("Updating listener proxy secret")
339370
if err := r.Patch(ctx, &proxySecret, client.MergeFrom(original.Get())); err != nil {
340371
log.Error(err, "Failed to update listener proxy secret")
341372
return ctrl.Result{}, err
342373
}
343-
return ctrl.Result{Requeue: true}, nil
344374
}
345375
case kerrors.IsNotFound(err):
346376
// Create a mirror secret for the listener pod in the Controller namespace for listener pod to use
@@ -363,10 +393,8 @@ func (r *AutoscalingListenerReconciler) Reconcile(ctx context.Context, req ctrl.
363393
log.Error(
364394
err,
365395
"Failed to get app config for AutoscalingRunnerSet.",
366-
"namespace",
367-
autoscalingRunnerSet.Namespace,
368-
"name",
369-
autoscalingRunnerSet.GitHubConfigSecret,
396+
"namespace", autoscalingRunnerSet.Namespace,
397+
"name", autoscalingRunnerSet.GitHubConfigSecret,
370398
)
371399
return nil, err
372400
}
@@ -394,6 +422,7 @@ func (r *AutoscalingListenerReconciler) Reconcile(ctx context.Context, req ctrl.
394422
)
395423
switch {
396424
case err == nil:
425+
original := newOnce(listenerConfigSecret.DeepCopy)
397426
cfg, err := r.GetAppConfig(ctx, &autoscalingRunnerSet)
398427
if err != nil {
399428
return ctrl.Result{}, err
@@ -409,21 +438,31 @@ func (r *AutoscalingListenerReconciler) Reconcile(ctx context.Context, req ctrl.
409438
if err != nil {
410439
return ctrl.Result{}, fmt.Errorf("failed to build listener config secret: %w", err)
411440
}
412-
desiredLabels := r.filterAndMergeLabels(listenerConfigSecret.Labels, desiredSecret.Labels)
413-
labelsModified := !maps.Equal(listenerConfigSecret.Labels, desiredLabels)
414-
desiredAnnotations := r.mergeAnnotations(listenerConfigSecret.Annotations, desiredSecret.Annotations)
415-
annotationsModified := !maps.Equal(listenerConfigSecret.Annotations, desiredAnnotations)
416-
var original once[*corev1.Secret]
441+
desiredLabels, labelsModified := r.mergeLabels(listenerConfigSecret.Labels, desiredSecret.Labels)
417442
if labelsModified {
418-
original.Do(listenerConfigSecret.DeepCopy)
443+
original.Do()
419444
listenerConfigSecret.Labels = desiredLabels
420445
}
446+
desiredAnnotations, annotationsModified := r.mergeAnnotations(listenerConfigSecret.Annotations, desiredSecret.Annotations)
421447
if annotationsModified {
422-
original.Do(listenerConfigSecret.DeepCopy)
448+
original.Do()
423449
listenerConfigSecret.Annotations = desiredAnnotations
424450
}
451+
// we set the data so we just need to check other fields are nil
452+
if listenerConfigSecret.Immutable != nil {
453+
original.Do()
454+
listenerConfigSecret.Immutable = nil
455+
}
456+
if listenerConfigSecret.StringData != nil {
457+
original.Do()
458+
listenerConfigSecret.StringData = nil
459+
}
460+
if listenerConfigSecret.Type != desiredSecret.Type {
461+
original.Do()
462+
listenerConfigSecret.Type = desiredSecret.Type
463+
}
425464

426-
if labelsModified || annotationsModified {
465+
if original.Called() {
427466
log.Info("Updating listener config secret", "namespace", listenerConfigSecret.Namespace, "name", listenerConfigSecret.Name)
428467
if err := r.Patch(ctx, &listenerConfigSecret, client.MergeFrom(original.Get())); err != nil {
429468
return ctrl.Result{}, fmt.Errorf("failed to update listener config secret: %w", err)
@@ -454,7 +493,7 @@ func (r *AutoscalingListenerReconciler) Reconcile(ctx context.Context, req ctrl.
454493
}
455494

456495
// Requeue to create listener pod with the config secret
457-
return ctrl.Result{Requeue: true}, nil
496+
return ctrl.Result{RequeueAfter: 100 * time.Millisecond}, nil
458497
default:
459498
log.Error(err, "Unable to get listener config secret", "namespace", autoscalingListener.Namespace, "name", scaleSetListenerConfigName(&autoscalingListener))
460499
return ctrl.Result{}, err
@@ -484,17 +523,15 @@ func (r *AutoscalingListenerReconciler) Reconcile(ctx context.Context, req ctrl.
484523
return ctrl.Result{}, err
485524
}
486525

487-
desiredLabels := r.filterAndMergeLabels(listenerPod.Labels, desiredPod.Labels)
488-
labelsModified := !maps.Equal(listenerPod.Labels, desiredLabels)
489-
desiredAnnotations := r.mergeAnnotations(listenerPod.Annotations, desiredPod.Annotations)
490-
annotationsModified := !maps.Equal(listenerPod.Annotations, desiredAnnotations)
491-
var original once[*corev1.Pod]
526+
original := newOnce(listenerPod.DeepCopy)
527+
desiredLabels, labelsModified := r.mergeLabels(listenerPod.Labels, desiredPod.Labels)
492528
if labelsModified {
493-
original.Do(listenerPod.DeepCopy)
529+
original.Do()
494530
listenerPod.Labels = desiredLabels
495531
}
532+
desiredAnnotations, annotationsModified := r.mergeAnnotations(listenerPod.Annotations, desiredPod.Annotations)
496533
if annotationsModified {
497-
original.Do(listenerPod.DeepCopy)
534+
original.Do()
498535
listenerPod.Annotations = desiredAnnotations
499536
}
500537

0 commit comments

Comments
 (0)