mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 11:48:15 +00:00 
			
		
		
		
	Impose length limit when concatenating revision history
This commit is contained in:
		@@ -124,6 +124,10 @@ func (dc *DeploymentController) getAllReplicaSetsAndSyncRevision(d *apps.Deploym
 | 
				
			|||||||
	return newRS, allOldRSs, nil
 | 
						return newRS, allOldRSs, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						maxRevHistoryLengthInChars = 2000
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Returns a replica set that matches the intent of the given deployment. Returns nil if the new replica set doesn't exist yet.
 | 
					// Returns a replica set that matches the intent of the given deployment. Returns nil if the new replica set doesn't exist yet.
 | 
				
			||||||
// 1. Get existing new RS (the RS that the given deployment targets, whose pod template is the same as deployment's).
 | 
					// 1. Get existing new RS (the RS that the given deployment targets, whose pod template is the same as deployment's).
 | 
				
			||||||
// 2. If there's existing new RS, update its revision number if it's smaller than (maxOldRevision + 1), where maxOldRevision is the max revision number among all old RSes.
 | 
					// 2. If there's existing new RS, update its revision number if it's smaller than (maxOldRevision + 1), where maxOldRevision is the max revision number among all old RSes.
 | 
				
			||||||
@@ -145,7 +149,7 @@ func (dc *DeploymentController) getNewReplicaSet(d *apps.Deployment, rsList, old
 | 
				
			|||||||
		rsCopy := existingNewRS.DeepCopy()
 | 
							rsCopy := existingNewRS.DeepCopy()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Set existing new replica set's annotation
 | 
							// Set existing new replica set's annotation
 | 
				
			||||||
		annotationsUpdated := deploymentutil.SetNewReplicaSetAnnotations(d, rsCopy, newRevision, true)
 | 
							annotationsUpdated := deploymentutil.SetNewReplicaSetAnnotations(d, rsCopy, newRevision, true, maxRevHistoryLengthInChars)
 | 
				
			||||||
		minReadySecondsNeedsUpdate := rsCopy.Spec.MinReadySeconds != d.Spec.MinReadySeconds
 | 
							minReadySecondsNeedsUpdate := rsCopy.Spec.MinReadySeconds != d.Spec.MinReadySeconds
 | 
				
			||||||
		if annotationsUpdated || minReadySecondsNeedsUpdate {
 | 
							if annotationsUpdated || minReadySecondsNeedsUpdate {
 | 
				
			||||||
			rsCopy.Spec.MinReadySeconds = d.Spec.MinReadySeconds
 | 
								rsCopy.Spec.MinReadySeconds = d.Spec.MinReadySeconds
 | 
				
			||||||
@@ -209,7 +213,7 @@ func (dc *DeploymentController) getNewReplicaSet(d *apps.Deployment, rsList, old
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	*(newRS.Spec.Replicas) = newReplicasCount
 | 
						*(newRS.Spec.Replicas) = newReplicasCount
 | 
				
			||||||
	// Set new replica set's annotation
 | 
						// Set new replica set's annotation
 | 
				
			||||||
	deploymentutil.SetNewReplicaSetAnnotations(d, &newRS, newRevision, false)
 | 
						deploymentutil.SetNewReplicaSetAnnotations(d, &newRS, newRevision, false, maxRevHistoryLengthInChars)
 | 
				
			||||||
	// Create the new ReplicaSet. If it already exists, then we need to check for possible
 | 
						// Create the new ReplicaSet. If it already exists, then we need to check for possible
 | 
				
			||||||
	// hash collisions. If there is any other error, we need to report it in the status of
 | 
						// hash collisions. If there is any other error, we need to report it in the status of
 | 
				
			||||||
	// the Deployment.
 | 
						// the Deployment.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -227,7 +227,7 @@ func Revision(obj runtime.Object) (int64, error) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// SetNewReplicaSetAnnotations sets new replica set's annotations appropriately by updating its revision and
 | 
					// SetNewReplicaSetAnnotations sets new replica set's annotations appropriately by updating its revision and
 | 
				
			||||||
// copying required deployment annotations to it; it returns true if replica set's annotation is changed.
 | 
					// copying required deployment annotations to it; it returns true if replica set's annotation is changed.
 | 
				
			||||||
func SetNewReplicaSetAnnotations(deployment *apps.Deployment, newRS *apps.ReplicaSet, newRevision string, exists bool) bool {
 | 
					func SetNewReplicaSetAnnotations(deployment *apps.Deployment, newRS *apps.ReplicaSet, newRevision string, exists bool, revHistoryLimitInChars int) bool {
 | 
				
			||||||
	// First, copy deployment's annotations (except for apply and revision annotations)
 | 
						// First, copy deployment's annotations (except for apply and revision annotations)
 | 
				
			||||||
	annotationChanged := copyDeploymentAnnotationsToReplicaSet(deployment, newRS)
 | 
						annotationChanged := copyDeploymentAnnotationsToReplicaSet(deployment, newRS)
 | 
				
			||||||
	// Then, update replica set's revision annotation
 | 
						// Then, update replica set's revision annotation
 | 
				
			||||||
@@ -261,14 +261,25 @@ func SetNewReplicaSetAnnotations(deployment *apps.Deployment, newRS *apps.Replic
 | 
				
			|||||||
	// If a revision annotation already existed and this replica set was updated with a new revision
 | 
						// If a revision annotation already existed and this replica set was updated with a new revision
 | 
				
			||||||
	// then that means we are rolling back to this replica set. We need to preserve the old revisions
 | 
						// then that means we are rolling back to this replica set. We need to preserve the old revisions
 | 
				
			||||||
	// for historical information.
 | 
						// for historical information.
 | 
				
			||||||
	if ok && annotationChanged {
 | 
						if ok && oldRevisionInt < newRevisionInt {
 | 
				
			||||||
		revisionHistoryAnnotation := newRS.Annotations[RevisionHistoryAnnotation]
 | 
							revisionHistoryAnnotation := newRS.Annotations[RevisionHistoryAnnotation]
 | 
				
			||||||
		oldRevisions := strings.Split(revisionHistoryAnnotation, ",")
 | 
							oldRevisions := strings.Split(revisionHistoryAnnotation, ",")
 | 
				
			||||||
		if len(oldRevisions[0]) == 0 {
 | 
							if len(oldRevisions[0]) == 0 {
 | 
				
			||||||
			newRS.Annotations[RevisionHistoryAnnotation] = oldRevision
 | 
								newRS.Annotations[RevisionHistoryAnnotation] = oldRevision
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			oldRevisions = append(oldRevisions, oldRevision)
 | 
								totalLen := len(revisionHistoryAnnotation) + len(oldRevision) + 1
 | 
				
			||||||
 | 
								// index for the starting position in oldRevisions
 | 
				
			||||||
 | 
								start := 0
 | 
				
			||||||
 | 
								for totalLen > revHistoryLimitInChars && start < len(oldRevisions) {
 | 
				
			||||||
 | 
									totalLen = totalLen - len(oldRevisions[start]) - 1
 | 
				
			||||||
 | 
									start++
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if totalLen <= revHistoryLimitInChars {
 | 
				
			||||||
 | 
									oldRevisions = append(oldRevisions[start:], oldRevision)
 | 
				
			||||||
				newRS.Annotations[RevisionHistoryAnnotation] = strings.Join(oldRevisions, ",")
 | 
									newRS.Annotations[RevisionHistoryAnnotation] = strings.Join(oldRevisions, ",")
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									klog.Warningf("Not appending revision due to length limit of %v reached", revHistoryLimitInChars)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// If the new replica set is about to be created, we need to add replica annotations to it.
 | 
						// If the new replica set is about to be created, we need to add replica annotations to it.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1274,13 +1274,19 @@ func TestAnnotationUtils(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	//Test Case 1: Check if anotations are copied properly from deployment to RS
 | 
						//Test Case 1: Check if anotations are copied properly from deployment to RS
 | 
				
			||||||
	t.Run("SetNewReplicaSetAnnotations", func(t *testing.T) {
 | 
						t.Run("SetNewReplicaSetAnnotations", func(t *testing.T) {
 | 
				
			||||||
		//Try to set the increment revision from 1 through 20
 | 
							//Try to set the increment revision from 11 through 20
 | 
				
			||||||
		for i := 0; i < 20; i++ {
 | 
							for i := 10; i < 20; i++ {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			nextRevision := fmt.Sprintf("%d", i+1)
 | 
								nextRevision := fmt.Sprintf("%d", i+1)
 | 
				
			||||||
			SetNewReplicaSetAnnotations(&tDeployment, &tRS, nextRevision, true)
 | 
								SetNewReplicaSetAnnotations(&tDeployment, &tRS, nextRevision, true, 5)
 | 
				
			||||||
			//Now the ReplicaSets Revision Annotation should be i+1
 | 
								//Now the ReplicaSets Revision Annotation should be i+1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if i >= 12 {
 | 
				
			||||||
 | 
									expectedHistoryAnnotation := fmt.Sprintf("%d,%d", i-1, i)
 | 
				
			||||||
 | 
									if tRS.Annotations[RevisionHistoryAnnotation] != expectedHistoryAnnotation {
 | 
				
			||||||
 | 
										t.Errorf("Revision History Expected=%s Obtained=%s", expectedHistoryAnnotation, tRS.Annotations[RevisionHistoryAnnotation])
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			if tRS.Annotations[RevisionAnnotation] != nextRevision {
 | 
								if tRS.Annotations[RevisionAnnotation] != nextRevision {
 | 
				
			||||||
				t.Errorf("Revision Expected=%s Obtained=%s", nextRevision, tRS.Annotations[RevisionAnnotation])
 | 
									t.Errorf("Revision Expected=%s Obtained=%s", nextRevision, tRS.Annotations[RevisionAnnotation])
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user