@@ -29,7 +29,7 @@ import (
29
29
30
30
"github.com/klauspost/compress/zstd"
31
31
corev1 "k8s.io/api/core/v1"
32
- metav1 "k8s.io/apimachinery/pkg/apis/meta /v1"
32
+ rbacv1 "k8s.io/api/rbac /v1"
33
33
"k8s.io/apimachinery/pkg/util/runtime"
34
34
"sigs.k8s.io/controller-runtime/pkg/client"
35
35
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
@@ -228,101 +228,133 @@ func buildInstanceByTemplate(tree *kubebuilderx.ObjectTree, name string, templat
228
228
return inst , nil
229
229
}
230
230
231
- // copyAndMerge merges two objects for updating:
232
- // 1. new an object targetObj by copying from oldObj
233
- // 2. merge all fields can be updated from newObj into targetObj
234
- func copyAndMerge (oldObj , newObj client.Object ) client.Object {
235
- if reflect .TypeOf (oldObj ) != reflect .TypeOf (newObj ) {
236
- return nil
237
- }
231
+ func copyAndMergeInstance (oldInst , newInst * workloads.Instance ) * workloads.Instance {
232
+ targetInst := oldInst .DeepCopyObject ().(* workloads.Instance )
238
233
239
- copyAndMergeSvc := func (oldSvc * corev1.Service , newSvc * corev1.Service ) client.Object {
240
- intctrlutil .MergeList (& newSvc .Finalizers , & oldSvc .Finalizers , func (finalizer string ) func (string ) bool {
241
- return func (item string ) bool {
242
- return finalizer == item
243
- }
244
- })
245
- intctrlutil .MergeList (& newSvc .OwnerReferences , & oldSvc .OwnerReferences , func (reference metav1.OwnerReference ) func (metav1.OwnerReference ) bool {
246
- return func (item metav1.OwnerReference ) bool {
247
- return reference .UID == item .UID
248
- }
249
- })
250
- mergeMap (& newSvc .Annotations , & oldSvc .Annotations )
251
- mergeMap (& newSvc .Labels , & oldSvc .Labels )
252
- oldSvc .Spec .Selector = newSvc .Spec .Selector
253
- oldSvc .Spec .Type = newSvc .Spec .Type
254
- oldSvc .Spec .PublishNotReadyAddresses = newSvc .Spec .PublishNotReadyAddresses
255
- // ignore NodePort&LB svc here, instanceSet only supports default headless svc
256
- oldSvc .Spec .Ports = newSvc .Spec .Ports
257
- return oldSvc
258
- }
234
+ // merge pod
235
+ mergeInPlaceFields (& newInst .Spec .Template , & targetInst .Spec .Template )
236
+ targetInst .Spec .Selector = newInst .Spec .Selector
237
+ targetInst .Spec .MinReadySeconds = newInst .Spec .MinReadySeconds
259
238
260
- copyAndMergeCm := func (oldCm , newCm * corev1.ConfigMap ) client.Object {
261
- intctrlutil .MergeList (& newCm .Finalizers , & oldCm .Finalizers , func (finalizer string ) func (string ) bool {
262
- return func (item string ) bool {
263
- return finalizer == item
264
- }
265
- })
266
- intctrlutil .MergeList (& newCm .OwnerReferences , & oldCm .OwnerReferences , func (reference metav1.OwnerReference ) func (metav1.OwnerReference ) bool {
267
- return func (item metav1.OwnerReference ) bool {
268
- return reference .UID == item .UID
269
- }
270
- })
271
- oldCm .Data = newCm .Data
272
- oldCm .BinaryData = newCm .BinaryData
273
- return oldCm
274
- }
275
-
276
- copyAndMergePod := func (oldPod , newPod * corev1.Pod ) client.Object {
277
- mergeInPlaceFields (newPod , oldPod )
278
- return oldPod
279
- }
280
-
281
- copyAndMergePVC := func (oldPVC , newPVC * corev1.PersistentVolumeClaim ) client.Object {
282
- mergeMap (& newPVC .Annotations , & oldPVC .Annotations )
239
+ // merge pvcs
240
+ for i := range newInst .Spec .VolumeClaimTemplates {
241
+ newPVC := & newInst .Spec .VolumeClaimTemplates [i ]
242
+ oldPVC := & targetInst .Spec .VolumeClaimTemplates [i ]
283
243
mergeMap (& newPVC .Labels , & oldPVC .Labels )
244
+ mergeMap (& newPVC .Annotations , & oldPVC .Annotations )
284
245
// resources.request.storage and accessModes support in-place update.
285
246
// resources.request.storage only supports volume expansion.
286
247
if reflect .DeepEqual (oldPVC .Spec .AccessModes , newPVC .Spec .AccessModes ) &&
287
248
oldPVC .Spec .Resources .Requests .Storage ().Cmp (* newPVC .Spec .Resources .Requests .Storage ()) >= 0 {
288
- return oldPVC
249
+ continue
289
250
}
290
251
oldPVC .Spec .AccessModes = newPVC .Spec .AccessModes
291
252
if newPVC .Spec .Resources .Requests == nil {
292
- return oldPVC
253
+ continue
293
254
}
294
255
if _ , ok := newPVC .Spec .Resources .Requests [corev1 .ResourceStorage ]; ! ok {
295
- return oldPVC
256
+ continue
296
257
}
297
258
requests := oldPVC .Spec .Resources .Requests
298
259
if requests == nil {
299
260
requests = make (corev1.ResourceList )
300
261
}
301
262
requests [corev1 .ResourceStorage ] = * newPVC .Spec .Resources .Requests .Storage ()
302
263
oldPVC .Spec .Resources .Requests = requests
303
- return oldPVC
304
264
}
265
+ targetInst .Spec .PersistentVolumeClaimRetentionPolicy = newInst .Spec .PersistentVolumeClaimRetentionPolicy
305
266
306
- copyAndMergeInstance := func (oldInst , newInst * workloads.Instance ) client.Object {
307
- // TODO: impl
308
- return newInst
267
+ copyAndMergeSvc := func (oldSvc , newSvc * corev1.Service ) client.Object {
268
+ mergeMap (& newSvc .Labels , & oldSvc .Labels )
269
+ mergeMap (& newSvc .Annotations , & oldSvc .Annotations )
270
+ oldSvc .Spec .Selector = newSvc .Spec .Selector
271
+ oldSvc .Spec .Type = newSvc .Spec .Type
272
+ oldSvc .Spec .PublishNotReadyAddresses = newSvc .Spec .PublishNotReadyAddresses
273
+ // ignore NodePort&LB svc here, instanceSet only supports default headless svc
274
+ oldSvc .Spec .Ports = newSvc .Spec .Ports
275
+ return oldSvc
276
+ }
277
+
278
+ copyAndMergeCM := func (old , new * corev1.ConfigMap ) client.Object {
279
+ mergeMap (& new .Labels , & old .Labels )
280
+ mergeMap (& new .Annotations , & old .Annotations )
281
+ old .Data = new .Data
282
+ old .BinaryData = new .BinaryData
283
+ return old
284
+ }
285
+
286
+ copyAndMergeSecret := func (old , new * corev1.Secret ) client.Object {
287
+ mergeMap (& new .Labels , & old .Labels )
288
+ mergeMap (& new .Annotations , & old .Annotations )
289
+ old .Data = new .Data
290
+ old .StringData = new .StringData
291
+ return old
292
+ }
293
+
294
+ copyAndMergeSA := func (old , new * corev1.ServiceAccount ) client.Object {
295
+ mergeMap (& new .Labels , & old .Labels )
296
+ mergeMap (& new .Annotations , & old .Annotations )
297
+ old .Secrets = new .Secrets
298
+ return old
299
+ }
300
+
301
+ copyAndMergeRole := func (old , new * rbacv1.Role ) client.Object {
302
+ mergeMap (& new .Labels , & old .Labels )
303
+ mergeMap (& new .Annotations , & old .Annotations )
304
+ old .Rules = new .Rules
305
+ return old
306
+ }
307
+
308
+ copyAndMergeRoleBinding := func (old , new * rbacv1.RoleBinding ) client.Object {
309
+ mergeMap (& new .Labels , & old .Labels )
310
+ mergeMap (& new .Annotations , & old .Annotations )
311
+ old .Subjects = new .Subjects
312
+ old .RoleRef = new .RoleRef
313
+ return old
314
+ }
315
+
316
+ copyNMergeAssistantObjects := func () {
317
+ for i := range newInst .Spec .AssistantObjects {
318
+ oldObj := & targetInst .Spec .AssistantObjects [i ]
319
+ newObj := & newInst .Spec .AssistantObjects [i ]
320
+ if newObj .ConfigMap != nil {
321
+ copyAndMergeCM (oldObj .ConfigMap , newObj .ConfigMap )
322
+ }
323
+ if newObj .Secret != nil {
324
+ copyAndMergeSecret (oldObj .Secret , newObj .Secret )
325
+ }
326
+ if newObj .Service != nil {
327
+ copyAndMergeSvc (oldObj .Service , newObj .Service )
328
+ }
329
+ if newObj .ServiceAccount != nil {
330
+ copyAndMergeSA (oldObj .ServiceAccount , newObj .ServiceAccount )
331
+ }
332
+ if newObj .Role != nil {
333
+ copyAndMergeRole (oldObj .Role , newObj .Role )
334
+ }
335
+ if newObj .RoleBinding != nil {
336
+ copyAndMergeRoleBinding (oldObj .RoleBinding , newObj .RoleBinding )
337
+ }
338
+ }
309
339
}
310
340
311
- targetObj := oldObj .DeepCopyObject ()
312
- switch o := newObj .(type ) {
313
- case * workloads.Instance :
314
- return copyAndMergeInstance (targetObj .(* workloads.Instance ), o )
315
- case * corev1.Service :
316
- return copyAndMergeSvc (targetObj .(* corev1.Service ), o )
317
- case * corev1.ConfigMap :
318
- return copyAndMergeCm (targetObj .(* corev1.ConfigMap ), o )
319
- case * corev1.Pod :
320
- return copyAndMergePod (targetObj .(* corev1.Pod ), o )
321
- case * corev1.PersistentVolumeClaim :
322
- return copyAndMergePVC (targetObj .(* corev1.PersistentVolumeClaim ), o )
323
- default :
324
- return newObj
341
+ // merge assistant objects
342
+ if len (targetInst .Spec .AssistantObjects ) == 0 {
343
+ targetInst .Spec .AssistantObjects = newInst .Spec .AssistantObjects
344
+ } else {
345
+ copyNMergeAssistantObjects ()
325
346
}
347
+
348
+ // other fields
349
+ targetInst .Spec .InstanceTemplateName = newInst .Spec .InstanceTemplateName
350
+ targetInst .Spec .InstanceUpdateStrategyType = newInst .Spec .InstanceUpdateStrategyType
351
+ targetInst .Spec .PodUpdatePolicy = newInst .Spec .PodUpdatePolicy
352
+ targetInst .Spec .DisableDefaultHeadlessService = newInst .Spec .DisableDefaultHeadlessService
353
+ targetInst .Spec .Roles = newInst .Spec .Roles
354
+ // targetInst.Spec.MembershipReconfiguration = newInst.Spec.MembershipReconfiguration
355
+ targetInst .Spec .TemplateVars = newInst .Spec .TemplateVars
356
+
357
+ return targetInst
326
358
}
327
359
328
360
func buildInstanceTemplateRevision (template * corev1.PodTemplateSpec , parent * workloads.InstanceSet ) (string , error ) {
0 commit comments