// 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. func SetNewReplicaSetAnnotations(deployment *extensions.Deployment, newRS *extensions.ReplicaSet, newRevision string, exists bool) bool { // First, copy deployment's annotations (except for apply and revision annotations) annotationChanged := copyDeploymentAnnotationsToReplicaSet(deployment, newRS) // Then, update replica set's revision annotation if newRS.Annotations == nil { newRS.Annotations = make(map[string]string) } oldRevision, ok := newRS.Annotations[RevisionAnnotation] // The newRS's revision should be the greatest among all RSes. Usually, its revision number is newRevision (the max revision number // of all old RSes + 1). However, it's possible that some of the old RSes are deleted after the newRS revision being updated, and // newRevision becomes smaller than newRS's revision. We should only update newRS revision when it's smaller than newRevision. if oldRevision < newRevision { newRS.Annotations[RevisionAnnotation] = newRevision annotationChanged = true glog.V(4).Infof("Updating replica set %q revision to %s", newRS.Name, newRevision) } // 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 // for historical information. if ok && annotationChanged { revisionHistoryAnnotation := newRS.Annotations[RevisionHistoryAnnotation] oldRevisions := strings.Split(revisionHistoryAnnotation, ",") if len(oldRevisions[0]) == 0 { newRS.Annotations[RevisionHistoryAnnotation] = oldRevision } else { oldRevisions = append(oldRevisions, oldRevision) newRS.Annotations[RevisionHistoryAnnotation] = strings.Join(oldRevisions, ",") } } // If the new replica set is about to be created, we need to add replica annotations to it. if !exists && SetReplicasAnnotations(newRS, *(deployment.Spec.Replicas), *(deployment.Spec.Replicas)+MaxSurge(*deployment)) { annotationChanged = true } return annotationChanged }
// SetReplicasAnnotations sets the desiredReplicas and maxReplicas into the annotations func SetReplicasAnnotations(rs *extensions.ReplicaSet, desiredReplicas, maxReplicas int32) bool { updated := false if rs.Annotations == nil { rs.Annotations = make(map[string]string) } desiredString := fmt.Sprintf("%d", desiredReplicas) if hasString := rs.Annotations[DesiredReplicasAnnotation]; hasString != desiredString { rs.Annotations[DesiredReplicasAnnotation] = desiredString updated = true } maxString := fmt.Sprintf("%d", maxReplicas) if hasString := rs.Annotations[MaxReplicasAnnotation]; hasString != maxString { rs.Annotations[MaxReplicasAnnotation] = maxString updated = true } return updated }
// copyDeploymentAnnotationsToReplicaSet copies deployment's annotations to replica set's annotations, // and returns true if replica set's annotation is changed. // Note that apply and revision annotations are not copied. func copyDeploymentAnnotationsToReplicaSet(deployment *extensions.Deployment, rs *extensions.ReplicaSet) bool { rsAnnotationsChanged := false if rs.Annotations == nil { rs.Annotations = make(map[string]string) } for k, v := range deployment.Annotations { // newRS revision is updated automatically in getNewReplicaSet, and the deployment's revision number is then updated // by copying its newRS revision number. We should not copy deployment's revision to its newRS, since the update of // deployment revision number may fail (revision becomes stale) and the revision number in newRS is more reliable. if skipCopyAnnotation(k) || rs.Annotations[k] == v { continue } rs.Annotations[k] = v rsAnnotationsChanged = true } return rsAnnotationsChanged }