cmd/kube-controller-manager
This commit is contained in:
@@ -26,11 +26,13 @@ import (
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/meta"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
"k8s.io/kubernetes/pkg/api/validation"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
|
||||
"k8s.io/kubernetes/pkg/client/cache"
|
||||
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5"
|
||||
"k8s.io/kubernetes/pkg/client/record"
|
||||
"k8s.io/kubernetes/pkg/conversion"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/util/clock"
|
||||
@@ -363,11 +365,11 @@ const (
|
||||
// created as an interface to allow testing.
|
||||
type PodControlInterface interface {
|
||||
// CreatePods creates new pods according to the spec.
|
||||
CreatePods(namespace string, template *api.PodTemplateSpec, object runtime.Object) error
|
||||
CreatePods(namespace string, template *v1.PodTemplateSpec, object runtime.Object) error
|
||||
// CreatePodsOnNode creates a new pod according to the spec on the specified node.
|
||||
CreatePodsOnNode(nodeName, namespace string, template *api.PodTemplateSpec, object runtime.Object) error
|
||||
CreatePodsOnNode(nodeName, namespace string, template *v1.PodTemplateSpec, object runtime.Object) error
|
||||
// CreatePodsWithControllerRef creates new pods according to the spec, and sets object as the pod's controller.
|
||||
CreatePodsWithControllerRef(namespace string, template *api.PodTemplateSpec, object runtime.Object, controllerRef *api.OwnerReference) error
|
||||
CreatePodsWithControllerRef(namespace string, template *v1.PodTemplateSpec, object runtime.Object, controllerRef *v1.OwnerReference) error
|
||||
// DeletePod deletes the pod identified by podID.
|
||||
DeletePod(namespace string, podID string, object runtime.Object) error
|
||||
// PatchPod patches the pod.
|
||||
@@ -382,7 +384,7 @@ type RealPodControl struct {
|
||||
|
||||
var _ PodControlInterface = &RealPodControl{}
|
||||
|
||||
func getPodsLabelSet(template *api.PodTemplateSpec) labels.Set {
|
||||
func getPodsLabelSet(template *v1.PodTemplateSpec) labels.Set {
|
||||
desiredLabels := make(labels.Set)
|
||||
for k, v := range template.Labels {
|
||||
desiredLabels[k] = v
|
||||
@@ -390,18 +392,18 @@ func getPodsLabelSet(template *api.PodTemplateSpec) labels.Set {
|
||||
return desiredLabels
|
||||
}
|
||||
|
||||
func getPodsFinalizers(template *api.PodTemplateSpec) []string {
|
||||
func getPodsFinalizers(template *v1.PodTemplateSpec) []string {
|
||||
desiredFinalizers := make([]string, len(template.Finalizers))
|
||||
copy(desiredFinalizers, template.Finalizers)
|
||||
return desiredFinalizers
|
||||
}
|
||||
|
||||
func getPodsAnnotationSet(template *api.PodTemplateSpec, object runtime.Object) (labels.Set, error) {
|
||||
func getPodsAnnotationSet(template *v1.PodTemplateSpec, object runtime.Object) (labels.Set, error) {
|
||||
desiredAnnotations := make(labels.Set)
|
||||
for k, v := range template.Annotations {
|
||||
desiredAnnotations[k] = v
|
||||
}
|
||||
createdByRef, err := api.GetReference(object)
|
||||
createdByRef, err := v1.GetReference(object)
|
||||
if err != nil {
|
||||
return desiredAnnotations, fmt.Errorf("unable to get controller reference: %v", err)
|
||||
}
|
||||
@@ -409,15 +411,15 @@ func getPodsAnnotationSet(template *api.PodTemplateSpec, object runtime.Object)
|
||||
// TODO: this code was not safe previously - as soon as new code came along that switched to v2, old clients
|
||||
// would be broken upon reading it. This is explicitly hardcoded to v1 to guarantee predictable deployment.
|
||||
// We need to consistently handle this case of annotation versioning.
|
||||
codec := api.Codecs.LegacyCodec(unversioned.GroupVersion{Group: api.GroupName, Version: "v1"})
|
||||
codec := api.Codecs.LegacyCodec(unversioned.GroupVersion{Group: v1.GroupName, Version: "v1"})
|
||||
|
||||
createdByRefJson, err := runtime.Encode(codec, &api.SerializedReference{
|
||||
createdByRefJson, err := runtime.Encode(codec, &v1.SerializedReference{
|
||||
Reference: *createdByRef,
|
||||
})
|
||||
if err != nil {
|
||||
return desiredAnnotations, fmt.Errorf("unable to serialize controller reference: %v", err)
|
||||
}
|
||||
desiredAnnotations[api.CreatedByAnnotation] = string(createdByRefJson)
|
||||
desiredAnnotations[v1.CreatedByAnnotation] = string(createdByRefJson)
|
||||
return desiredAnnotations, nil
|
||||
}
|
||||
|
||||
@@ -430,11 +432,11 @@ func getPodsPrefix(controllerName string) string {
|
||||
return prefix
|
||||
}
|
||||
|
||||
func (r RealPodControl) CreatePods(namespace string, template *api.PodTemplateSpec, object runtime.Object) error {
|
||||
func (r RealPodControl) CreatePods(namespace string, template *v1.PodTemplateSpec, object runtime.Object) error {
|
||||
return r.createPods("", namespace, template, object, nil)
|
||||
}
|
||||
|
||||
func (r RealPodControl) CreatePodsWithControllerRef(namespace string, template *api.PodTemplateSpec, controllerObject runtime.Object, controllerRef *api.OwnerReference) error {
|
||||
func (r RealPodControl) CreatePodsWithControllerRef(namespace string, template *v1.PodTemplateSpec, controllerObject runtime.Object, controllerRef *v1.OwnerReference) error {
|
||||
if controllerRef == nil {
|
||||
return fmt.Errorf("controllerRef is nil")
|
||||
}
|
||||
@@ -450,7 +452,7 @@ func (r RealPodControl) CreatePodsWithControllerRef(namespace string, template *
|
||||
return r.createPods("", namespace, template, controllerObject, controllerRef)
|
||||
}
|
||||
|
||||
func (r RealPodControl) CreatePodsOnNode(nodeName, namespace string, template *api.PodTemplateSpec, object runtime.Object) error {
|
||||
func (r RealPodControl) CreatePodsOnNode(nodeName, namespace string, template *v1.PodTemplateSpec, object runtime.Object) error {
|
||||
return r.createPods(nodeName, namespace, template, object, nil)
|
||||
}
|
||||
|
||||
@@ -459,7 +461,7 @@ func (r RealPodControl) PatchPod(namespace, name string, data []byte) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func GetPodFromTemplate(template *api.PodTemplateSpec, parentObject runtime.Object, controllerRef *api.OwnerReference) (*api.Pod, error) {
|
||||
func GetPodFromTemplate(template *v1.PodTemplateSpec, parentObject runtime.Object, controllerRef *v1.OwnerReference) (*v1.Pod, error) {
|
||||
desiredLabels := getPodsLabelSet(template)
|
||||
desiredFinalizers := getPodsFinalizers(template)
|
||||
desiredAnnotations, err := getPodsAnnotationSet(template, parentObject)
|
||||
@@ -472,8 +474,8 @@ func GetPodFromTemplate(template *api.PodTemplateSpec, parentObject runtime.Obje
|
||||
}
|
||||
prefix := getPodsPrefix(accessor.GetName())
|
||||
|
||||
pod := &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
pod := &v1.Pod{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Labels: desiredLabels,
|
||||
Annotations: desiredAnnotations,
|
||||
GenerateName: prefix,
|
||||
@@ -483,13 +485,15 @@ func GetPodFromTemplate(template *api.PodTemplateSpec, parentObject runtime.Obje
|
||||
if controllerRef != nil {
|
||||
pod.OwnerReferences = append(pod.OwnerReferences, *controllerRef)
|
||||
}
|
||||
if err := api.Scheme.Convert(&template.Spec, &pod.Spec, nil); err != nil {
|
||||
return nil, fmt.Errorf("unable to convert pod template: %v", err)
|
||||
clone, err := conversion.NewCloner().DeepCopy(&template.Spec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pod.Spec = *clone.(*v1.PodSpec)
|
||||
return pod, nil
|
||||
}
|
||||
|
||||
func (r RealPodControl) createPods(nodeName, namespace string, template *api.PodTemplateSpec, object runtime.Object, controllerRef *api.OwnerReference) error {
|
||||
func (r RealPodControl) createPods(nodeName, namespace string, template *v1.PodTemplateSpec, object runtime.Object, controllerRef *v1.OwnerReference) error {
|
||||
pod, err := GetPodFromTemplate(template, object, controllerRef)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -501,7 +505,7 @@ func (r RealPodControl) createPods(nodeName, namespace string, template *api.Pod
|
||||
return fmt.Errorf("unable to create pods, no labels")
|
||||
}
|
||||
if newPod, err := r.KubeClient.Core().Pods(namespace).Create(pod); err != nil {
|
||||
r.Recorder.Eventf(object, api.EventTypeWarning, FailedCreatePodReason, "Error creating: %v", err)
|
||||
r.Recorder.Eventf(object, v1.EventTypeWarning, FailedCreatePodReason, "Error creating: %v", err)
|
||||
return fmt.Errorf("unable to create pods: %v", err)
|
||||
} else {
|
||||
accessor, err := meta.Accessor(object)
|
||||
@@ -510,7 +514,7 @@ func (r RealPodControl) createPods(nodeName, namespace string, template *api.Pod
|
||||
return nil
|
||||
}
|
||||
glog.V(4).Infof("Controller %v created pod %v", accessor.GetName(), newPod.Name)
|
||||
r.Recorder.Eventf(object, api.EventTypeNormal, SuccessfulCreatePodReason, "Created pod: %v", newPod.Name)
|
||||
r.Recorder.Eventf(object, v1.EventTypeNormal, SuccessfulCreatePodReason, "Created pod: %v", newPod.Name)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -522,18 +526,18 @@ func (r RealPodControl) DeletePod(namespace string, podID string, object runtime
|
||||
}
|
||||
glog.V(2).Infof("Controller %v deleting pod %v/%v", accessor.GetName(), namespace, podID)
|
||||
if err := r.KubeClient.Core().Pods(namespace).Delete(podID, nil); err != nil {
|
||||
r.Recorder.Eventf(object, api.EventTypeWarning, FailedDeletePodReason, "Error deleting: %v", err)
|
||||
r.Recorder.Eventf(object, v1.EventTypeWarning, FailedDeletePodReason, "Error deleting: %v", err)
|
||||
return fmt.Errorf("unable to delete pods: %v", err)
|
||||
} else {
|
||||
r.Recorder.Eventf(object, api.EventTypeNormal, SuccessfulDeletePodReason, "Deleted pod: %v", podID)
|
||||
r.Recorder.Eventf(object, v1.EventTypeNormal, SuccessfulDeletePodReason, "Deleted pod: %v", podID)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type FakePodControl struct {
|
||||
sync.Mutex
|
||||
Templates []api.PodTemplateSpec
|
||||
ControllerRefs []api.OwnerReference
|
||||
Templates []v1.PodTemplateSpec
|
||||
ControllerRefs []v1.OwnerReference
|
||||
DeletePodName []string
|
||||
Patches [][]byte
|
||||
Err error
|
||||
@@ -551,7 +555,7 @@ func (f *FakePodControl) PatchPod(namespace, name string, data []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FakePodControl) CreatePods(namespace string, spec *api.PodTemplateSpec, object runtime.Object) error {
|
||||
func (f *FakePodControl) CreatePods(namespace string, spec *v1.PodTemplateSpec, object runtime.Object) error {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.Templates = append(f.Templates, *spec)
|
||||
@@ -561,7 +565,7 @@ func (f *FakePodControl) CreatePods(namespace string, spec *api.PodTemplateSpec,
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FakePodControl) CreatePodsWithControllerRef(namespace string, spec *api.PodTemplateSpec, object runtime.Object, controllerRef *api.OwnerReference) error {
|
||||
func (f *FakePodControl) CreatePodsWithControllerRef(namespace string, spec *v1.PodTemplateSpec, object runtime.Object, controllerRef *v1.OwnerReference) error {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.Templates = append(f.Templates, *spec)
|
||||
@@ -572,7 +576,7 @@ func (f *FakePodControl) CreatePodsWithControllerRef(namespace string, spec *api
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FakePodControl) CreatePodsOnNode(nodeName, namespace string, template *api.PodTemplateSpec, object runtime.Object) error {
|
||||
func (f *FakePodControl) CreatePodsOnNode(nodeName, namespace string, template *v1.PodTemplateSpec, object runtime.Object) error {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.Templates = append(f.Templates, *template)
|
||||
@@ -596,13 +600,13 @@ func (f *FakePodControl) Clear() {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.DeletePodName = []string{}
|
||||
f.Templates = []api.PodTemplateSpec{}
|
||||
f.ControllerRefs = []api.OwnerReference{}
|
||||
f.Templates = []v1.PodTemplateSpec{}
|
||||
f.ControllerRefs = []v1.OwnerReference{}
|
||||
f.Patches = [][]byte{}
|
||||
}
|
||||
|
||||
// ByLogging allows custom sorting of pods so the best one can be picked for getting its logs.
|
||||
type ByLogging []*api.Pod
|
||||
type ByLogging []*v1.Pod
|
||||
|
||||
func (s ByLogging) Len() int { return len(s) }
|
||||
func (s ByLogging) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
@@ -613,18 +617,18 @@ func (s ByLogging) Less(i, j int) bool {
|
||||
return len(s[i].Spec.NodeName) > 0
|
||||
}
|
||||
// 2. PodRunning < PodUnknown < PodPending
|
||||
m := map[api.PodPhase]int{api.PodRunning: 0, api.PodUnknown: 1, api.PodPending: 2}
|
||||
m := map[v1.PodPhase]int{v1.PodRunning: 0, v1.PodUnknown: 1, v1.PodPending: 2}
|
||||
if m[s[i].Status.Phase] != m[s[j].Status.Phase] {
|
||||
return m[s[i].Status.Phase] < m[s[j].Status.Phase]
|
||||
}
|
||||
// 3. ready < not ready
|
||||
if api.IsPodReady(s[i]) != api.IsPodReady(s[j]) {
|
||||
return api.IsPodReady(s[i])
|
||||
if v1.IsPodReady(s[i]) != v1.IsPodReady(s[j]) {
|
||||
return v1.IsPodReady(s[i])
|
||||
}
|
||||
// TODO: take availability into account when we push minReadySeconds information from deployment into pods,
|
||||
// see https://github.com/kubernetes/kubernetes/issues/22065
|
||||
// 4. Been ready for more time < less time < empty time
|
||||
if api.IsPodReady(s[i]) && api.IsPodReady(s[j]) && !podReadyTime(s[i]).Equal(podReadyTime(s[j])) {
|
||||
if v1.IsPodReady(s[i]) && v1.IsPodReady(s[j]) && !podReadyTime(s[i]).Equal(podReadyTime(s[j])) {
|
||||
return afterOrZero(podReadyTime(s[j]), podReadyTime(s[i]))
|
||||
}
|
||||
// 5. Pods with containers with higher restart counts < lower restart counts
|
||||
@@ -639,7 +643,7 @@ func (s ByLogging) Less(i, j int) bool {
|
||||
}
|
||||
|
||||
// ActivePods type allows custom sorting of pods so a controller can pick the best ones to delete.
|
||||
type ActivePods []*api.Pod
|
||||
type ActivePods []*v1.Pod
|
||||
|
||||
func (s ActivePods) Len() int { return len(s) }
|
||||
func (s ActivePods) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
@@ -651,20 +655,20 @@ func (s ActivePods) Less(i, j int) bool {
|
||||
return len(s[i].Spec.NodeName) == 0
|
||||
}
|
||||
// 2. PodPending < PodUnknown < PodRunning
|
||||
m := map[api.PodPhase]int{api.PodPending: 0, api.PodUnknown: 1, api.PodRunning: 2}
|
||||
m := map[v1.PodPhase]int{v1.PodPending: 0, v1.PodUnknown: 1, v1.PodRunning: 2}
|
||||
if m[s[i].Status.Phase] != m[s[j].Status.Phase] {
|
||||
return m[s[i].Status.Phase] < m[s[j].Status.Phase]
|
||||
}
|
||||
// 3. Not ready < ready
|
||||
// If only one of the pods is not ready, the not ready one is smaller
|
||||
if api.IsPodReady(s[i]) != api.IsPodReady(s[j]) {
|
||||
return !api.IsPodReady(s[i])
|
||||
if v1.IsPodReady(s[i]) != v1.IsPodReady(s[j]) {
|
||||
return !v1.IsPodReady(s[i])
|
||||
}
|
||||
// TODO: take availability into account when we push minReadySeconds information from deployment into pods,
|
||||
// see https://github.com/kubernetes/kubernetes/issues/22065
|
||||
// 4. Been ready for empty time < less time < more time
|
||||
// If both pods are ready, the latest ready one is smaller
|
||||
if api.IsPodReady(s[i]) && api.IsPodReady(s[j]) && !podReadyTime(s[i]).Equal(podReadyTime(s[j])) {
|
||||
if v1.IsPodReady(s[i]) && v1.IsPodReady(s[j]) && !podReadyTime(s[i]).Equal(podReadyTime(s[j])) {
|
||||
return afterOrZero(podReadyTime(s[i]), podReadyTime(s[j]))
|
||||
}
|
||||
// 5. Pods with containers with higher restart counts < lower restart counts
|
||||
@@ -687,11 +691,11 @@ func afterOrZero(t1, t2 unversioned.Time) bool {
|
||||
return t1.After(t2.Time)
|
||||
}
|
||||
|
||||
func podReadyTime(pod *api.Pod) unversioned.Time {
|
||||
if api.IsPodReady(pod) {
|
||||
func podReadyTime(pod *v1.Pod) unversioned.Time {
|
||||
if v1.IsPodReady(pod) {
|
||||
for _, c := range pod.Status.Conditions {
|
||||
// we only care about pod ready conditions
|
||||
if c.Type == api.PodReady && c.Status == api.ConditionTrue {
|
||||
if c.Type == v1.PodReady && c.Status == v1.ConditionTrue {
|
||||
return c.LastTransitionTime
|
||||
}
|
||||
}
|
||||
@@ -699,7 +703,7 @@ func podReadyTime(pod *api.Pod) unversioned.Time {
|
||||
return unversioned.Time{}
|
||||
}
|
||||
|
||||
func maxContainerRestarts(pod *api.Pod) int {
|
||||
func maxContainerRestarts(pod *v1.Pod) int {
|
||||
maxRestarts := 0
|
||||
for _, c := range pod.Status.ContainerStatuses {
|
||||
maxRestarts = integer.IntMax(maxRestarts, int(c.RestartCount))
|
||||
@@ -708,8 +712,8 @@ func maxContainerRestarts(pod *api.Pod) int {
|
||||
}
|
||||
|
||||
// FilterActivePods returns pods that have not terminated.
|
||||
func FilterActivePods(pods []*api.Pod) []*api.Pod {
|
||||
var result []*api.Pod
|
||||
func FilterActivePods(pods []*v1.Pod) []*v1.Pod {
|
||||
var result []*v1.Pod
|
||||
for _, p := range pods {
|
||||
if IsPodActive(p) {
|
||||
result = append(result, p)
|
||||
@@ -721,9 +725,9 @@ func FilterActivePods(pods []*api.Pod) []*api.Pod {
|
||||
return result
|
||||
}
|
||||
|
||||
func IsPodActive(p *api.Pod) bool {
|
||||
return api.PodSucceeded != p.Status.Phase &&
|
||||
api.PodFailed != p.Status.Phase &&
|
||||
func IsPodActive(p *v1.Pod) bool {
|
||||
return v1.PodSucceeded != p.Status.Phase &&
|
||||
v1.PodFailed != p.Status.Phase &&
|
||||
p.DeletionTimestamp == nil
|
||||
}
|
||||
|
||||
@@ -733,7 +737,7 @@ func FilterActiveReplicaSets(replicaSets []*extensions.ReplicaSet) []*extensions
|
||||
for i := range replicaSets {
|
||||
rs := replicaSets[i]
|
||||
|
||||
if rs != nil && rs.Spec.Replicas > 0 {
|
||||
if rs != nil && *(rs.Spec.Replicas) > 0 {
|
||||
active = append(active, replicaSets[i])
|
||||
}
|
||||
}
|
||||
@@ -744,12 +748,12 @@ func FilterActiveReplicaSets(replicaSets []*extensions.ReplicaSet) []*extensions
|
||||
// It's used so we consistently use the same key scheme in this module.
|
||||
// It does exactly what cache.MetaNamespaceKeyFunc would have done
|
||||
// except there's not possibility for error since we know the exact type.
|
||||
func PodKey(pod *api.Pod) string {
|
||||
func PodKey(pod *v1.Pod) string {
|
||||
return fmt.Sprintf("%v/%v", pod.Namespace, pod.Name)
|
||||
}
|
||||
|
||||
// ControllersByCreationTimestamp sorts a list of ReplicationControllers by creation timestamp, using their names as a tie breaker.
|
||||
type ControllersByCreationTimestamp []*api.ReplicationController
|
||||
type ControllersByCreationTimestamp []*v1.ReplicationController
|
||||
|
||||
func (o ControllersByCreationTimestamp) Len() int { return len(o) }
|
||||
func (o ControllersByCreationTimestamp) Swap(i, j int) { o[i], o[j] = o[j], o[i] }
|
||||
@@ -779,10 +783,10 @@ type ReplicaSetsBySizeOlder []*extensions.ReplicaSet
|
||||
func (o ReplicaSetsBySizeOlder) Len() int { return len(o) }
|
||||
func (o ReplicaSetsBySizeOlder) Swap(i, j int) { o[i], o[j] = o[j], o[i] }
|
||||
func (o ReplicaSetsBySizeOlder) Less(i, j int) bool {
|
||||
if o[i].Spec.Replicas == o[j].Spec.Replicas {
|
||||
if *(o[i].Spec.Replicas) == *(o[j].Spec.Replicas) {
|
||||
return ReplicaSetsByCreationTimestamp(o).Less(i, j)
|
||||
}
|
||||
return o[i].Spec.Replicas > o[j].Spec.Replicas
|
||||
return *(o[i].Spec.Replicas) > *(o[j].Spec.Replicas)
|
||||
}
|
||||
|
||||
// ReplicaSetsBySizeNewer sorts a list of ReplicaSet by size in descending order, using their creation timestamp or name as a tie breaker.
|
||||
@@ -792,8 +796,8 @@ type ReplicaSetsBySizeNewer []*extensions.ReplicaSet
|
||||
func (o ReplicaSetsBySizeNewer) Len() int { return len(o) }
|
||||
func (o ReplicaSetsBySizeNewer) Swap(i, j int) { o[i], o[j] = o[j], o[i] }
|
||||
func (o ReplicaSetsBySizeNewer) Less(i, j int) bool {
|
||||
if o[i].Spec.Replicas == o[j].Spec.Replicas {
|
||||
if *(o[i].Spec.Replicas) == *(o[j].Spec.Replicas) {
|
||||
return ReplicaSetsByCreationTimestamp(o).Less(j, i)
|
||||
}
|
||||
return o[i].Spec.Replicas > o[j].Spec.Replicas
|
||||
return *(o[i].Spec.Replicas) > *(o[j].Spec.Replicas)
|
||||
}
|
||||
|
Reference in New Issue
Block a user