vendor update for CSI 0.3.0

This commit is contained in:
gman
2018-07-18 16:47:22 +02:00
parent 6f484f92fc
commit 8ea659f0d5
6810 changed files with 438061 additions and 193861 deletions

View File

@ -19,8 +19,8 @@ go_library(
"//pkg/controller:go_default_library",
"//pkg/util/labels:go_default_library",
"//vendor/github.com/golang/glog:go_default_library",
"//vendor/k8s.io/api/apps/v1:go_default_library",
"//vendor/k8s.io/api/core/v1:go_default_library",
"//vendor/k8s.io/api/extensions/v1beta1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
@ -29,11 +29,10 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
"//vendor/k8s.io/client-go/kubernetes/typed/apps/v1:go_default_library",
"//vendor/k8s.io/client-go/kubernetes/typed/core/v1:go_default_library",
"//vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1:go_default_library",
"//vendor/k8s.io/client-go/listers/apps/v1:go_default_library",
"//vendor/k8s.io/client-go/listers/core/v1:go_default_library",
"//vendor/k8s.io/client-go/listers/extensions/v1beta1:go_default_library",
"//vendor/k8s.io/client-go/util/integer:go_default_library",
"//vendor/k8s.io/client-go/util/retry:go_default_library",
],
@ -49,8 +48,8 @@ go_test(
deps = [
"//pkg/controller:go_default_library",
"//pkg/util/hash:go_default_library",
"//vendor/k8s.io/api/apps/v1:go_default_library",
"//vendor/k8s.io/api/core/v1:go_default_library",
"//vendor/k8s.io/api/extensions/v1beta1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",

View File

@ -25,20 +25,16 @@ import (
"github.com/golang/glog"
apps "k8s.io/api/apps/v1"
"k8s.io/api/core/v1"
extensions "k8s.io/api/extensions/v1beta1"
apiequality "k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/errors"
intstrutil "k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/apimachinery/pkg/util/wait"
clientset "k8s.io/client-go/kubernetes"
extensionsv1beta1 "k8s.io/client-go/kubernetes/typed/extensions/v1beta1"
corelisters "k8s.io/client-go/listers/core/v1"
extensionslisters "k8s.io/client-go/listers/extensions/v1beta1"
appsclient "k8s.io/client-go/kubernetes/typed/apps/v1"
"k8s.io/client-go/util/integer"
internalextensions "k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/controller"
@ -102,8 +98,8 @@ const (
)
// NewDeploymentCondition creates a new deployment condition.
func NewDeploymentCondition(condType extensions.DeploymentConditionType, status v1.ConditionStatus, reason, message string) *extensions.DeploymentCondition {
return &extensions.DeploymentCondition{
func NewDeploymentCondition(condType apps.DeploymentConditionType, status v1.ConditionStatus, reason, message string) *apps.DeploymentCondition {
return &apps.DeploymentCondition{
Type: condType,
Status: status,
LastUpdateTime: metav1.Now(),
@ -114,7 +110,7 @@ func NewDeploymentCondition(condType extensions.DeploymentConditionType, status
}
// GetDeploymentCondition returns the condition with the provided type.
func GetDeploymentCondition(status extensions.DeploymentStatus, condType extensions.DeploymentConditionType) *extensions.DeploymentCondition {
func GetDeploymentCondition(status apps.DeploymentStatus, condType apps.DeploymentConditionType) *apps.DeploymentCondition {
for i := range status.Conditions {
c := status.Conditions[i]
if c.Type == condType {
@ -126,7 +122,7 @@ func GetDeploymentCondition(status extensions.DeploymentStatus, condType extensi
// SetDeploymentCondition updates the deployment to include the provided condition. If the condition that
// we are about to add already exists and has the same status and reason then we are not going to update.
func SetDeploymentCondition(status *extensions.DeploymentStatus, condition extensions.DeploymentCondition) {
func SetDeploymentCondition(status *apps.DeploymentStatus, condition apps.DeploymentCondition) {
currentCond := GetDeploymentCondition(*status, condition.Type)
if currentCond != nil && currentCond.Status == condition.Status && currentCond.Reason == condition.Reason {
return
@ -140,13 +136,13 @@ func SetDeploymentCondition(status *extensions.DeploymentStatus, condition exten
}
// RemoveDeploymentCondition removes the deployment condition with the provided type.
func RemoveDeploymentCondition(status *extensions.DeploymentStatus, condType extensions.DeploymentConditionType) {
func RemoveDeploymentCondition(status *apps.DeploymentStatus, condType apps.DeploymentConditionType) {
status.Conditions = filterOutCondition(status.Conditions, condType)
}
// filterOutCondition returns a new slice of deployment conditions without conditions with the provided type.
func filterOutCondition(conditions []extensions.DeploymentCondition, condType extensions.DeploymentConditionType) []extensions.DeploymentCondition {
var newConditions []extensions.DeploymentCondition
func filterOutCondition(conditions []apps.DeploymentCondition, condType apps.DeploymentConditionType) []apps.DeploymentCondition {
var newConditions []apps.DeploymentCondition
for _, c := range conditions {
if c.Type == condType {
continue
@ -158,9 +154,9 @@ func filterOutCondition(conditions []extensions.DeploymentCondition, condType ex
// ReplicaSetToDeploymentCondition converts a replica set condition into a deployment condition.
// Useful for promoting replica set failure conditions into deployments.
func ReplicaSetToDeploymentCondition(cond extensions.ReplicaSetCondition) extensions.DeploymentCondition {
return extensions.DeploymentCondition{
Type: extensions.DeploymentConditionType(cond.Type),
func ReplicaSetToDeploymentCondition(cond apps.ReplicaSetCondition) apps.DeploymentCondition {
return apps.DeploymentCondition{
Type: apps.DeploymentConditionType(cond.Type),
Status: cond.Status,
LastTransitionTime: cond.LastTransitionTime,
LastUpdateTime: cond.LastTransitionTime,
@ -170,7 +166,7 @@ func ReplicaSetToDeploymentCondition(cond extensions.ReplicaSetCondition) extens
}
// SetDeploymentRevision updates the revision for a deployment.
func SetDeploymentRevision(deployment *extensions.Deployment, revision string) bool {
func SetDeploymentRevision(deployment *apps.Deployment, revision string) bool {
updated := false
if deployment.Annotations == nil {
@ -185,7 +181,7 @@ func SetDeploymentRevision(deployment *extensions.Deployment, revision string) b
}
// MaxRevision finds the highest revision in the replica sets
func MaxRevision(allRSs []*extensions.ReplicaSet) int64 {
func MaxRevision(allRSs []*apps.ReplicaSet) int64 {
max := int64(0)
for _, rs := range allRSs {
if v, err := Revision(rs); err != nil {
@ -199,7 +195,7 @@ func MaxRevision(allRSs []*extensions.ReplicaSet) int64 {
}
// LastRevision finds the second max revision number in all replica sets (the last revision)
func LastRevision(allRSs []*extensions.ReplicaSet) int64 {
func LastRevision(allRSs []*apps.ReplicaSet) int64 {
max, secMax := int64(0), int64(0)
for _, rs := range allRSs {
if v, err := Revision(rs); err != nil {
@ -230,7 +226,7 @@ func Revision(obj runtime.Object) (int64, error) {
// 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 {
func SetNewReplicaSetAnnotations(deployment *apps.Deployment, newRS *apps.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
@ -287,6 +283,7 @@ var annotationsToSkip = map[string]bool{
RevisionHistoryAnnotation: true,
DesiredReplicasAnnotation: true,
MaxReplicasAnnotation: true,
apps.DeprecatedRollbackTo: true,
}
// skipCopyAnnotation returns true if we should skip copying the annotation with the given annotation key
@ -299,7 +296,7 @@ func skipCopyAnnotation(key string) bool {
// 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 {
func copyDeploymentAnnotationsToReplicaSet(deployment *apps.Deployment, rs *apps.ReplicaSet) bool {
rsAnnotationsChanged := false
if rs.Annotations == nil {
rs.Annotations = make(map[string]string)
@ -320,7 +317,7 @@ func copyDeploymentAnnotationsToReplicaSet(deployment *extensions.Deployment, rs
// SetDeploymentAnnotationsTo sets deployment's annotations as given RS's annotations.
// This action should be done if and only if the deployment is rolling back to this rs.
// Note that apply and revision annotations are not changed.
func SetDeploymentAnnotationsTo(deployment *extensions.Deployment, rollbackToRS *extensions.ReplicaSet) {
func SetDeploymentAnnotationsTo(deployment *apps.Deployment, rollbackToRS *apps.ReplicaSet) {
deployment.Annotations = getSkippedAnnotations(deployment.Annotations)
for k, v := range rollbackToRS.Annotations {
if !skipCopyAnnotation(k) {
@ -341,7 +338,7 @@ func getSkippedAnnotations(annotations map[string]string) map[string]string {
// FindActiveOrLatest returns the only active or the latest replica set in case there is at most one active
// replica set. If there are more active replica sets, then we should proportionally scale them.
func FindActiveOrLatest(newRS *extensions.ReplicaSet, oldRSs []*extensions.ReplicaSet) *extensions.ReplicaSet {
func FindActiveOrLatest(newRS *apps.ReplicaSet, oldRSs []*apps.ReplicaSet) *apps.ReplicaSet {
if newRS == nil && len(oldRSs) == 0 {
return nil
}
@ -364,15 +361,15 @@ func FindActiveOrLatest(newRS *extensions.ReplicaSet, oldRSs []*extensions.Repli
}
// GetDesiredReplicasAnnotation returns the number of desired replicas
func GetDesiredReplicasAnnotation(rs *extensions.ReplicaSet) (int32, bool) {
func GetDesiredReplicasAnnotation(rs *apps.ReplicaSet) (int32, bool) {
return getIntFromAnnotation(rs, DesiredReplicasAnnotation)
}
func getMaxReplicasAnnotation(rs *extensions.ReplicaSet) (int32, bool) {
func getMaxReplicasAnnotation(rs *apps.ReplicaSet) (int32, bool) {
return getIntFromAnnotation(rs, MaxReplicasAnnotation)
}
func getIntFromAnnotation(rs *extensions.ReplicaSet, annotationKey string) (int32, bool) {
func getIntFromAnnotation(rs *apps.ReplicaSet, annotationKey string) (int32, bool) {
annotationValue, ok := rs.Annotations[annotationKey]
if !ok {
return int32(0), false
@ -386,7 +383,7 @@ func getIntFromAnnotation(rs *extensions.ReplicaSet, annotationKey string) (int3
}
// SetReplicasAnnotations sets the desiredReplicas and maxReplicas into the annotations
func SetReplicasAnnotations(rs *extensions.ReplicaSet, desiredReplicas, maxReplicas int32) bool {
func SetReplicasAnnotations(rs *apps.ReplicaSet, desiredReplicas, maxReplicas int32) bool {
updated := false
if rs.Annotations == nil {
rs.Annotations = make(map[string]string)
@ -404,8 +401,24 @@ func SetReplicasAnnotations(rs *extensions.ReplicaSet, desiredReplicas, maxRepli
return updated
}
// AnnotationsNeedUpdate return true if ReplicasAnnotations need to be updated
func ReplicasAnnotationsNeedUpdate(rs *apps.ReplicaSet, desiredReplicas, maxReplicas int32) bool {
if rs.Annotations == nil {
return true
}
desiredString := fmt.Sprintf("%d", desiredReplicas)
if hasString := rs.Annotations[DesiredReplicasAnnotation]; hasString != desiredString {
return true
}
maxString := fmt.Sprintf("%d", maxReplicas)
if hasString := rs.Annotations[MaxReplicasAnnotation]; hasString != maxString {
return true
}
return false
}
// MaxUnavailable returns the maximum unavailable pods a rolling deployment can take.
func MaxUnavailable(deployment extensions.Deployment) int32 {
func MaxUnavailable(deployment apps.Deployment) int32 {
if !IsRollingUpdate(&deployment) || *(deployment.Spec.Replicas) == 0 {
return int32(0)
}
@ -418,7 +431,7 @@ func MaxUnavailable(deployment extensions.Deployment) int32 {
}
// MinAvailable returns the minimum available pods of a given deployment
func MinAvailable(deployment *extensions.Deployment) int32 {
func MinAvailable(deployment *apps.Deployment) int32 {
if !IsRollingUpdate(deployment) {
return int32(0)
}
@ -426,7 +439,7 @@ func MinAvailable(deployment *extensions.Deployment) int32 {
}
// MaxSurge returns the maximum surge pods a rolling deployment can take.
func MaxSurge(deployment extensions.Deployment) int32 {
func MaxSurge(deployment apps.Deployment) int32 {
if !IsRollingUpdate(&deployment) {
return int32(0)
}
@ -438,7 +451,7 @@ func MaxSurge(deployment extensions.Deployment) int32 {
// GetProportion will estimate the proportion for the provided replica set using 1. the current size
// of the parent deployment, 2. the replica count that needs be added on the replica sets of the
// deployment, and 3. the total replicas added in the replica sets of the deployment so far.
func GetProportion(rs *extensions.ReplicaSet, d extensions.Deployment, deploymentReplicasToAdd, deploymentReplicasAdded int32) int32 {
func GetProportion(rs *apps.ReplicaSet, d apps.Deployment, deploymentReplicasToAdd, deploymentReplicasAdded int32) int32 {
if rs == nil || *(rs.Spec.Replicas) == 0 || deploymentReplicasToAdd == 0 || deploymentReplicasToAdd == deploymentReplicasAdded {
return int32(0)
}
@ -460,7 +473,7 @@ func GetProportion(rs *extensions.ReplicaSet, d extensions.Deployment, deploymen
// getReplicaSetFraction estimates the fraction of replicas a replica set can have in
// 1. a scaling event during a rollout or 2. when scaling a paused deployment.
func getReplicaSetFraction(rs extensions.ReplicaSet, d extensions.Deployment) int32 {
func getReplicaSetFraction(rs apps.ReplicaSet, d apps.Deployment) int32 {
// If we are scaling down to zero then the fraction of this replica set is its whole size (negative)
if *(d.Spec.Replicas) == int32(0) {
return -*(rs.Spec.Replicas)
@ -485,7 +498,7 @@ func getReplicaSetFraction(rs extensions.ReplicaSet, d extensions.Deployment) in
// GetAllReplicaSets returns the old and new replica sets targeted by the given Deployment. It gets PodList and ReplicaSetList from client interface.
// Note that the first set of old replica sets doesn't include the ones with no pods, and the second set of old replica sets include all old replica sets.
// The third returned value is the new replica set, and it may be nil if it doesn't exist yet.
func GetAllReplicaSets(deployment *extensions.Deployment, c extensionsv1beta1.ExtensionsV1beta1Interface) ([]*extensions.ReplicaSet, []*extensions.ReplicaSet, *extensions.ReplicaSet, error) {
func GetAllReplicaSets(deployment *apps.Deployment, c appsclient.AppsV1Interface) ([]*apps.ReplicaSet, []*apps.ReplicaSet, *apps.ReplicaSet, error) {
rsList, err := ListReplicaSets(deployment, RsListFromClient(c))
if err != nil {
return nil, nil, nil, err
@ -497,7 +510,7 @@ func GetAllReplicaSets(deployment *extensions.Deployment, c extensionsv1beta1.Ex
// GetOldReplicaSets returns the old replica sets targeted by the given Deployment; get PodList and ReplicaSetList from client interface.
// Note that the first set of old replica sets doesn't include the ones with no pods, and the second set of old replica sets include all old replica sets.
func GetOldReplicaSets(deployment *extensions.Deployment, c extensionsv1beta1.ExtensionsV1beta1Interface) ([]*extensions.ReplicaSet, []*extensions.ReplicaSet, error) {
func GetOldReplicaSets(deployment *apps.Deployment, c appsclient.AppsV1Interface) ([]*apps.ReplicaSet, []*apps.ReplicaSet, error) {
rsList, err := ListReplicaSets(deployment, RsListFromClient(c))
if err != nil {
return nil, nil, err
@ -508,7 +521,7 @@ func GetOldReplicaSets(deployment *extensions.Deployment, c extensionsv1beta1.Ex
// GetNewReplicaSet returns a replica set that matches the intent of the given deployment; get ReplicaSetList from client interface.
// Returns nil if the new replica set doesn't exist yet.
func GetNewReplicaSet(deployment *extensions.Deployment, c extensionsv1beta1.ExtensionsV1beta1Interface) (*extensions.ReplicaSet, error) {
func GetNewReplicaSet(deployment *apps.Deployment, c appsclient.AppsV1Interface) (*apps.ReplicaSet, error) {
rsList, err := ListReplicaSets(deployment, RsListFromClient(c))
if err != nil {
return nil, err
@ -517,13 +530,13 @@ func GetNewReplicaSet(deployment *extensions.Deployment, c extensionsv1beta1.Ext
}
// RsListFromClient returns an rsListFunc that wraps the given client.
func RsListFromClient(c extensionsv1beta1.ExtensionsV1beta1Interface) RsListFunc {
return func(namespace string, options metav1.ListOptions) ([]*extensions.ReplicaSet, error) {
func RsListFromClient(c appsclient.AppsV1Interface) RsListFunc {
return func(namespace string, options metav1.ListOptions) ([]*apps.ReplicaSet, error) {
rsList, err := c.ReplicaSets(namespace).List(options)
if err != nil {
return nil, err
}
var ret []*extensions.ReplicaSet
var ret []*apps.ReplicaSet
for i := range rsList.Items {
ret = append(ret, &rsList.Items[i])
}
@ -532,14 +545,14 @@ func RsListFromClient(c extensionsv1beta1.ExtensionsV1beta1Interface) RsListFunc
}
// TODO: switch this to full namespacers
type RsListFunc func(string, metav1.ListOptions) ([]*extensions.ReplicaSet, error)
type RsListFunc func(string, metav1.ListOptions) ([]*apps.ReplicaSet, error)
type podListFunc func(string, metav1.ListOptions) (*v1.PodList, error)
// ListReplicaSets returns a slice of RSes the given deployment targets.
// Note that this does NOT attempt to reconcile ControllerRef (adopt/orphan),
// because only the controller itself should do that.
// However, it does filter out anything whose ControllerRef doesn't match.
func ListReplicaSets(deployment *extensions.Deployment, getRSList RsListFunc) ([]*extensions.ReplicaSet, error) {
func ListReplicaSets(deployment *apps.Deployment, getRSList RsListFunc) ([]*apps.ReplicaSet, error) {
// TODO: Right now we list replica sets by their labels. We should list them by selector, i.e. the replica set's selector
// should be a superset of the deployment's selector, see https://github.com/kubernetes/kubernetes/issues/19830.
namespace := deployment.Namespace
@ -553,7 +566,7 @@ func ListReplicaSets(deployment *extensions.Deployment, getRSList RsListFunc) ([
return nil, err
}
// Only include those whose ControllerRef matches the Deployment.
owned := make([]*extensions.ReplicaSet, 0, len(all))
owned := make([]*apps.ReplicaSet, 0, len(all))
for _, rs := range all {
if metav1.IsControlledBy(rs, deployment) {
owned = append(owned, rs)
@ -591,7 +604,7 @@ func ListReplicaSetsInternal(deployment *internalextensions.Deployment, getRSLis
// Note that this does NOT attempt to reconcile ControllerRef (adopt/orphan),
// because only the controller itself should do that.
// However, it does filter out anything whose ControllerRef doesn't match.
func ListPods(deployment *extensions.Deployment, rsList []*extensions.ReplicaSet, getPodList podListFunc) (*v1.PodList, error) {
func ListPods(deployment *apps.Deployment, rsList []*apps.ReplicaSet, getPodList podListFunc) (*v1.PodList, error) {
namespace := deployment.Namespace
selector, err := metav1.LabelSelectorAsSelector(deployment.Spec.Selector)
if err != nil {
@ -620,30 +633,21 @@ func ListPods(deployment *extensions.Deployment, rsList []*extensions.ReplicaSet
}
// EqualIgnoreHash returns true if two given podTemplateSpec are equal, ignoring the diff in value of Labels[pod-template-hash]
// We ignore pod-template-hash because the hash result would be different upon podTemplateSpec API changes
// (e.g. the addition of a new field will cause the hash code to change)
// Note that we assume input podTemplateSpecs contain non-empty labels
// We ignore pod-template-hash because:
// 1. The hash result would be different upon podTemplateSpec API changes
// (e.g. the addition of a new field will cause the hash code to change)
// 2. The deployment template won't have hash labels
func EqualIgnoreHash(template1, template2 *v1.PodTemplateSpec) bool {
t1Copy := template1.DeepCopy()
t2Copy := template2.DeepCopy()
// First, compare template.Labels (ignoring hash)
labels1, labels2 := t1Copy.Labels, t2Copy.Labels
if len(labels1) > len(labels2) {
labels1, labels2 = labels2, labels1
}
// We make sure len(labels2) >= len(labels1)
for k, v := range labels2 {
if labels1[k] != v && k != extensions.DefaultDeploymentUniqueLabelKey {
return false
}
}
// Then, compare the templates without comparing their labels
t1Copy.Labels, t2Copy.Labels = nil, nil
// Remove hash labels from template.Labels before comparing
delete(t1Copy.Labels, apps.DefaultDeploymentUniqueLabelKey)
delete(t2Copy.Labels, apps.DefaultDeploymentUniqueLabelKey)
return apiequality.Semantic.DeepEqual(t1Copy, t2Copy)
}
// FindNewReplicaSet returns the new RS this given deployment targets (the one with the same pod template).
func FindNewReplicaSet(deployment *extensions.Deployment, rsList []*extensions.ReplicaSet) *extensions.ReplicaSet {
func FindNewReplicaSet(deployment *apps.Deployment, rsList []*apps.ReplicaSet) *apps.ReplicaSet {
sort.Sort(controller.ReplicaSetsByCreationTimestamp(rsList))
for i := range rsList {
if EqualIgnoreHash(&rsList[i].Spec.Template, &deployment.Spec.Template) {
@ -660,9 +664,9 @@ func FindNewReplicaSet(deployment *extensions.Deployment, rsList []*extensions.R
// FindOldReplicaSets returns the old replica sets targeted by the given Deployment, with the given slice of RSes.
// Note that the first set of old replica sets doesn't include the ones with no pods, and the second set of old replica sets include all old replica sets.
func FindOldReplicaSets(deployment *extensions.Deployment, rsList []*extensions.ReplicaSet) ([]*extensions.ReplicaSet, []*extensions.ReplicaSet) {
var requiredRSs []*extensions.ReplicaSet
var allRSs []*extensions.ReplicaSet
func FindOldReplicaSets(deployment *apps.Deployment, rsList []*apps.ReplicaSet) ([]*apps.ReplicaSet, []*apps.ReplicaSet) {
var requiredRSs []*apps.ReplicaSet
var allRSs []*apps.ReplicaSet
newRS := FindNewReplicaSet(deployment, rsList)
for _, rs := range rsList {
// Filter out new replica set
@ -677,68 +681,18 @@ func FindOldReplicaSets(deployment *extensions.Deployment, rsList []*extensions.
return requiredRSs, allRSs
}
// WaitForReplicaSetUpdated polls the replica set until it is updated.
func WaitForReplicaSetUpdated(c extensionslisters.ReplicaSetLister, desiredGeneration int64, namespace, name string) error {
return wait.PollImmediate(1*time.Second, 1*time.Minute, func() (bool, error) {
rs, err := c.ReplicaSets(namespace).Get(name)
if err != nil {
return false, err
}
return rs.Status.ObservedGeneration >= desiredGeneration, nil
})
}
// WaitForPodsHashPopulated polls the replica set until updated and fully labeled.
func WaitForPodsHashPopulated(c extensionslisters.ReplicaSetLister, desiredGeneration int64, namespace, name string) error {
return wait.PollImmediate(1*time.Second, 1*time.Minute, func() (bool, error) {
rs, err := c.ReplicaSets(namespace).Get(name)
if err != nil {
return false, err
}
return rs.Status.ObservedGeneration >= desiredGeneration &&
rs.Status.FullyLabeledReplicas == *(rs.Spec.Replicas), nil
})
}
// LabelPodsWithHash labels all pods in the given podList with the new hash label.
func LabelPodsWithHash(podList *v1.PodList, c clientset.Interface, podLister corelisters.PodLister, namespace, name, hash string) error {
for _, pod := range podList.Items {
// Ignore inactive Pods.
if !controller.IsPodActive(&pod) {
continue
}
// Only label the pod that doesn't already have the new hash
if pod.Labels[extensions.DefaultDeploymentUniqueLabelKey] != hash {
_, err := UpdatePodWithRetries(c.CoreV1().Pods(namespace), podLister, pod.Namespace, pod.Name,
func(podToUpdate *v1.Pod) error {
// Precondition: the pod doesn't contain the new hash in its label.
if podToUpdate.Labels[extensions.DefaultDeploymentUniqueLabelKey] == hash {
return errors.ErrPreconditionViolated
}
podToUpdate.Labels = labelsutil.AddLabel(podToUpdate.Labels, extensions.DefaultDeploymentUniqueLabelKey, hash)
return nil
})
if err != nil {
return fmt.Errorf("error in adding template hash label %s to pod %q: %v", hash, pod.Name, err)
}
glog.V(4).Infof("Labeled pod %s/%s of ReplicaSet %s/%s with hash %s.", pod.Namespace, pod.Name, namespace, name, hash)
}
}
return nil
}
// SetFromReplicaSetTemplate sets the desired PodTemplateSpec from a replica set template to the given deployment.
func SetFromReplicaSetTemplate(deployment *extensions.Deployment, template v1.PodTemplateSpec) *extensions.Deployment {
func SetFromReplicaSetTemplate(deployment *apps.Deployment, template v1.PodTemplateSpec) *apps.Deployment {
deployment.Spec.Template.ObjectMeta = template.ObjectMeta
deployment.Spec.Template.Spec = template.Spec
deployment.Spec.Template.ObjectMeta.Labels = labelsutil.CloneAndRemoveLabel(
deployment.Spec.Template.ObjectMeta.Labels,
extensions.DefaultDeploymentUniqueLabelKey)
apps.DefaultDeploymentUniqueLabelKey)
return deployment
}
// GetReplicaCountForReplicaSets returns the sum of Replicas of the given replica sets.
func GetReplicaCountForReplicaSets(replicaSets []*extensions.ReplicaSet) int32 {
func GetReplicaCountForReplicaSets(replicaSets []*apps.ReplicaSet) int32 {
totalReplicas := int32(0)
for _, rs := range replicaSets {
if rs != nil {
@ -749,7 +703,7 @@ func GetReplicaCountForReplicaSets(replicaSets []*extensions.ReplicaSet) int32 {
}
// GetActualReplicaCountForReplicaSets returns the sum of actual replicas of the given replica sets.
func GetActualReplicaCountForReplicaSets(replicaSets []*extensions.ReplicaSet) int32 {
func GetActualReplicaCountForReplicaSets(replicaSets []*apps.ReplicaSet) int32 {
totalActualReplicas := int32(0)
for _, rs := range replicaSets {
if rs != nil {
@ -760,7 +714,7 @@ func GetActualReplicaCountForReplicaSets(replicaSets []*extensions.ReplicaSet) i
}
// GetReadyReplicaCountForReplicaSets returns the number of ready pods corresponding to the given replica sets.
func GetReadyReplicaCountForReplicaSets(replicaSets []*extensions.ReplicaSet) int32 {
func GetReadyReplicaCountForReplicaSets(replicaSets []*apps.ReplicaSet) int32 {
totalReadyReplicas := int32(0)
for _, rs := range replicaSets {
if rs != nil {
@ -771,7 +725,7 @@ func GetReadyReplicaCountForReplicaSets(replicaSets []*extensions.ReplicaSet) in
}
// GetAvailableReplicaCountForReplicaSets returns the number of available pods corresponding to the given replica sets.
func GetAvailableReplicaCountForReplicaSets(replicaSets []*extensions.ReplicaSet) int32 {
func GetAvailableReplicaCountForReplicaSets(replicaSets []*apps.ReplicaSet) int32 {
totalAvailableReplicas := int32(0)
for _, rs := range replicaSets {
if rs != nil {
@ -782,13 +736,13 @@ func GetAvailableReplicaCountForReplicaSets(replicaSets []*extensions.ReplicaSet
}
// IsRollingUpdate returns true if the strategy type is a rolling update.
func IsRollingUpdate(deployment *extensions.Deployment) bool {
return deployment.Spec.Strategy.Type == extensions.RollingUpdateDeploymentStrategyType
func IsRollingUpdate(deployment *apps.Deployment) bool {
return deployment.Spec.Strategy.Type == apps.RollingUpdateDeploymentStrategyType
}
// DeploymentComplete considers a deployment to be complete once all of its desired replicas
// are updated and available, and no old pods are running.
func DeploymentComplete(deployment *extensions.Deployment, newStatus *extensions.DeploymentStatus) bool {
func DeploymentComplete(deployment *apps.Deployment, newStatus *apps.DeploymentStatus) bool {
return newStatus.UpdatedReplicas == *(deployment.Spec.Replicas) &&
newStatus.Replicas == *(deployment.Spec.Replicas) &&
newStatus.AvailableReplicas == *(deployment.Spec.Replicas) &&
@ -799,7 +753,7 @@ func DeploymentComplete(deployment *extensions.Deployment, newStatus *extensions
// current with the new status of the deployment that the controller is observing. More specifically,
// when new pods are scaled up or become ready or available, or old pods are scaled down, then we
// consider the deployment is progressing.
func DeploymentProgressing(deployment *extensions.Deployment, newStatus *extensions.DeploymentStatus) bool {
func DeploymentProgressing(deployment *apps.Deployment, newStatus *apps.DeploymentStatus) bool {
oldStatus := deployment.Status
// Old replicas that need to be scaled down
@ -818,7 +772,7 @@ var nowFn = func() time.Time { return time.Now() }
// DeploymentTimedOut considers a deployment to have timed out once its condition that reports progress
// is older than progressDeadlineSeconds or a Progressing condition with a TimedOutReason reason already
// exists.
func DeploymentTimedOut(deployment *extensions.Deployment, newStatus *extensions.DeploymentStatus) bool {
func DeploymentTimedOut(deployment *apps.Deployment, newStatus *apps.DeploymentStatus) bool {
if deployment.Spec.ProgressDeadlineSeconds == nil {
return false
}
@ -826,7 +780,7 @@ func DeploymentTimedOut(deployment *extensions.Deployment, newStatus *extensions
// Look for the Progressing condition. If it doesn't exist, we have no base to estimate progress.
// If it's already set with a TimedOutReason reason, we have already timed out, no need to check
// again.
condition := GetDeploymentCondition(*newStatus, extensions.DeploymentProgressing)
condition := GetDeploymentCondition(*newStatus, apps.DeploymentProgressing)
if condition == nil {
return false
}
@ -864,9 +818,9 @@ func DeploymentTimedOut(deployment *extensions.Deployment, newStatus *extensions
// When one of the followings is true, we're rolling out the deployment; otherwise, we're scaling it.
// 1) The new RS is saturated: newRS's replicas == deployment's replicas
// 2) Max number of pods allowed is reached: deployment's replicas + maxSurge == all RSs' replicas
func NewRSNewReplicas(deployment *extensions.Deployment, allRSs []*extensions.ReplicaSet, newRS *extensions.ReplicaSet) (int32, error) {
func NewRSNewReplicas(deployment *apps.Deployment, allRSs []*apps.ReplicaSet, newRS *apps.ReplicaSet) (int32, error) {
switch deployment.Spec.Strategy.Type {
case extensions.RollingUpdateDeploymentStrategyType:
case apps.RollingUpdateDeploymentStrategyType:
// Check if we can scale up.
maxSurge, err := intstrutil.GetValueFromIntOrPercent(deployment.Spec.Strategy.RollingUpdate.MaxSurge, int(*(deployment.Spec.Replicas)), true)
if err != nil {
@ -884,7 +838,7 @@ func NewRSNewReplicas(deployment *extensions.Deployment, allRSs []*extensions.Re
// Do not exceed the number of desired replicas.
scaleUpCount = int32(integer.IntMin(int(scaleUpCount), int(*(deployment.Spec.Replicas)-*(newRS.Spec.Replicas))))
return *(newRS.Spec.Replicas) + scaleUpCount, nil
case extensions.RecreateDeploymentStrategyType:
case apps.RecreateDeploymentStrategyType:
return *(deployment.Spec.Replicas), nil
default:
return 0, fmt.Errorf("deployment type %v isn't supported", deployment.Spec.Strategy.Type)
@ -895,7 +849,7 @@ func NewRSNewReplicas(deployment *extensions.Deployment, allRSs []*extensions.Re
// Both the deployment and the replica set have to believe this replica set can own all of the desired
// replicas in the deployment and the annotation helps in achieving that. All pods of the ReplicaSet
// need to be available.
func IsSaturated(deployment *extensions.Deployment, rs *extensions.ReplicaSet) bool {
func IsSaturated(deployment *apps.Deployment, rs *apps.ReplicaSet) bool {
if rs == nil {
return false
}
@ -911,7 +865,7 @@ func IsSaturated(deployment *extensions.Deployment, rs *extensions.ReplicaSet) b
// WaitForObservedDeployment polls for deployment to be updated so that deployment.Status.ObservedGeneration >= desiredGeneration.
// Returns error if polling timesout.
func WaitForObservedDeployment(getDeploymentFunc func() (*extensions.Deployment, error), desiredGeneration int64, interval, timeout time.Duration) error {
func WaitForObservedDeployment(getDeploymentFunc func() (*apps.Deployment, error), desiredGeneration int64, interval, timeout time.Duration) error {
// TODO: This should take clientset.Interface when all code is updated to use clientset. Keeping it this way allows the function to be used by callers who have client.Interface.
return wait.PollImmediate(interval, timeout, func() (bool, error) {
deployment, err := getDeploymentFunc()

View File

@ -25,8 +25,8 @@ import (
"testing"
"time"
apps "k8s.io/api/apps/v1"
"k8s.io/api/core/v1"
extensions "k8s.io/api/extensions/v1beta1"
apiequality "k8s.io/apimachinery/pkg/api/equality"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
@ -53,7 +53,7 @@ func addListPodsReactor(fakeClient *fake.Clientset, obj runtime.Object) *fake.Cl
}
func addGetRSReactor(fakeClient *fake.Clientset, obj runtime.Object) *fake.Clientset {
rsList, ok := obj.(*extensions.ReplicaSetList)
rsList, ok := obj.(*apps.ReplicaSetList)
fakeClient.AddReactor("get", "replicasets", func(action core.Action) (handled bool, ret runtime.Object, err error) {
name := action.(core.GetAction).GetName()
if ok {
@ -71,7 +71,7 @@ func addGetRSReactor(fakeClient *fake.Clientset, obj runtime.Object) *fake.Clien
func addUpdateRSReactor(fakeClient *fake.Clientset) *fake.Clientset {
fakeClient.AddReactor("update", "replicasets", func(action core.Action) (handled bool, ret runtime.Object, err error) {
obj := action.(core.UpdateAction).GetObject().(*extensions.ReplicaSet)
obj := action.(core.UpdateAction).GetObject().(*apps.ReplicaSet)
return true, obj, nil
})
return fakeClient
@ -85,13 +85,13 @@ func addUpdatePodsReactor(fakeClient *fake.Clientset) *fake.Clientset {
return fakeClient
}
func generateRSWithLabel(labels map[string]string, image string) extensions.ReplicaSet {
return extensions.ReplicaSet{
func generateRSWithLabel(labels map[string]string, image string) apps.ReplicaSet {
return apps.ReplicaSet{
ObjectMeta: metav1.ObjectMeta{
Name: names.SimpleNameGenerator.GenerateName("replicaset"),
Labels: labels,
},
Spec: extensions.ReplicaSetSpec{
Spec: apps.ReplicaSetSpec{
Replicas: func(i int32) *int32 { return &i }(1),
Selector: &metav1.LabelSelector{MatchLabels: labels},
Template: v1.PodTemplateSpec{
@ -113,10 +113,10 @@ func generateRSWithLabel(labels map[string]string, image string) extensions.Repl
}
}
func newDControllerRef(d *extensions.Deployment) *metav1.OwnerReference {
func newDControllerRef(d *apps.Deployment) *metav1.OwnerReference {
isController := true
return &metav1.OwnerReference{
APIVersion: "extensions/v1beta1",
APIVersion: "apps/v1",
Kind: "Deployment",
Name: d.GetName(),
UID: d.GetUID(),
@ -125,16 +125,16 @@ func newDControllerRef(d *extensions.Deployment) *metav1.OwnerReference {
}
// generateRS creates a replica set, with the input deployment's template as its template
func generateRS(deployment extensions.Deployment) extensions.ReplicaSet {
func generateRS(deployment apps.Deployment) apps.ReplicaSet {
template := deployment.Spec.Template.DeepCopy()
return extensions.ReplicaSet{
return apps.ReplicaSet{
ObjectMeta: metav1.ObjectMeta{
UID: randomUID(),
Name: names.SimpleNameGenerator.GenerateName("replicaset"),
Labels: template.Labels,
OwnerReferences: []metav1.OwnerReference{*newDControllerRef(&deployment)},
},
Spec: extensions.ReplicaSetSpec{
Spec: apps.ReplicaSetSpec{
Replicas: new(int32),
Template: *template,
Selector: &metav1.LabelSelector{MatchLabels: template.Labels},
@ -147,15 +147,15 @@ func randomUID() types.UID {
}
// generateDeployment creates a deployment, with the input image as its template
func generateDeployment(image string) extensions.Deployment {
func generateDeployment(image string) apps.Deployment {
podLabels := map[string]string{"name": image}
terminationSec := int64(30)
return extensions.Deployment{
return apps.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: image,
Annotations: make(map[string]string),
},
Spec: extensions.DeploymentSpec{
Spec: apps.DeploymentSpec{
Replicas: func(i int32) *int32 { return &i }(1),
Selector: &metav1.LabelSelector{MatchLabels: podLabels},
Template: v1.PodTemplateSpec{
@ -188,14 +188,14 @@ func TestGetNewRS(t *testing.T) {
tests := []struct {
Name string
objs []runtime.Object
expected *extensions.ReplicaSet
expected *apps.ReplicaSet
}{
{
"No new ReplicaSet",
[]runtime.Object{
&v1.PodList{},
&extensions.ReplicaSetList{
Items: []extensions.ReplicaSet{
&apps.ReplicaSetList{
Items: []apps.ReplicaSet{
generateRS(generateDeployment("foo")),
generateRS(generateDeployment("bar")),
},
@ -207,8 +207,8 @@ func TestGetNewRS(t *testing.T) {
"Has new ReplicaSet",
[]runtime.Object{
&v1.PodList{},
&extensions.ReplicaSetList{
Items: []extensions.ReplicaSet{
&apps.ReplicaSetList{
Items: []apps.ReplicaSet{
generateRS(generateDeployment("foo")),
generateRS(generateDeployment("bar")),
generateRS(generateDeployment("abc")),
@ -228,7 +228,7 @@ func TestGetNewRS(t *testing.T) {
fakeClient = addListRSReactor(fakeClient, test.objs[1])
fakeClient = addUpdatePodsReactor(fakeClient)
fakeClient = addUpdateRSReactor(fakeClient)
rs, err := GetNewReplicaSet(&newDeployment, fakeClient.ExtensionsV1beta1())
rs, err := GetNewReplicaSet(&newDeployment, fakeClient.AppsV1())
if err != nil {
t.Errorf("In test case %s, got unexpected error %v", test.Name, err)
}
@ -262,13 +262,13 @@ func TestGetOldRSs(t *testing.T) {
tests := []struct {
Name string
objs []runtime.Object
expected []*extensions.ReplicaSet
expected []*apps.ReplicaSet
}{
{
"No old ReplicaSets",
[]runtime.Object{
&extensions.ReplicaSetList{
Items: []extensions.ReplicaSet{
&apps.ReplicaSetList{
Items: []apps.ReplicaSet{
generateRS(generateDeployment("foo")),
newRS,
generateRS(generateDeployment("bar")),
@ -280,8 +280,8 @@ func TestGetOldRSs(t *testing.T) {
{
"Has old ReplicaSet",
[]runtime.Object{
&extensions.ReplicaSetList{
Items: []extensions.ReplicaSet{
&apps.ReplicaSetList{
Items: []apps.ReplicaSet{
oldRS2,
oldRS,
existedRS,
@ -291,7 +291,7 @@ func TestGetOldRSs(t *testing.T) {
},
},
},
[]*extensions.ReplicaSet{&oldRS, &oldRS2},
[]*apps.ReplicaSet{&oldRS, &oldRS2},
},
}
@ -301,7 +301,7 @@ func TestGetOldRSs(t *testing.T) {
fakeClient = addListRSReactor(fakeClient, test.objs[0])
fakeClient = addGetRSReactor(fakeClient, test.objs[0])
fakeClient = addUpdateRSReactor(fakeClient)
_, rss, err := GetOldReplicaSets(&newDeployment, fakeClient.ExtensionsV1beta1())
_, rss, err := GetOldReplicaSets(&newDeployment, fakeClient.AppsV1())
if err != nil {
t.Errorf("In test case %s, got unexpected error %v", test.Name, err)
}
@ -340,44 +340,56 @@ func TestEqualIgnoreHash(t *testing.T) {
}{
{
"Same spec, same labels",
generatePodTemplateSpec("foo", "foo-node", map[string]string{}, map[string]string{extensions.DefaultDeploymentUniqueLabelKey: "value-1", "something": "else"}),
generatePodTemplateSpec("foo", "foo-node", map[string]string{}, map[string]string{extensions.DefaultDeploymentUniqueLabelKey: "value-1", "something": "else"}),
generatePodTemplateSpec("foo", "foo-node", map[string]string{}, map[string]string{apps.DefaultDeploymentUniqueLabelKey: "value-1", "something": "else"}),
generatePodTemplateSpec("foo", "foo-node", map[string]string{}, map[string]string{apps.DefaultDeploymentUniqueLabelKey: "value-1", "something": "else"}),
true,
},
{
"Same spec, only pod-template-hash label value is different",
generatePodTemplateSpec("foo", "foo-node", map[string]string{}, map[string]string{extensions.DefaultDeploymentUniqueLabelKey: "value-1", "something": "else"}),
generatePodTemplateSpec("foo", "foo-node", map[string]string{}, map[string]string{extensions.DefaultDeploymentUniqueLabelKey: "value-2", "something": "else"}),
generatePodTemplateSpec("foo", "foo-node", map[string]string{}, map[string]string{apps.DefaultDeploymentUniqueLabelKey: "value-1", "something": "else"}),
generatePodTemplateSpec("foo", "foo-node", map[string]string{}, map[string]string{apps.DefaultDeploymentUniqueLabelKey: "value-2", "something": "else"}),
true,
},
{
"Same spec, the former doesn't have pod-template-hash label",
generatePodTemplateSpec("foo", "foo-node", map[string]string{}, map[string]string{"something": "else"}),
generatePodTemplateSpec("foo", "foo-node", map[string]string{}, map[string]string{extensions.DefaultDeploymentUniqueLabelKey: "value-2", "something": "else"}),
generatePodTemplateSpec("foo", "foo-node", map[string]string{}, map[string]string{apps.DefaultDeploymentUniqueLabelKey: "value-2", "something": "else"}),
true,
},
{
"Same spec, the label is different, the former doesn't have pod-template-hash label, same number of labels",
generatePodTemplateSpec("foo", "foo-node", map[string]string{}, map[string]string{"something": "else"}),
generatePodTemplateSpec("foo", "foo-node", map[string]string{}, map[string]string{apps.DefaultDeploymentUniqueLabelKey: "value-2"}),
false,
},
{
"Same spec, the label is different, the latter doesn't have pod-template-hash label, same number of labels",
generatePodTemplateSpec("foo", "foo-node", map[string]string{}, map[string]string{apps.DefaultDeploymentUniqueLabelKey: "value-1"}),
generatePodTemplateSpec("foo", "foo-node", map[string]string{}, map[string]string{"something": "else"}),
false,
},
{
"Same spec, the label is different, and the pod-template-hash label value is the same",
generatePodTemplateSpec("foo", "foo-node", map[string]string{}, map[string]string{extensions.DefaultDeploymentUniqueLabelKey: "value-1"}),
generatePodTemplateSpec("foo", "foo-node", map[string]string{}, map[string]string{extensions.DefaultDeploymentUniqueLabelKey: "value-1", "something": "else"}),
generatePodTemplateSpec("foo", "foo-node", map[string]string{}, map[string]string{apps.DefaultDeploymentUniqueLabelKey: "value-1"}),
generatePodTemplateSpec("foo", "foo-node", map[string]string{}, map[string]string{apps.DefaultDeploymentUniqueLabelKey: "value-1", "something": "else"}),
false,
},
{
"Different spec, same labels",
generatePodTemplateSpec("foo", "foo-node", map[string]string{"former": "value"}, map[string]string{extensions.DefaultDeploymentUniqueLabelKey: "value-1", "something": "else"}),
generatePodTemplateSpec("foo", "foo-node", map[string]string{"latter": "value"}, map[string]string{extensions.DefaultDeploymentUniqueLabelKey: "value-1", "something": "else"}),
generatePodTemplateSpec("foo", "foo-node", map[string]string{"former": "value"}, map[string]string{apps.DefaultDeploymentUniqueLabelKey: "value-1", "something": "else"}),
generatePodTemplateSpec("foo", "foo-node", map[string]string{"latter": "value"}, map[string]string{apps.DefaultDeploymentUniqueLabelKey: "value-1", "something": "else"}),
false,
},
{
"Different spec, different pod-template-hash label value",
generatePodTemplateSpec("foo-1", "foo-node", map[string]string{}, map[string]string{extensions.DefaultDeploymentUniqueLabelKey: "value-1", "something": "else"}),
generatePodTemplateSpec("foo-2", "foo-node", map[string]string{}, map[string]string{extensions.DefaultDeploymentUniqueLabelKey: "value-2", "something": "else"}),
generatePodTemplateSpec("foo-1", "foo-node", map[string]string{}, map[string]string{apps.DefaultDeploymentUniqueLabelKey: "value-1", "something": "else"}),
generatePodTemplateSpec("foo-2", "foo-node", map[string]string{}, map[string]string{apps.DefaultDeploymentUniqueLabelKey: "value-2", "something": "else"}),
false,
},
{
"Different spec, the former doesn't have pod-template-hash label",
generatePodTemplateSpec("foo-1", "foo-node-1", map[string]string{}, map[string]string{"something": "else"}),
generatePodTemplateSpec("foo-2", "foo-node-2", map[string]string{}, map[string]string{extensions.DefaultDeploymentUniqueLabelKey: "value-2", "something": "else"}),
generatePodTemplateSpec("foo-2", "foo-node-2", map[string]string{}, map[string]string{apps.DefaultDeploymentUniqueLabelKey: "value-2", "something": "else"}),
false,
},
{
@ -419,11 +431,11 @@ func TestFindNewReplicaSet(t *testing.T) {
deployment := generateDeployment("nginx")
newRS := generateRS(deployment)
newRS.Labels[extensions.DefaultDeploymentUniqueLabelKey] = "hash"
newRS.Labels[apps.DefaultDeploymentUniqueLabelKey] = "hash"
newRS.CreationTimestamp = later
newRSDup := generateRS(deployment)
newRSDup.Labels[extensions.DefaultDeploymentUniqueLabelKey] = "different-hash"
newRSDup.Labels[apps.DefaultDeploymentUniqueLabelKey] = "different-hash"
newRSDup.CreationTimestamp = now
oldDeployment := generateDeployment("nginx")
@ -433,26 +445,26 @@ func TestFindNewReplicaSet(t *testing.T) {
tests := []struct {
Name string
deployment extensions.Deployment
rsList []*extensions.ReplicaSet
expected *extensions.ReplicaSet
deployment apps.Deployment
rsList []*apps.ReplicaSet
expected *apps.ReplicaSet
}{
{
Name: "Get new ReplicaSet with the same template as Deployment spec but different pod-template-hash value",
deployment: deployment,
rsList: []*extensions.ReplicaSet{&newRS, &oldRS},
rsList: []*apps.ReplicaSet{&newRS, &oldRS},
expected: &newRS,
},
{
Name: "Get the oldest new ReplicaSet when there are more than one ReplicaSet with the same template",
deployment: deployment,
rsList: []*extensions.ReplicaSet{&newRS, &oldRS, &newRSDup},
rsList: []*apps.ReplicaSet{&newRS, &oldRS, &newRSDup},
expected: &newRSDup,
},
{
Name: "Get nil new ReplicaSet",
deployment: deployment,
rsList: []*extensions.ReplicaSet{&oldRS},
rsList: []*apps.ReplicaSet{&oldRS},
expected: nil,
},
}
@ -474,11 +486,11 @@ func TestFindOldReplicaSets(t *testing.T) {
deployment := generateDeployment("nginx")
newRS := generateRS(deployment)
*(newRS.Spec.Replicas) = 1
newRS.Labels[extensions.DefaultDeploymentUniqueLabelKey] = "hash"
newRS.Labels[apps.DefaultDeploymentUniqueLabelKey] = "hash"
newRS.CreationTimestamp = later
newRSDup := generateRS(deployment)
newRSDup.Labels[extensions.DefaultDeploymentUniqueLabelKey] = "different-hash"
newRSDup.Labels[apps.DefaultDeploymentUniqueLabelKey] = "different-hash"
newRSDup.CreationTimestamp = now
oldDeployment := generateDeployment("nginx")
@ -489,37 +501,37 @@ func TestFindOldReplicaSets(t *testing.T) {
tests := []struct {
Name string
deployment extensions.Deployment
rsList []*extensions.ReplicaSet
deployment apps.Deployment
rsList []*apps.ReplicaSet
podList *v1.PodList
expected []*extensions.ReplicaSet
expectedRequire []*extensions.ReplicaSet
expected []*apps.ReplicaSet
expectedRequire []*apps.ReplicaSet
}{
{
Name: "Get old ReplicaSets",
deployment: deployment,
rsList: []*extensions.ReplicaSet{&newRS, &oldRS},
expected: []*extensions.ReplicaSet{&oldRS},
rsList: []*apps.ReplicaSet{&newRS, &oldRS},
expected: []*apps.ReplicaSet{&oldRS},
expectedRequire: nil,
},
{
Name: "Get old ReplicaSets with no new ReplicaSet",
deployment: deployment,
rsList: []*extensions.ReplicaSet{&oldRS},
expected: []*extensions.ReplicaSet{&oldRS},
rsList: []*apps.ReplicaSet{&oldRS},
expected: []*apps.ReplicaSet{&oldRS},
expectedRequire: nil,
},
{
Name: "Get old ReplicaSets with two new ReplicaSets, only the oldest new ReplicaSet is seen as new ReplicaSet",
deployment: deployment,
rsList: []*extensions.ReplicaSet{&oldRS, &newRS, &newRSDup},
expected: []*extensions.ReplicaSet{&oldRS, &newRS},
expectedRequire: []*extensions.ReplicaSet{&newRS},
rsList: []*apps.ReplicaSet{&oldRS, &newRS, &newRSDup},
expected: []*apps.ReplicaSet{&oldRS, &newRS},
expectedRequire: []*apps.ReplicaSet{&newRS},
},
{
Name: "Get empty old ReplicaSets",
deployment: deployment,
rsList: []*extensions.ReplicaSet{&newRS},
rsList: []*apps.ReplicaSet{&newRS},
expected: nil,
expectedRequire: nil,
},
@ -542,7 +554,7 @@ func TestFindOldReplicaSets(t *testing.T) {
}
// equal compares the equality of two ReplicaSet slices regardless of their ordering
func equal(rss1, rss2 []*extensions.ReplicaSet) bool {
func equal(rss1, rss2 []*apps.ReplicaSet) bool {
if reflect.DeepEqual(rss1, rss2) {
return true
}
@ -571,19 +583,19 @@ func TestGetReplicaCountForReplicaSets(t *testing.T) {
tests := []struct {
Name string
sets []*extensions.ReplicaSet
sets []*apps.ReplicaSet
expectedCount int32
expectedActual int32
}{
{
"1:2 Replicas",
[]*extensions.ReplicaSet{&rs1},
[]*apps.ReplicaSet{&rs1},
1,
2,
},
{
"3:5 Replicas",
[]*extensions.ReplicaSet{&rs1, &rs2},
[]*apps.ReplicaSet{&rs1, &rs2},
3,
5,
},
@ -667,7 +679,7 @@ func TestResolveFenceposts(t *testing.T) {
func TestNewRSNewReplicas(t *testing.T) {
tests := []struct {
Name string
strategyType extensions.DeploymentStrategyType
strategyType apps.DeploymentStrategyType
depReplicas int32
newRSReplicas int32
maxSurge int
@ -675,17 +687,17 @@ func TestNewRSNewReplicas(t *testing.T) {
}{
{
"can not scale up - to newRSReplicas",
extensions.RollingUpdateDeploymentStrategyType,
apps.RollingUpdateDeploymentStrategyType,
1, 5, 1, 5,
},
{
"scale up - to depReplicas",
extensions.RollingUpdateDeploymentStrategyType,
apps.RollingUpdateDeploymentStrategyType,
6, 2, 10, 6,
},
{
"recreate - to depReplicas",
extensions.RecreateDeploymentStrategyType,
apps.RecreateDeploymentStrategyType,
3, 1, 1, 3,
},
}
@ -697,8 +709,8 @@ func TestNewRSNewReplicas(t *testing.T) {
for _, test := range tests {
t.Run(test.Name, func(t *testing.T) {
*(newDeployment.Spec.Replicas) = test.depReplicas
newDeployment.Spec.Strategy = extensions.DeploymentStrategy{Type: test.strategyType}
newDeployment.Spec.Strategy.RollingUpdate = &extensions.RollingUpdateDeployment{
newDeployment.Spec.Strategy = apps.DeploymentStrategy{Type: test.strategyType}
newDeployment.Spec.Strategy.RollingUpdate = &apps.RollingUpdateDeployment{
MaxUnavailable: func(i int) *intstr.IntOrString {
x := intstr.FromInt(i)
return &x
@ -709,7 +721,7 @@ func TestNewRSNewReplicas(t *testing.T) {
}(test.maxSurge),
}
*(newRC.Spec.Replicas) = test.newRSReplicas
rs, err := NewRSNewReplicas(&newDeployment, []*extensions.ReplicaSet{&rs5}, &newRC)
rs, err := NewRSNewReplicas(&newDeployment, []*apps.ReplicaSet{&rs5}, &newRC)
if err != nil {
t.Errorf("In test case %s, got unexpected error %v", test.Name, err)
}
@ -721,33 +733,33 @@ func TestNewRSNewReplicas(t *testing.T) {
}
var (
condProgressing = func() extensions.DeploymentCondition {
return extensions.DeploymentCondition{
Type: extensions.DeploymentProgressing,
condProgressing = func() apps.DeploymentCondition {
return apps.DeploymentCondition{
Type: apps.DeploymentProgressing,
Status: v1.ConditionFalse,
Reason: "ForSomeReason",
}
}
condProgressing2 = func() extensions.DeploymentCondition {
return extensions.DeploymentCondition{
Type: extensions.DeploymentProgressing,
condProgressing2 = func() apps.DeploymentCondition {
return apps.DeploymentCondition{
Type: apps.DeploymentProgressing,
Status: v1.ConditionTrue,
Reason: "BecauseItIs",
}
}
condAvailable = func() extensions.DeploymentCondition {
return extensions.DeploymentCondition{
Type: extensions.DeploymentAvailable,
condAvailable = func() apps.DeploymentCondition {
return apps.DeploymentCondition{
Type: apps.DeploymentAvailable,
Status: v1.ConditionTrue,
Reason: "AwesomeController",
}
}
status = func() *extensions.DeploymentStatus {
return &extensions.DeploymentStatus{
Conditions: []extensions.DeploymentCondition{condProgressing(), condAvailable()},
status = func() *apps.DeploymentStatus {
return &apps.DeploymentStatus{
Conditions: []apps.DeploymentCondition{condProgressing(), condAvailable()},
}
}
)
@ -758,8 +770,8 @@ func TestGetCondition(t *testing.T) {
tests := []struct {
name string
status extensions.DeploymentStatus
condType extensions.DeploymentConditionType
status apps.DeploymentStatus
condType apps.DeploymentConditionType
expected bool
}{
@ -767,7 +779,7 @@ func TestGetCondition(t *testing.T) {
name: "condition exists",
status: *exampleStatus,
condType: extensions.DeploymentAvailable,
condType: apps.DeploymentAvailable,
expected: true,
},
@ -775,7 +787,7 @@ func TestGetCondition(t *testing.T) {
name: "condition does not exist",
status: *exampleStatus,
condType: extensions.DeploymentReplicaFailure,
condType: apps.DeploymentReplicaFailure,
expected: false,
},
@ -796,23 +808,23 @@ func TestSetCondition(t *testing.T) {
tests := []struct {
name string
status *extensions.DeploymentStatus
cond extensions.DeploymentCondition
status *apps.DeploymentStatus
cond apps.DeploymentCondition
expectedStatus *extensions.DeploymentStatus
expectedStatus *apps.DeploymentStatus
}{
{
name: "set for the first time",
status: &extensions.DeploymentStatus{},
status: &apps.DeploymentStatus{},
cond: condAvailable(),
expectedStatus: &extensions.DeploymentStatus{Conditions: []extensions.DeploymentCondition{condAvailable()}},
expectedStatus: &apps.DeploymentStatus{Conditions: []apps.DeploymentCondition{condAvailable()}},
},
{
name: "simple set",
status: &extensions.DeploymentStatus{Conditions: []extensions.DeploymentCondition{condProgressing()}},
status: &apps.DeploymentStatus{Conditions: []apps.DeploymentCondition{condProgressing()}},
cond: condAvailable(),
expectedStatus: status(),
@ -820,10 +832,10 @@ func TestSetCondition(t *testing.T) {
{
name: "overwrite",
status: &extensions.DeploymentStatus{Conditions: []extensions.DeploymentCondition{condProgressing()}},
status: &apps.DeploymentStatus{Conditions: []apps.DeploymentCondition{condProgressing()}},
cond: condProgressing2(),
expectedStatus: &extensions.DeploymentStatus{Conditions: []extensions.DeploymentCondition{condProgressing2()}},
expectedStatus: &apps.DeploymentStatus{Conditions: []apps.DeploymentCondition{condProgressing2()}},
},
}
@ -841,32 +853,32 @@ func TestRemoveCondition(t *testing.T) {
tests := []struct {
name string
status *extensions.DeploymentStatus
condType extensions.DeploymentConditionType
status *apps.DeploymentStatus
condType apps.DeploymentConditionType
expectedStatus *extensions.DeploymentStatus
expectedStatus *apps.DeploymentStatus
}{
{
name: "remove from empty status",
status: &extensions.DeploymentStatus{},
condType: extensions.DeploymentProgressing,
status: &apps.DeploymentStatus{},
condType: apps.DeploymentProgressing,
expectedStatus: &extensions.DeploymentStatus{},
expectedStatus: &apps.DeploymentStatus{},
},
{
name: "simple remove",
status: &extensions.DeploymentStatus{Conditions: []extensions.DeploymentCondition{condProgressing()}},
condType: extensions.DeploymentProgressing,
status: &apps.DeploymentStatus{Conditions: []apps.DeploymentCondition{condProgressing()}},
condType: apps.DeploymentProgressing,
expectedStatus: &extensions.DeploymentStatus{},
expectedStatus: &apps.DeploymentStatus{},
},
{
name: "doesn't remove anything",
status: status(),
condType: extensions.DeploymentReplicaFailure,
condType: apps.DeploymentReplicaFailure,
expectedStatus: status(),
},
@ -883,19 +895,19 @@ func TestRemoveCondition(t *testing.T) {
}
func TestDeploymentComplete(t *testing.T) {
deployment := func(desired, current, updated, available, maxUnavailable, maxSurge int32) *extensions.Deployment {
return &extensions.Deployment{
Spec: extensions.DeploymentSpec{
deployment := func(desired, current, updated, available, maxUnavailable, maxSurge int32) *apps.Deployment {
return &apps.Deployment{
Spec: apps.DeploymentSpec{
Replicas: &desired,
Strategy: extensions.DeploymentStrategy{
RollingUpdate: &extensions.RollingUpdateDeployment{
Strategy: apps.DeploymentStrategy{
RollingUpdate: &apps.RollingUpdateDeployment{
MaxUnavailable: func(i int) *intstr.IntOrString { x := intstr.FromInt(i); return &x }(int(maxUnavailable)),
MaxSurge: func(i int) *intstr.IntOrString { x := intstr.FromInt(i); return &x }(int(maxSurge)),
},
Type: extensions.RollingUpdateDeploymentStrategyType,
Type: apps.RollingUpdateDeploymentStrategyType,
},
},
Status: extensions.DeploymentStatus{
Status: apps.DeploymentStatus{
Replicas: current,
UpdatedReplicas: updated,
AvailableReplicas: available,
@ -906,7 +918,7 @@ func TestDeploymentComplete(t *testing.T) {
tests := []struct {
name string
d *extensions.Deployment
d *apps.Deployment
expected bool
}{
@ -960,9 +972,9 @@ func TestDeploymentComplete(t *testing.T) {
}
func TestDeploymentProgressing(t *testing.T) {
deployment := func(current, updated, ready, available int32) *extensions.Deployment {
return &extensions.Deployment{
Status: extensions.DeploymentStatus{
deployment := func(current, updated, ready, available int32) *apps.Deployment {
return &apps.Deployment{
Status: apps.DeploymentStatus{
Replicas: current,
UpdatedReplicas: updated,
ReadyReplicas: ready,
@ -970,8 +982,8 @@ func TestDeploymentProgressing(t *testing.T) {
},
}
}
newStatus := func(current, updated, ready, available int32) extensions.DeploymentStatus {
return extensions.DeploymentStatus{
newStatus := func(current, updated, ready, available int32) apps.DeploymentStatus {
return apps.DeploymentStatus{
Replicas: current,
UpdatedReplicas: updated,
ReadyReplicas: ready,
@ -982,8 +994,8 @@ func TestDeploymentProgressing(t *testing.T) {
tests := []struct {
name string
d *extensions.Deployment
newStatus extensions.DeploymentStatus
d *apps.Deployment
newStatus apps.DeploymentStatus
expected bool
}{
@ -1063,13 +1075,13 @@ func TestDeploymentTimedOut(t *testing.T) {
timeFn := func(min, sec int) time.Time {
return time.Date(2016, 1, 1, 0, min, sec, 0, time.UTC)
}
deployment := func(condType extensions.DeploymentConditionType, status v1.ConditionStatus, reason string, pds *int32, from time.Time) extensions.Deployment {
return extensions.Deployment{
Spec: extensions.DeploymentSpec{
deployment := func(condType apps.DeploymentConditionType, status v1.ConditionStatus, reason string, pds *int32, from time.Time) apps.Deployment {
return apps.Deployment{
Spec: apps.DeploymentSpec{
ProgressDeadlineSeconds: pds,
},
Status: extensions.DeploymentStatus{
Conditions: []extensions.DeploymentCondition{
Status: apps.DeploymentStatus{
Conditions: []apps.DeploymentCondition{
{
Type: condType,
Status: status,
@ -1084,7 +1096,7 @@ func TestDeploymentTimedOut(t *testing.T) {
tests := []struct {
name string
d extensions.Deployment
d apps.Deployment
nowFn func() time.Time
expected bool
@ -1092,28 +1104,28 @@ func TestDeploymentTimedOut(t *testing.T) {
{
name: "no progressDeadlineSeconds specified - no timeout",
d: deployment(extensions.DeploymentProgressing, v1.ConditionTrue, "", null, timeFn(1, 9)),
d: deployment(apps.DeploymentProgressing, v1.ConditionTrue, "", null, timeFn(1, 9)),
nowFn: func() time.Time { return timeFn(1, 20) },
expected: false,
},
{
name: "progressDeadlineSeconds: 10s, now - started => 00:01:20 - 00:01:09 => 11s",
d: deployment(extensions.DeploymentProgressing, v1.ConditionTrue, "", &ten, timeFn(1, 9)),
d: deployment(apps.DeploymentProgressing, v1.ConditionTrue, "", &ten, timeFn(1, 9)),
nowFn: func() time.Time { return timeFn(1, 20) },
expected: true,
},
{
name: "progressDeadlineSeconds: 10s, now - started => 00:01:20 - 00:01:11 => 9s",
d: deployment(extensions.DeploymentProgressing, v1.ConditionTrue, "", &ten, timeFn(1, 11)),
d: deployment(apps.DeploymentProgressing, v1.ConditionTrue, "", &ten, timeFn(1, 11)),
nowFn: func() time.Time { return timeFn(1, 20) },
expected: false,
},
{
name: "previous status was a complete deployment",
d: deployment(extensions.DeploymentProgressing, v1.ConditionTrue, NewRSAvailableReason, nil, time.Time{}),
d: deployment(apps.DeploymentProgressing, v1.ConditionTrue, NewRSAvailableReason, nil, time.Time{}),
expected: false,
},
}
@ -1129,23 +1141,23 @@ func TestDeploymentTimedOut(t *testing.T) {
}
func TestMaxUnavailable(t *testing.T) {
deployment := func(replicas int32, maxUnavailable intstr.IntOrString) extensions.Deployment {
return extensions.Deployment{
Spec: extensions.DeploymentSpec{
deployment := func(replicas int32, maxUnavailable intstr.IntOrString) apps.Deployment {
return apps.Deployment{
Spec: apps.DeploymentSpec{
Replicas: func(i int32) *int32 { return &i }(replicas),
Strategy: extensions.DeploymentStrategy{
RollingUpdate: &extensions.RollingUpdateDeployment{
Strategy: apps.DeploymentStrategy{
RollingUpdate: &apps.RollingUpdateDeployment{
MaxSurge: func(i int) *intstr.IntOrString { x := intstr.FromInt(i); return &x }(int(1)),
MaxUnavailable: &maxUnavailable,
},
Type: extensions.RollingUpdateDeploymentStrategyType,
Type: apps.RollingUpdateDeploymentStrategyType,
},
},
}
}
tests := []struct {
name string
deployment extensions.Deployment
deployment apps.Deployment
expected int32
}{
{
@ -1170,10 +1182,10 @@ func TestMaxUnavailable(t *testing.T) {
},
{
name: "maxUnavailable with Recreate deployment strategy",
deployment: extensions.Deployment{
Spec: extensions.DeploymentSpec{
Strategy: extensions.DeploymentStrategy{
Type: extensions.RecreateDeploymentStrategyType,
deployment: apps.Deployment{
Spec: apps.DeploymentSpec{
Strategy: apps.DeploymentStrategy{
Type: apps.RecreateDeploymentStrategyType,
},
},
},
@ -1265,3 +1277,77 @@ func TestAnnotationUtils(t *testing.T) {
})
//Tear Down
}
func TestReplicasAnnotationsNeedUpdate(t *testing.T) {
desiredReplicas := fmt.Sprintf("%d", int32(10))
maxReplicas := fmt.Sprintf("%d", int32(20))
tests := []struct {
name string
replicaSet *apps.ReplicaSet
expected bool
}{
{
name: "test Annotations nil",
replicaSet: &apps.ReplicaSet{
ObjectMeta: metav1.ObjectMeta{Name: "hello", Namespace: "test"},
Spec: apps.ReplicaSetSpec{
Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}},
},
},
expected: true,
},
{
name: "test desiredReplicas update",
replicaSet: &apps.ReplicaSet{
ObjectMeta: metav1.ObjectMeta{
Name: "hello",
Namespace: "test",
Annotations: map[string]string{DesiredReplicasAnnotation: "8", MaxReplicasAnnotation: maxReplicas},
},
Spec: apps.ReplicaSetSpec{
Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}},
},
},
expected: true,
},
{
name: "test maxReplicas update",
replicaSet: &apps.ReplicaSet{
ObjectMeta: metav1.ObjectMeta{
Name: "hello",
Namespace: "test",
Annotations: map[string]string{DesiredReplicasAnnotation: desiredReplicas, MaxReplicasAnnotation: "16"},
},
Spec: apps.ReplicaSetSpec{
Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}},
},
},
expected: true,
},
{
name: "test needn't update",
replicaSet: &apps.ReplicaSet{
ObjectMeta: metav1.ObjectMeta{
Name: "hello",
Namespace: "test",
Annotations: map[string]string{DesiredReplicasAnnotation: desiredReplicas, MaxReplicasAnnotation: maxReplicas},
},
Spec: apps.ReplicaSetSpec{
Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}},
},
},
expected: false,
},
}
for i, test := range tests {
t.Run(test.name, func(t *testing.T) {
result := ReplicasAnnotationsNeedUpdate(test.replicaSet, 10, 20)
if result != test.expected {
t.Errorf("case[%d]:%s Expected %v, Got: %v", i, test.name, test.expected, result)
}
})
}
}

View File

@ -17,27 +17,23 @@ limitations under the License.
package util
import (
"fmt"
"github.com/golang/glog"
extensions "k8s.io/api/extensions/v1beta1"
apps "k8s.io/api/apps/v1"
errorsutil "k8s.io/apimachinery/pkg/util/errors"
unversionedextensions "k8s.io/client-go/kubernetes/typed/extensions/v1beta1"
extensionslisters "k8s.io/client-go/listers/extensions/v1beta1"
appsclient "k8s.io/client-go/kubernetes/typed/apps/v1"
appslisters "k8s.io/client-go/listers/apps/v1"
"k8s.io/client-go/util/retry"
"k8s.io/kubernetes/pkg/controller"
labelsutil "k8s.io/kubernetes/pkg/util/labels"
)
// TODO: use client library instead when it starts to support update retries
// see https://github.com/kubernetes/kubernetes/issues/21479
type updateRSFunc func(rs *extensions.ReplicaSet) error
type updateRSFunc func(rs *apps.ReplicaSet) error
// UpdateRSWithRetries updates a RS with given applyUpdate function. Note that RS not found error is ignored.
// The returned bool value can be used to tell if the RS is actually updated.
func UpdateRSWithRetries(rsClient unversionedextensions.ReplicaSetInterface, rsLister extensionslisters.ReplicaSetLister, namespace, name string, applyUpdate updateRSFunc) (*extensions.ReplicaSet, error) {
var rs *extensions.ReplicaSet
func UpdateRSWithRetries(rsClient appsclient.ReplicaSetInterface, rsLister appslisters.ReplicaSetLister, namespace, name string, applyUpdate updateRSFunc) (*apps.ReplicaSet, error) {
var rs *apps.ReplicaSet
retryErr := retry.RetryOnConflict(retry.DefaultBackoff, func() error {
var err error
@ -62,10 +58,3 @@ func UpdateRSWithRetries(rsClient unversionedextensions.ReplicaSetInterface, rsL
return rs, retryErr
}
// GetReplicaSetHash returns the pod template hash of a ReplicaSet's pod template space
func GetReplicaSetHash(rs *extensions.ReplicaSet, uniquifier *int32) (string, error) {
rsTemplate := rs.Spec.Template.DeepCopy()
rsTemplate.Labels = labelsutil.CloneAndRemoveLabel(rsTemplate.Labels, extensions.DefaultDeploymentUniqueLabelKey)
return fmt.Sprintf("%d", controller.ComputeHash(rsTemplate, uniquifier)), nil
}