@@ -268,47 +268,23 @@ func (o orderByDefault) Less(i, j int) bool {
268
268
}
269
269
270
270
type PodUpdater interface {
271
- BeginUpdate (resources * collasetutils.RelatedResources , podCh chan * PodUpdateInfo ) (bool , error )
272
- FilterAllowOpsPodsAndUpdatePodContext (podToUpdate []* PodUpdateInfo , ownedIDs map [int ]* appsv1alpha1.ContextDetail , resources * collasetutils.RelatedResources , podCh chan * PodUpdateInfo ) (* time.Duration , error )
273
271
FulfillPodUpdatedInfo (revision * appsv1.ControllerRevision , podUpdateInfo * PodUpdateInfo ) error
272
+ BeginUpdatePod (resources * collasetutils.RelatedResources , podCh chan * PodUpdateInfo ) (bool , error )
273
+ FilterAllowOpsPods (podToUpdate []* PodUpdateInfo , ownedIDs map [int ]* appsv1alpha1.ContextDetail , resources * collasetutils.RelatedResources , podCh chan * PodUpdateInfo ) (* time.Duration , error )
274
274
UpgradePod (podInfo * PodUpdateInfo ) error
275
275
GetPodUpdateFinishStatus (podUpdateInfo * PodUpdateInfo ) (bool , string , error )
276
276
FinishUpdatePod (podInfo * PodUpdateInfo ) error
277
277
}
278
278
279
- func newPodUpdater (ctx context.Context , client client.Client , cls * appsv1alpha1.CollaSet , podControl podcontrol.Interface , recorder record.EventRecorder ) PodUpdater {
280
- switch cls .Spec .UpdateStrategy .PodUpdatePolicy {
281
- case appsv1alpha1 .CollaSetRecreatePodUpdateStrategyType :
282
- return & recreatePodUpdater {collaSet : cls , ctx : ctx , Client : client , podControl : podControl , recorder : recorder }
283
- case appsv1alpha1 .CollaSetInPlaceOnlyPodUpdateStrategyType :
284
- // In case of using native K8s, Pod is only allowed to update with container image, so InPlaceOnly policy is
285
- // implemented with InPlaceIfPossible policy as default for compatibility.
286
- return & inPlaceIfPossibleUpdater {collaSet : cls , ctx : ctx , Client : client }
287
- case appsv1alpha1 .CollaSetReplacePodUpdateStrategyType :
288
- return & replaceUpdatePodUpdater {collaSet : cls , ctx : ctx , Client : client , podControl : podControl , recorder : recorder }
289
- default :
290
- return & inPlaceIfPossibleUpdater {collaSet : cls , ctx : ctx , Client : client , podControl : podControl , recorder : recorder }
291
- }
292
- }
293
-
294
- type PodStatus struct {
295
- ContainerStates map [string ]* ContainerStatus `json:"containerStates,omitempty"`
296
- }
297
-
298
- type ContainerStatus struct {
299
- LatestImage string `json:"latestImage,omitempty"`
300
- LastImageID string `json:"lastImageID,omitempty"`
301
- }
302
-
303
- type inPlaceIfPossibleUpdater struct {
279
+ type GenericPodUpdater struct {
304
280
collaSet * appsv1alpha1.CollaSet
305
281
ctx context.Context
306
282
podControl podcontrol.Interface
307
283
recorder record.EventRecorder
308
284
client.Client
309
285
}
310
286
311
- func (u * inPlaceIfPossibleUpdater ) BeginUpdate (resources * collasetutils.RelatedResources , podCh chan * PodUpdateInfo ) (bool , error ) {
287
+ func (u * GenericPodUpdater ) BeginUpdatePod (resources * collasetutils.RelatedResources , podCh chan * PodUpdateInfo ) (bool , error ) {
312
288
succCount , err := controllerutils .SlowStartBatch (len (podCh ), controllerutils .SlowStartInitialBatchSize , false , func (int , error ) error {
313
289
podInfo := <- podCh
314
290
u .recorder .Eventf (podInfo .Pod , corev1 .EventTypeNormal , "PodUpdateLifecycle" , "try to begin PodOpsLifecycle for updating Pod of CollaSet" )
@@ -339,7 +315,7 @@ func (u *inPlaceIfPossibleUpdater) BeginUpdate(resources *collasetutils.RelatedR
339
315
return updating , nil
340
316
}
341
317
342
- func (u * inPlaceIfPossibleUpdater ) FilterAllowOpsPodsAndUpdatePodContext (podToUpdate []* PodUpdateInfo , ownedIDs map [int ]* appsv1alpha1.ContextDetail , resources * collasetutils.RelatedResources , podCh chan * PodUpdateInfo ) (* time.Duration , error ) {
318
+ func (u * GenericPodUpdater ) FilterAllowOpsPods (podToUpdate []* PodUpdateInfo , ownedIDs map [int ]* appsv1alpha1.ContextDetail , resources * collasetutils.RelatedResources , podCh chan * PodUpdateInfo ) (* time.Duration , error ) {
343
319
var recordedRequeueAfter * time.Duration
344
320
needUpdateContext := false
345
321
for i := range podToUpdate {
@@ -386,6 +362,56 @@ func (u *inPlaceIfPossibleUpdater) FilterAllowOpsPodsAndUpdatePodContext(podToUp
386
362
return recordedRequeueAfter , nil
387
363
}
388
364
365
+ func (u * GenericPodUpdater ) FinishUpdatePod (podInfo * PodUpdateInfo ) error {
366
+ //u.recorder.Eventf().V(1).Info("try to finish update PodOpsLifecycle for Pod", "pod", commonutils.ObjectKeyString(podInfo.Pod))
367
+ if updated , err := podopslifecycle .Finish (u .Client , collasetutils .UpdateOpsLifecycleAdapter , podInfo .Pod ); err != nil {
368
+ return fmt .Errorf ("failed to finish PodOpsLifecycle for updating Pod %s/%s: %s" , podInfo .Namespace , podInfo .Name , err )
369
+ } else if updated {
370
+ // add an expectation for this pod update, before next reconciling
371
+ if err := collasetutils .ActiveExpectations .ExpectUpdate (u .collaSet , expectations .Pod , podInfo .Name , podInfo .ResourceVersion ); err != nil {
372
+ return err
373
+ }
374
+ u .recorder .Eventf (podInfo .Pod ,
375
+ corev1 .EventTypeNormal ,
376
+ "UpdateReady" , "pod %s/%s update finished" , podInfo .Namespace , podInfo .Name )
377
+ }
378
+ return nil
379
+ }
380
+
381
+ func newPodUpdater (ctx context.Context , client client.Client , cls * appsv1alpha1.CollaSet , podControl podcontrol.Interface , recorder record.EventRecorder ) PodUpdater {
382
+ genericPodUpdater := & GenericPodUpdater {collaSet : cls , ctx : ctx , Client : client , podControl : podControl , recorder : recorder }
383
+ switch cls .Spec .UpdateStrategy .PodUpdatePolicy {
384
+ case appsv1alpha1 .CollaSetRecreatePodUpdateStrategyType :
385
+ return & recreatePodUpdater {collaSet : cls , ctx : ctx , Client : client , podControl : podControl , recorder : recorder , GenericPodUpdater : * genericPodUpdater }
386
+ case appsv1alpha1 .CollaSetInPlaceOnlyPodUpdateStrategyType :
387
+ // In case of using native K8s, Pod is only allowed to update with container image, so InPlaceOnly policy is
388
+ // implemented with InPlaceIfPossible policy as default for compatibility.
389
+ return & inPlaceIfPossibleUpdater {collaSet : cls , ctx : ctx , Client : client }
390
+ case appsv1alpha1 .CollaSetReplacePodUpdateStrategyType :
391
+ return & replaceUpdatePodUpdater {collaSet : cls , ctx : ctx , Client : client , podControl : podControl , recorder : recorder }
392
+ default :
393
+ return & inPlaceIfPossibleUpdater {collaSet : cls , ctx : ctx , Client : client , podControl : podControl , recorder : recorder , GenericPodUpdater : * genericPodUpdater }
394
+ }
395
+ }
396
+
397
+ type PodStatus struct {
398
+ ContainerStates map [string ]* ContainerStatus `json:"containerStates,omitempty"`
399
+ }
400
+
401
+ type ContainerStatus struct {
402
+ LatestImage string `json:"latestImage,omitempty"`
403
+ LastImageID string `json:"lastImageID,omitempty"`
404
+ }
405
+
406
+ type inPlaceIfPossibleUpdater struct {
407
+ collaSet * appsv1alpha1.CollaSet
408
+ ctx context.Context
409
+ podControl podcontrol.Interface
410
+ recorder record.EventRecorder
411
+ GenericPodUpdater
412
+ client.Client
413
+ }
414
+
389
415
func (u * inPlaceIfPossibleUpdater ) FulfillPodUpdatedInfo (
390
416
updatedRevision * appsv1.ControllerRevision ,
391
417
podUpdateInfo * PodUpdateInfo ) error {
@@ -605,22 +631,6 @@ func (u *inPlaceIfPossibleUpdater) GetPodUpdateFinishStatus(podUpdateInfo *PodUp
605
631
return true , "" , nil
606
632
}
607
633
608
- func (u * inPlaceIfPossibleUpdater ) FinishUpdatePod (podInfo * PodUpdateInfo ) error {
609
- //u.recorder.Eventf().V(1).Info("try to finish update PodOpsLifecycle for Pod", "pod", commonutils.ObjectKeyString(podInfo.Pod))
610
- if updated , err := podopslifecycle .Finish (u .Client , collasetutils .UpdateOpsLifecycleAdapter , podInfo .Pod ); err != nil {
611
- return fmt .Errorf ("failed to finish PodOpsLifecycle for updating Pod %s/%s: %s" , podInfo .Namespace , podInfo .Name , err )
612
- } else if updated {
613
- // add an expectation for this pod update, before next reconciling
614
- if err := collasetutils .ActiveExpectations .ExpectUpdate (u .collaSet , expectations .Pod , podInfo .Name , podInfo .ResourceVersion ); err != nil {
615
- return err
616
- }
617
- u .recorder .Eventf (podInfo .Pod ,
618
- corev1 .EventTypeNormal ,
619
- "UpdateReady" , "pod %s/%s update finished" , podInfo .Namespace , podInfo .Name )
620
- }
621
- return nil
622
- }
623
-
624
634
// TODO
625
635
type inPlaceOnlyPodUpdater struct {
626
636
}
@@ -650,87 +660,10 @@ type recreatePodUpdater struct {
650
660
ctx context.Context
651
661
podControl podcontrol.Interface
652
662
recorder record.EventRecorder
663
+ GenericPodUpdater
653
664
client.Client
654
665
}
655
666
656
- func (u * recreatePodUpdater ) BeginUpdate (resources * collasetutils.RelatedResources , podCh chan * PodUpdateInfo ) (bool , error ) {
657
- succCount , err := controllerutils .SlowStartBatch (len (podCh ), controllerutils .SlowStartInitialBatchSize , false , func (int , error ) error {
658
- podInfo := <- podCh
659
- u .recorder .Eventf (podInfo .Pod , corev1 .EventTypeNormal , "PodUpdateLifecycle" , "try to begin PodOpsLifecycle for updating Pod of CollaSet" )
660
- if updated , err := podopslifecycle .Begin (u .Client , collasetutils .UpdateOpsLifecycleAdapter , podInfo .Pod , func (obj client.Object ) (bool , error ) {
661
- if ! podInfo .OnlyMetadataChanged && ! podInfo .InPlaceUpdateSupport {
662
- return podopslifecycle .WhenBeginDelete (obj )
663
- }
664
- return false , nil
665
- }); err != nil {
666
- return fmt .Errorf ("fail to begin PodOpsLifecycle for updating Pod %s/%s: %s" , podInfo .Namespace , podInfo .Name , err )
667
- } else if updated {
668
- // add an expectation for this pod update, before next reconciling
669
- if err := collasetutils .ActiveExpectations .ExpectUpdate (u .collaSet , expectations .Pod , podInfo .Name , podInfo .ResourceVersion ); err != nil {
670
- return err
671
- }
672
- }
673
-
674
- return nil
675
- })
676
-
677
- updating := succCount > 0
678
- if err != nil {
679
- collasetutils .AddOrUpdateCondition (resources .NewStatus , appsv1alpha1 .CollaSetUpdate , err , "UpdateFailed" , err .Error ())
680
- return updating , err
681
- } else {
682
- collasetutils .AddOrUpdateCondition (resources .NewStatus , appsv1alpha1 .CollaSetUpdate , nil , "Updated" , "" )
683
- }
684
- return updating , nil
685
- }
686
-
687
- func (u * recreatePodUpdater ) FilterAllowOpsPodsAndUpdatePodContext (podToUpdate []* PodUpdateInfo , ownedIDs map [int ]* appsv1alpha1.ContextDetail , resources * collasetutils.RelatedResources , podCh chan * PodUpdateInfo ) (* time.Duration , error ) {
688
- var recordedRequeueAfter * time.Duration
689
- needUpdateContext := false
690
- for i := range podToUpdate {
691
- podInfo := podToUpdate [i ]
692
- requeueAfter , allowed := podopslifecycle .AllowOps (collasetutils .UpdateOpsLifecycleAdapter , realValue (u .collaSet .Spec .UpdateStrategy .OperationDelaySeconds ), podInfo .Pod )
693
- if ! allowed {
694
- u .recorder .Eventf (podInfo , corev1 .EventTypeNormal , "PodUpdateLifecycle" , "Pod %s is not allowed to update" , commonutils .ObjectKeyString (podInfo .Pod ))
695
- continue
696
- }
697
- if requeueAfter != nil {
698
- u .recorder .Eventf (podInfo , corev1 .EventTypeNormal , "PodUpdateLifecycle" , "delay Pod update for %d seconds" , requeueAfter .Seconds ())
699
- if recordedRequeueAfter == nil || * requeueAfter < * recordedRequeueAfter {
700
- recordedRequeueAfter = requeueAfter
701
- }
702
- continue
703
- }
704
-
705
- if ! ownedIDs [podInfo .ID ].Contains (podcontext .RevisionContextDataKey , resources .UpdatedRevision .Name ) {
706
- needUpdateContext = true
707
- ownedIDs [podInfo .ID ].Put (podcontext .RevisionContextDataKey , resources .UpdatedRevision .Name )
708
- }
709
- if podInfo .PodDecorationChanged {
710
- decorationStr := utilspoddecoration .GetDecorationInfoString (podInfo .UpdatedPodDecorations )
711
- if val , ok := ownedIDs [podInfo .ID ].Get (podcontext .PodDecorationRevisionKey ); ! ok || val != decorationStr {
712
- needUpdateContext = true
713
- ownedIDs [podInfo .ID ].Put (podcontext .PodDecorationRevisionKey , decorationStr )
714
- }
715
- }
716
-
717
- if podInfo .IsUpdatedRevision && ! podInfo .PodDecorationChanged {
718
- continue
719
- }
720
- // if Pod has not been updated, update it.
721
- podCh <- podToUpdate [i ]
722
- }
723
- // 4. mark Pod to use updated revision before updating it.
724
- if needUpdateContext {
725
- u .recorder .Eventf (u .collaSet , corev1 .EventTypeNormal , "UpdateToPodContext" , "try to update ResourceContext for CollaSet" )
726
- err := retry .RetryOnConflict (retry .DefaultRetry , func () error {
727
- return podcontext .UpdateToPodContext (u .Client , u .collaSet , ownedIDs )
728
- })
729
- return recordedRequeueAfter , err
730
- }
731
- return recordedRequeueAfter , nil
732
- }
733
-
734
667
func (u * recreatePodUpdater ) FulfillPodUpdatedInfo (_ * appsv1.ControllerRevision , _ * PodUpdateInfo ) error {
735
668
return nil
736
669
}
@@ -744,21 +677,6 @@ func (u *recreatePodUpdater) GetPodUpdateFinishStatus(podInfo *PodUpdateInfo) (f
744
677
return podInfo .IsUpdatedRevision && ! podInfo .PodDecorationChanged , "" , nil
745
678
}
746
679
747
- func (u * recreatePodUpdater ) FinishUpdatePod (podInfo * PodUpdateInfo ) error {
748
- if updated , err := podopslifecycle .Finish (u .Client , collasetutils .UpdateOpsLifecycleAdapter , podInfo .Pod ); err != nil {
749
- return fmt .Errorf ("failed to finish PodOpsLifecycle for updating Pod %s/%s: %s" , podInfo .Namespace , podInfo .Name , err )
750
- } else if updated {
751
- // add an expectation for this pod update, before next reconciling
752
- if err := collasetutils .ActiveExpectations .ExpectUpdate (u .collaSet , expectations .Pod , podInfo .Name , podInfo .ResourceVersion ); err != nil {
753
- return err
754
- }
755
- u .recorder .Eventf (podInfo .Pod ,
756
- corev1 .EventTypeNormal ,
757
- "UpdateReady" , "pod %s/%s update finished" , podInfo .Namespace , podInfo .Name )
758
- }
759
- return nil
760
- }
761
-
762
680
type replaceUpdatePodUpdater struct {
763
681
collaSet * appsv1alpha1.CollaSet
764
682
ctx context.Context
@@ -767,7 +685,7 @@ type replaceUpdatePodUpdater struct {
767
685
client.Client
768
686
}
769
687
770
- func (u * replaceUpdatePodUpdater ) BeginUpdate (resources * collasetutils.RelatedResources , podCh chan * PodUpdateInfo ) (updating bool , err error ) {
688
+ func (u * replaceUpdatePodUpdater ) BeginUpdatePod (resources * collasetutils.RelatedResources , podCh chan * PodUpdateInfo ) (bool , error ) {
771
689
succCount , err := controllerutils .SlowStartBatch (len (podCh ), controllerutils .SlowStartInitialBatchSize , false , func (int , error ) error {
772
690
podInfo := <- podCh
773
691
if podInfo .replacePairNewPodInfo != nil {
@@ -785,10 +703,10 @@ func (u *replaceUpdatePodUpdater) BeginUpdate(resources *collasetutils.RelatedRe
785
703
newPodRevision ,
786
704
resources .UpdatedRevision .Name )
787
705
patch := client .RawPatch (types .StrategicMergePatchType , []byte (fmt .Sprintf (`{"metadata":{"labels":{"%s":"%d"}}}` , appsv1alpha1 .PodDeletionIndicationLabelKey , time .Now ().UnixNano ())))
788
- if err = u .Patch (u .ctx , podInfo .replacePairNewPodInfo .Pod , patch ); err != nil {
789
- err = fmt .Errorf ("failed to delete replace pair new pod %s/%s %s" ,
790
- podInfo .replacePairNewPodInfo .Namespace , podInfo .replacePairNewPodInfo .Name , err )
791
- return nil
706
+ if patchErr : = u .Patch (u .ctx , podInfo .replacePairNewPodInfo .Pod , patch ); patchErr != nil {
707
+ err : = fmt .Errorf ("failed to delete replace pair new pod %s/%s %s" ,
708
+ podInfo .replacePairNewPodInfo .Namespace , podInfo .replacePairNewPodInfo .Name , patchErr )
709
+ return err
792
710
}
793
711
}
794
712
return nil
@@ -797,34 +715,18 @@ func (u *replaceUpdatePodUpdater) BeginUpdate(resources *collasetutils.RelatedRe
797
715
return succCount > 0 , err
798
716
}
799
717
800
- func (u * replaceUpdatePodUpdater ) FilterAllowOpsPodsAndUpdatePodContext (_ []* PodUpdateInfo , _ map [int ]* appsv1alpha1.ContextDetail , _ * collasetutils.RelatedResources , _ chan * PodUpdateInfo ) (requeueAfter * time.Duration , err error ) {
801
- return
718
+ func (u * replaceUpdatePodUpdater ) FilterAllowOpsPods (podToUpdate []* PodUpdateInfo , _ map [int ]* appsv1alpha1.ContextDetail , _ * collasetutils.RelatedResources , podCh chan * PodUpdateInfo ) (requeueAfter * time.Duration , err error ) {
719
+ for i , podInfo := range podToUpdate {
720
+ if podInfo .IsUpdatedRevision && ! podInfo .PodDecorationChanged && ! podInfo .PvcTmpHashChanged {
721
+ continue
722
+ }
723
+
724
+ podCh <- podToUpdate [i ]
725
+ }
726
+ return nil , err
802
727
}
803
728
804
729
func (u * replaceUpdatePodUpdater ) FulfillPodUpdatedInfo (_ * appsv1.ControllerRevision , _ * PodUpdateInfo ) (err error ) {
805
- //// when replaceUpdate, inPlaceUpdateSupport and onlyMetadataChanged always false
806
- //// judge replace pair new pod is updated revision, if not, delete.
807
- //if podUpdateInfo.replacePairNewPodInfo != nil {
808
- // replacePairNewPod := podUpdateInfo.replacePairNewPodInfo.Pod
809
- // newPodRevision, exist := replacePairNewPod.Labels[appsv1.ControllerRevisionHashLabelKey]
810
- // if exist && newPodRevision == updatedRevision.Name {
811
- // return
812
- // }
813
- // u.recorder.Eventf(podUpdateInfo.Pod,
814
- // corev1.EventTypeNormal,
815
- // "ReplaceUpdatePod",
816
- // "label to-delete on new pair pod %s/%s because it is not updated revision, current revision: %s, updated revision: %s",
817
- // replacePairNewPod.Namespace,
818
- // replacePairNewPod.Name,
819
- // newPodRevision,
820
- // updatedRevision.Name)
821
- // patch := client.RawPatch(types.StrategicMergePatchType, []byte(fmt.Sprintf(`{"metadata":{"labels":{"%s":"%d"}}}`, appsv1alpha1.PodDeletionIndicationLabelKey, time.Now().UnixNano())))
822
- // if err = u.Patch(u.ctx, podUpdateInfo.replacePairNewPodInfo.Pod, patch); err != nil {
823
- // err = fmt.Errorf("failed to delete replace pair new pod %s/%s %s",
824
- // podUpdateInfo.replacePairNewPodInfo.Namespace, podUpdateInfo.replacePairNewPodInfo.Name, err)
825
- // return
826
- // }
827
- //}
828
730
return
829
731
}
830
732
0 commit comments