@@ -162,7 +162,8 @@ func (c *Reconciler) ReconcileKind(ctx context.Context, service *servingv1.Servi
162
162
}
163
163
164
164
// After the RolloutOrchestrator is created or updated, call the base reconciliation loop of the service.
165
- err = c .baseReconciler .ReconcileKind (ctx , TransformService (service , rolloutOrchestrator , c .rolloutConfig ))
165
+ err = c .baseReconciler .ReconcileKind (ctx , TransformService (service , rolloutOrchestrator , c .rolloutConfig , c .spaLister .StagePodAutoscalers (service .Namespace ),
166
+ c .routeLister .Routes (service .Namespace )))
166
167
if err != nil {
167
168
return err
168
169
}
@@ -909,19 +910,76 @@ func calculateStageTargetRevisions(replicasMap map[string]int32, startRevisions
909
910
return stageRevisionTarget
910
911
}
911
912
912
- func TransformService (service * servingv1.Service , ro * v1.RolloutOrchestrator , rc * RolloutConfig ) * servingv1.Service {
913
+ func TransformService (service * servingv1.Service , ro * v1.RolloutOrchestrator , rc * RolloutConfig ,
914
+ spaLister listers.StagePodAutoscalerNamespaceLister , routeLister servinglisters.RouteNamespaceLister ) * servingv1.Service {
913
915
// If Knative Service defines more than one traffic, this feature tentatively does not cover this case.
914
916
if len (service .Spec .Traffic ) > 1 {
915
917
return service
916
918
}
917
919
service .Spec .RouteSpec = servingv1.RouteSpec {
918
- Traffic : convertIntoTrafficTarget (service .GetName (), ro , rc ),
920
+ Traffic : convertIntoTrafficTarget (service .GetName (), ro , rc , spaLister , routeLister ),
919
921
}
920
922
return service
921
923
}
922
924
923
- func convertIntoTrafficTarget (name string , ro * v1.RolloutOrchestrator , rc * RolloutConfig ) []servingv1.TrafficTarget {
925
+ func convertIntoTrafficTarget (name string , ro * v1.RolloutOrchestrator , rc * RolloutConfig ,
926
+ spaLister listers.StagePodAutoscalerNamespaceLister , routeLister servinglisters.RouteNamespaceLister ) []servingv1.TrafficTarget {
924
927
revisionTarget := ro .Spec .StageTargetRevisions
928
+ finalTargetRevs := ro .Spec .TargetRevisions
929
+ targetRevName := finalTargetRevs [0 ].RevisionName
930
+ if ! ro .IsNotConvertToOneUpgrade () && rc .ProgressiveRolloutEnabled {
931
+ // The revisionTarget is set directly to ro.Spec.StageTargetRevisions, because this is not a
932
+ // one-to-one revision upgrade or the rollout feature is disabled. We do not cover this use case
933
+ // in the implementation. The traffic target is set directly configured in ro.Spec.StageTargetRevisions.
934
+ // However, if this is one-to-one or many-to-one rollout, we need to make sure the minimum number of
935
+ // replicas are met before shifting the traffic percentage over.
936
+ // Find out the name of the revision scaling up. Get the name of the spa for the revision scaling up.
937
+ // The name is the same as the revision name.
938
+ spaTargetRevName := targetRevName
939
+ targetNumberReplicas , minScale := finalTargetRevs [0 ].MinScale , finalTargetRevs [0 ].MinScale
940
+
941
+ // Find the target number of replicas for the current stage.
942
+ for _ , revision := range ro .Spec .StageTargetRevisions {
943
+ if revision .RevisionName == spaTargetRevName && revision .TargetReplicas != nil {
944
+ targetNumberReplicas = revision .TargetReplicas
945
+ }
946
+ }
947
+ spa , err := spaLister .Get (spaTargetRevName )
948
+ // Check the number of replicas has reached the target number of replicas for the revision scaling up
949
+ if err == nil && targetNumberReplicas != nil && spa .Status .ActualScale != nil && minScale != nil &&
950
+ * spa .Status .ActualScale < * minScale && * spa .Status .ActualScale < * targetNumberReplicas {
951
+ // If we have issues getting the spa, or the number of the replicas has reached the target number of
952
+ // the revision to scale up, we set the revisionTarget to ro.Spec.StageTargetRevisions.
953
+
954
+ // However, if there is no issue getting yhe spa, and the actual number of replicas is less than
955
+ // the target number of replicas, we need to use ro.Status.StageRevisionStatus or route.Status.Traffic
956
+ // as the traffic information for the route.
957
+ if len (ro .Status .StageRevisionStatus ) > 0 {
958
+ // If the ro has the StageRevisionStatus in the status, use it.
959
+ revisionTarget = ro .Status .StageRevisionStatus
960
+ for index := range revisionTarget {
961
+ if revisionTarget [index ].RevisionName == spaTargetRevName {
962
+ continue
963
+ }
964
+ revisionTarget [index ].LatestRevision = ptr .Bool (false )
965
+ }
966
+ } else {
967
+ // If the ro does not have the StageRevisionStatus in the status, use the existing one in route.
968
+ route , errRoute := routeLister .Get (ro .Name )
969
+ if errRoute == nil && len (route .Status .Traffic ) > 0 {
970
+ traffics := route .Status .Traffic
971
+ for index := range traffics {
972
+ if traffics [index ].RevisionName == spaTargetRevName {
973
+ continue
974
+ }
975
+ traffics [index ].LatestRevision = ptr .Bool (false )
976
+ }
977
+ return traffics
978
+ }
979
+ }
980
+ }
981
+ }
982
+
925
983
trafficTarget := make ([]servingv1.TrafficTarget , 0 , len (revisionTarget ))
926
984
for _ , revision := range revisionTarget {
927
985
target := servingv1.TrafficTarget {}
@@ -948,6 +1006,8 @@ func convertIntoTrafficTarget(name string, ro *v1.RolloutOrchestrator, rc *Rollo
948
1006
}
949
1007
950
1008
if revision .LatestRevision != nil && * revision .LatestRevision {
1009
+ // No matter the RevisionName is available for the latest revision or not, we cannot
1010
+ // set the RevisionName here. Only ConfigurationName is allowed.
951
1011
if strings .TrimSpace (revision .ConfigurationName ) != "" {
952
1012
target .ConfigurationName = revision .ConfigurationName
953
1013
} else {
0 commit comments