@@ -365,8 +365,14 @@ func dealReplacePods(pods []*corev1.Pod, instance *appsv1alpha1.CollaSet) (needR
365
365
366
366
// pod is replace new created pod, skip replace
367
367
if originPodName , exist := pod .Labels [appsv1alpha1 .PodReplacePairOriginName ]; exist {
368
- if _ , exist := podNameMap [originPodName ]; ! exist {
368
+ // replace pair origin pod is not exist, clean label.
369
+ if originPod , exist := podNameMap [originPodName ]; ! exist {
369
370
needCleanLabels = append (needCleanLabels , appsv1alpha1 .PodReplacePairOriginName )
371
+ } else if ! replaceByUpdate {
372
+ // not replace update, delete origin pod when new created pod is service available
373
+ if _ , serviceAvailable := pod .Labels [appsv1alpha1 .PodServiceAvailableLabel ]; serviceAvailable {
374
+ needDeletePods = append (needDeletePods , originPod )
375
+ }
370
376
}
371
377
}
372
378
@@ -690,143 +696,57 @@ func (r *RealSyncControl) Update(
690
696
logger := r .logger .WithValues ("collaset" , commonutils .ObjectKeyString (cls ))
691
697
var recordedRequeueAfter * time.Duration
692
698
// 1. scan and analysis pods update info
693
- podUpdateInfos , err := attachPodUpdateInfo (ctx , podWrappers , resources )
699
+ podUpdateInfos , err := attachPodUpdateInfo (ctx , cls , podWrappers , resources )
694
700
if err != nil {
695
701
return false , nil , fmt .Errorf ("fail to attach pod update info, %v" , err )
696
702
}
697
- for _ , podInfo := range podUpdateInfos {
698
- // if template is updated, update pod by recreate
699
- podInfo .PvcTmpHashChanged , err = pvccontrol .IsPodPvcTmpChanged (cls , podInfo .PodWrapper .Pod , resources .ExistingPvcs )
700
- if err != nil {
701
- return false , nil , fmt .Errorf ("fail to check pvc template changed, %v" , err )
702
- }
703
- }
704
703
705
704
// 2. decide Pod update candidates
706
705
podToUpdate := decidePodToUpdate (cls , podUpdateInfos )
707
706
podCh := make (chan * PodUpdateInfo , len (podToUpdate ))
708
- updater := newPodUpdater (ctx , r .client , cls )
707
+ updater := newPodUpdater (ctx , r .client , cls , r . podControl , r . recorder )
709
708
updating := false
710
- analysedPod := sets .NewString ()
711
709
712
- if cls .Spec .UpdateStrategy .PodUpdatePolicy != appsv1alpha1 .CollaSetReplacePodUpdateStrategyType {
713
- // 3. prepare Pods to begin PodOpsLifecycle
714
- for i , podInfo := range podToUpdate {
715
- if podInfo .IsUpdatedRevision && ! podInfo .PodDecorationChanged {
716
- continue
717
- }
718
-
719
- if podopslifecycle .IsDuringOps (collasetutils .UpdateOpsLifecycleAdapter , podInfo ) {
720
- continue
721
- }
722
- podCh <- podToUpdate [i ]
710
+ // 3. filter already updated revision,
711
+ for i , podInfo := range podToUpdate {
712
+ if podInfo .IsUpdatedRevision && ! podInfo .PodDecorationChanged && ! podInfo .PvcTmpHashChanged {
713
+ continue
723
714
}
724
715
725
- // 4. begin podOpsLifecycle parallel
726
-
727
- succCount , err := controllerutils .SlowStartBatch (len (podCh ), controllerutils .SlowStartInitialBatchSize , false , func (int , error ) error {
728
- podInfo := <- podCh
729
- // fulfill Pod update information
730
- if err = updater .FulfillPodUpdatedInfo (resources .UpdatedRevision , podInfo ); err != nil {
731
- return fmt .Errorf ("fail to analyse pod %s/%s in-place update support: %s" , podInfo .Namespace , podInfo .Name , err )
732
- }
733
- analysedPod .Insert (podInfo .Name )
734
- logger .V (1 ).Info ("try to begin PodOpsLifecycle for updating Pod of CollaSet" , "pod" , commonutils .ObjectKeyString (podInfo .Pod ))
735
- if updated , err := podopslifecycle .Begin (r .client , collasetutils .UpdateOpsLifecycleAdapter , podInfo .Pod , func (obj client.Object ) (bool , error ) {
736
- if ! podInfo .OnlyMetadataChanged && ! podInfo .InPlaceUpdateSupport {
737
- return podopslifecycle .WhenBeginDelete (obj )
738
- }
739
- return false , nil
740
- }); err != nil {
741
- return fmt .Errorf ("fail to begin PodOpsLifecycle for updating Pod %s/%s: %s" , podInfo .Namespace , podInfo .Name , err )
742
- } else if updated {
743
- // add an expectation for this pod update, before next reconciling
744
- if err := collasetutils .ActiveExpectations .ExpectUpdate (cls , expectations .Pod , podInfo .Name , podInfo .ResourceVersion ); err != nil {
745
- return err
746
- }
747
- }
748
- return nil
749
- })
750
-
751
- updating = updating || succCount > 0
752
- if err != nil {
753
- collasetutils .AddOrUpdateCondition (resources .NewStatus , appsv1alpha1 .CollaSetUpdate , err , "UpdateFailed" , err .Error ())
754
- return updating , nil , err
755
- } else {
756
- collasetutils .AddOrUpdateCondition (resources .NewStatus , appsv1alpha1 .CollaSetUpdate , nil , "Updated" , "" )
716
+ // 3.1 fulfillPodUpdateInfo to all not updatedRevision pod
717
+ if err = updater .FulfillPodUpdatedInfo (resources .UpdatedRevision , podInfo ); err != nil {
718
+ logger .Error (err , fmt .Sprintf ("fail to analyse pod %s/%s in-place update support" , podInfo .Namespace , podInfo .Name ))
719
+ continue
757
720
}
758
721
759
- needUpdateContext := false
760
- for i := range podToUpdate {
761
- podInfo := podToUpdate [i ]
762
- requeueAfter , allowed := podopslifecycle .AllowOps (collasetutils .UpdateOpsLifecycleAdapter , realValue (cls .Spec .UpdateStrategy .OperationDelaySeconds ), podInfo .Pod )
763
- if ! allowed {
764
- r .recorder .Eventf (podInfo , corev1 .EventTypeNormal , "PodUpdateLifecycle" , "Pod %s is not allowed to update" , commonutils .ObjectKeyString (podInfo .Pod ))
765
- continue
766
- }
767
- if requeueAfter != nil {
768
- r .recorder .Eventf (podInfo , corev1 .EventTypeNormal , "PodUpdateLifecycle" , "delay Pod update for %d seconds" , requeueAfter .Seconds ())
769
- if recordedRequeueAfter == nil || * requeueAfter < * recordedRequeueAfter {
770
- recordedRequeueAfter = requeueAfter
771
- }
772
- continue
773
- }
774
-
775
- if ! ownedIDs [podInfo .ID ].Contains (podcontext .RevisionContextDataKey , resources .UpdatedRevision .Name ) {
776
- needUpdateContext = true
777
- ownedIDs [podInfo .ID ].Put (podcontext .RevisionContextDataKey , resources .UpdatedRevision .Name )
778
- }
779
- if podInfo .PodDecorationChanged {
780
- decorationStr := utilspoddecoration .GetDecorationInfoString (podInfo .UpdatedPodDecorations )
781
- if val , ok := ownedIDs [podInfo .ID ].Get (podcontext .PodDecorationRevisionKey ); ! ok || val != decorationStr {
782
- needUpdateContext = true
783
- ownedIDs [podInfo .ID ].Put (podcontext .PodDecorationRevisionKey , decorationStr )
784
- }
785
- }
786
-
787
- if podInfo .IsUpdatedRevision && ! podInfo .PodDecorationChanged {
788
- continue
789
- }
790
- // if Pod has not been updated, update it.
791
- podCh <- podToUpdate [i ]
722
+ if podopslifecycle .IsDuringOps (collasetutils .UpdateOpsLifecycleAdapter , podInfo ) {
723
+ continue
792
724
}
793
725
794
- // 5. mark Pod to use updated revision before updating it.
795
- if needUpdateContext {
796
- logger .V (1 ).Info ("try to update ResourceContext for CollaSet" )
797
- err = retry .RetryOnConflict (retry .DefaultRetry , func () error {
798
- return podcontext .UpdateToPodContext (r .client , cls , ownedIDs )
799
- })
726
+ podCh <- podToUpdate [i ]
727
+ }
800
728
801
- if err != nil {
802
- collasetutils .AddOrUpdateCondition (resources .NewStatus ,
803
- appsv1alpha1 .CollaSetScale , err , "UpdateFailed" ,
804
- fmt .Sprintf ("fail to update Context for updating: %s" , err ))
805
- return updating , recordedRequeueAfter , err
806
- } else {
807
- collasetutils .AddOrUpdateCondition (resources .NewStatus ,
808
- appsv1alpha1 .CollaSetScale , nil , "UpdateFailed" , "" )
809
- }
810
- }
729
+ // 4. begin pod update lifecycle
730
+ updating , err = updater .BeginUpdatePod (resources , podCh )
731
+ if err != nil {
732
+ return updating , recordedRequeueAfter , err
733
+ }
734
+
735
+ // 5. filter pods not allow to ops now, such as OperationDelaySeconds strategy
736
+ recordedRequeueAfter , err = updater .FilterAllowOpsPods (podToUpdate , ownedIDs , resources , podCh )
737
+ if err != nil {
738
+ collasetutils .AddOrUpdateCondition (resources .NewStatus ,
739
+ appsv1alpha1 .CollaSetScale , err , "UpdateFailed" ,
740
+ fmt .Sprintf ("fail to update Context for updating: %s" , err ))
741
+ return updating , recordedRequeueAfter , err
811
742
} else {
812
- for i , podInfo := range podToUpdate {
813
- // The pod is in a "replaceUpdate" state, always requires further update processing.
814
- if podInfo .IsUpdatedRevision && ! podInfo .PodDecorationChanged && ! podInfo .PvcTmpHashChanged {
815
- continue
816
- }
817
- podCh <- podToUpdate [i ]
818
- }
743
+ collasetutils .AddOrUpdateCondition (resources .NewStatus ,
744
+ appsv1alpha1 .CollaSetScale , nil , "Updated" , "" )
819
745
}
820
746
821
747
// 6. update Pod
822
748
succCount , err := controllerutils .SlowStartBatch (len (podCh ), controllerutils .SlowStartInitialBatchSize , false , func (_ int , _ error ) error {
823
749
podInfo := <- podCh
824
- if ! analysedPod .Has (podInfo .Name ) {
825
- if err = updater .FulfillPodUpdatedInfo (resources .UpdatedRevision , podInfo ); err != nil {
826
- return fmt .Errorf ("fail to analyse pod %s/%s in-place update support: %s" , podInfo .Namespace , podInfo .Name , err )
827
- }
828
- }
829
-
830
750
logger .V (1 ).Info ("before pod update operation" ,
831
751
"pod" , commonutils .ObjectKeyString (podInfo .Pod ),
832
752
"revision.from" , podInfo .CurrentRevision .Name ,
@@ -835,41 +755,8 @@ func (r *RealSyncControl) Update(
835
755
"onlyMetadataChanged" , podInfo .OnlyMetadataChanged ,
836
756
)
837
757
838
- if (podInfo .OnlyMetadataChanged || podInfo .InPlaceUpdateSupport ) && ! podInfo .PvcTmpHashChanged {
839
- // 6.1 if pod template changes only include metadata or support in-place update, just apply these changes to pod directly
840
- if err = r .podControl .UpdatePod (podInfo .UpdatedPod ); err != nil {
841
- return fmt .Errorf ("fail to update Pod %s/%s when updating by in-place: %s" , podInfo .Namespace , podInfo .Name , err )
842
- } else {
843
- podInfo .Pod = podInfo .UpdatedPod
844
- r .recorder .Eventf (podInfo .Pod ,
845
- corev1 .EventTypeNormal ,
846
- "UpdatePod" ,
847
- "succeed to update Pod %s/%s to from revision %s to revision %s by in-place" ,
848
- podInfo .Namespace , podInfo .Name ,
849
- podInfo .CurrentRevision .Name ,
850
- resources .UpdatedRevision .Name )
851
- if err := collasetutils .ActiveExpectations .ExpectUpdate (cls , expectations .Pod , podInfo .Name , podInfo .UpdatedPod .ResourceVersion ); err != nil {
852
- return err
853
- }
854
- }
855
- } else if cls .Spec .UpdateStrategy .PodUpdatePolicy == appsv1alpha1 .CollaSetReplacePodUpdateStrategyType {
856
- return nil
857
- } else {
858
- // 6.2 if pod has changes not in-place supported, recreate it
859
- if err = r .podControl .DeletePod (podInfo .Pod ); err != nil {
860
- return fmt .Errorf ("fail to delete Pod %s/%s when updating by recreate: %s" , podInfo .Namespace , podInfo .Name , err )
861
- } else {
862
- r .recorder .Eventf (podInfo .Pod ,
863
- corev1 .EventTypeNormal ,
864
- "UpdatePod" ,
865
- "succeed to update Pod %s/%s to from revision %s to revision %s by recreate" ,
866
- podInfo .Namespace ,
867
- podInfo .Name ,
868
- podInfo .CurrentRevision .Name , resources .UpdatedRevision .Name )
869
- if err := collasetutils .ActiveExpectations .ExpectDelete (cls , expectations .Pod , podInfo .Name ); err != nil {
870
- return err
871
- }
872
- }
758
+ if err = updater .UpgradePod (podInfo ); err != nil {
759
+ return err
873
760
}
874
761
875
762
return nil
@@ -883,7 +770,7 @@ func (r *RealSyncControl) Update(
883
770
collasetutils .AddOrUpdateCondition (resources .NewStatus , appsv1alpha1 .CollaSetUpdate , nil , "Updated" , "" )
884
771
}
885
772
886
- // try to finish all Pods'PodOpsLifecycle if its update is finished.
773
+ // 7. try to finish all Pods'PodOpsLifecycle if its update is finished.
887
774
succCount , err = controllerutils .SlowStartBatch (len (podUpdateInfos ), controllerutils .SlowStartInitialBatchSize , false , func (i int , _ error ) error {
888
775
podInfo := podUpdateInfos [i ]
889
776
@@ -898,29 +785,9 @@ func (r *RealSyncControl) Update(
898
785
}
899
786
900
787
if finished {
901
- if podInfo .isInReplacing {
902
- replacePairNewPodInfo := podInfo .replacePairNewPodInfo
903
- if replacePairNewPodInfo != nil {
904
- if _ , exist := replacePairNewPodInfo .Labels [appsv1alpha1 .PodDeletionIndicationLabelKey ]; ! exist {
905
- patch := client .RawPatch (types .StrategicMergePatchType , []byte (fmt .Sprintf (`{"metadata":{"labels":{"%s":"%d"}}}` , appsv1alpha1 .PodDeletionIndicationLabelKey , time .Now ().UnixNano ())))
906
- if err = r .podControl .PatchPod (podInfo .Pod , patch ); err != nil {
907
- return fmt .Errorf ("failed to delete replace pair origin pod %s/%s %s" , podInfo .Namespace , podInfo .replacePairNewPodInfo .Name , err )
908
- }
909
- }
910
- }
911
- } else {
912
- logger .V (1 ).Info ("try to finish update PodOpsLifecycle for Pod" , "pod" , commonutils .ObjectKeyString (podInfo .Pod ))
913
- if updated , err := podopslifecycle .Finish (r .client , collasetutils .UpdateOpsLifecycleAdapter , podInfo .Pod ); err != nil {
914
- return fmt .Errorf ("failed to finish PodOpsLifecycle for updating Pod %s/%s: %s" , podInfo .Namespace , podInfo .Name , err )
915
- } else if updated {
916
- // add an expectation for this pod update, before next reconciling
917
- if err := collasetutils .ActiveExpectations .ExpectUpdate (cls , expectations .Pod , podInfo .Name , podInfo .ResourceVersion ); err != nil {
918
- return err
919
- }
920
- r .recorder .Eventf (podInfo .Pod ,
921
- corev1 .EventTypeNormal ,
922
- "UpdateReady" , "pod %s/%s update finished" , podInfo .Namespace , podInfo .Name )
923
- }
788
+ err := updater .FinishUpdatePod (podInfo )
789
+ if err != nil {
790
+ return err
924
791
}
925
792
} else {
926
793
r .recorder .Eventf (podInfo .Pod ,
0 commit comments