Update ingress godeps
This commit is contained in:
parent
d43021b3f1
commit
28db8fb16d
1068 changed files with 461467 additions and 117300 deletions
144
vendor/k8s.io/kubernetes/pkg/controller/controller_ref_manager.go
generated
vendored
Normal file
144
vendor/k8s.io/kubernetes/pkg/controller/controller_ref_manager.go
generated
vendored
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/errors"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
)
|
||||
|
||||
type PodControllerRefManager struct {
|
||||
podControl PodControlInterface
|
||||
controllerObject api.ObjectMeta
|
||||
controllerSelector labels.Selector
|
||||
controllerKind unversioned.GroupVersionKind
|
||||
}
|
||||
|
||||
// NewPodControllerRefManager returns a PodControllerRefManager that exposes
|
||||
// methods to manage the controllerRef of pods.
|
||||
func NewPodControllerRefManager(
|
||||
podControl PodControlInterface,
|
||||
controllerObject api.ObjectMeta,
|
||||
controllerSelector labels.Selector,
|
||||
controllerKind unversioned.GroupVersionKind,
|
||||
) *PodControllerRefManager {
|
||||
return &PodControllerRefManager{podControl, controllerObject, controllerSelector, controllerKind}
|
||||
}
|
||||
|
||||
// Classify first filters out inactive pods, then it classify the remaining pods
|
||||
// into three categories: 1. matchesAndControlled are the pods whose labels
|
||||
// match the selector of the RC, and have a controllerRef pointing to the
|
||||
// controller 2. matchesNeedsController are the pods whose labels match the RC,
|
||||
// but don't have a controllerRef. (Pods with matching labels but with a
|
||||
// controllerRef pointing to other object are ignored) 3. controlledDoesNotMatch
|
||||
// are the pods that have a controllerRef pointing to the controller, but their
|
||||
// labels no longer match the selector.
|
||||
func (m *PodControllerRefManager) Classify(pods []*api.Pod) (
|
||||
matchesAndControlled []*api.Pod,
|
||||
matchesNeedsController []*api.Pod,
|
||||
controlledDoesNotMatch []*api.Pod) {
|
||||
for i := range pods {
|
||||
pod := pods[i]
|
||||
if !IsPodActive(pod) {
|
||||
glog.V(4).Infof("Ignoring inactive pod %v/%v in state %v, deletion time %v",
|
||||
pod.Namespace, pod.Name, pod.Status.Phase, pod.DeletionTimestamp)
|
||||
continue
|
||||
}
|
||||
controllerRef := getControllerOf(pod.ObjectMeta)
|
||||
if controllerRef != nil {
|
||||
if controllerRef.UID == m.controllerObject.UID {
|
||||
// already controlled
|
||||
if m.controllerSelector.Matches(labels.Set(pod.Labels)) {
|
||||
matchesAndControlled = append(matchesAndControlled, pod)
|
||||
} else {
|
||||
controlledDoesNotMatch = append(controlledDoesNotMatch, pod)
|
||||
}
|
||||
} else {
|
||||
// ignoring the pod controlled by other controller
|
||||
glog.V(4).Infof("Ignoring pod %v/%v, it's owned by [%s/%s, name: %s, uid: %s]",
|
||||
pod.Namespace, pod.Name, controllerRef.APIVersion, controllerRef.Kind, controllerRef.Name, controllerRef.UID)
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
if !m.controllerSelector.Matches(labels.Set(pod.Labels)) {
|
||||
continue
|
||||
}
|
||||
matchesNeedsController = append(matchesNeedsController, pod)
|
||||
}
|
||||
}
|
||||
return matchesAndControlled, matchesNeedsController, controlledDoesNotMatch
|
||||
}
|
||||
|
||||
// getControllerOf returns the controllerRef if controllee has a controller,
|
||||
// otherwise returns nil.
|
||||
func getControllerOf(controllee api.ObjectMeta) *api.OwnerReference {
|
||||
for _, owner := range controllee.OwnerReferences {
|
||||
// controlled by other controller
|
||||
if owner.Controller != nil && *owner.Controller == true {
|
||||
return &owner
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AdoptPod sends a patch to take control of the pod. It returns the error if
|
||||
// the patching fails.
|
||||
func (m *PodControllerRefManager) AdoptPod(pod *api.Pod) error {
|
||||
// we should not adopt any pods if the controller is about to be deleted
|
||||
if m.controllerObject.DeletionTimestamp != nil {
|
||||
return fmt.Errorf("cancel the adopt attempt for pod %s because the controlller is being deleted",
|
||||
strings.Join([]string{pod.Namespace, pod.Name, string(pod.UID)}, "_"))
|
||||
}
|
||||
addControllerPatch := fmt.Sprintf(
|
||||
`{"metadata":{"ownerReferences":[{"apiVersion":"%s","kind":"%s","name":"%s","uid":"%s","controller":true}],"uid":"%s"}}`,
|
||||
m.controllerKind.GroupVersion(), m.controllerKind.Kind,
|
||||
m.controllerObject.Name, m.controllerObject.UID, pod.UID)
|
||||
return m.podControl.PatchPod(pod.Namespace, pod.Name, []byte(addControllerPatch))
|
||||
}
|
||||
|
||||
// ReleasePod sends a patch to free the pod from the control of the controller.
|
||||
// It returns the error if the patching fails. 404 and 422 errors are ignored.
|
||||
func (m *PodControllerRefManager) ReleasePod(pod *api.Pod) error {
|
||||
glog.V(2).Infof("patching pod %s_%s to remove its controllerRef to %s/%s:%s",
|
||||
pod.Namespace, pod.Name, m.controllerKind.GroupVersion(), m.controllerKind.Kind, m.controllerObject.Name)
|
||||
deleteOwnerRefPatch := fmt.Sprintf(`{"metadata":{"ownerReferences":[{"$patch":"delete","uid":"%s"}],"uid":"%s"}}`, m.controllerObject.UID, pod.UID)
|
||||
err := m.podControl.PatchPod(pod.Namespace, pod.Name, []byte(deleteOwnerRefPatch))
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
// If the pod no longer exists, ignore it.
|
||||
return nil
|
||||
}
|
||||
if errors.IsInvalid(err) {
|
||||
// Invalid error will be returned in two cases: 1. the pod
|
||||
// has no owner reference, 2. the uid of the pod doesn't
|
||||
// match, which means the pod is deleted and then recreated.
|
||||
// In both cases, the error can be ignored.
|
||||
|
||||
// TODO: If the pod has owner references, but none of them
|
||||
// has the owner.UID, server will silently ignore the patch.
|
||||
// Investigate why.
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
102
vendor/k8s.io/kubernetes/pkg/controller/controller_utils.go
generated
vendored
102
vendor/k8s.io/kubernetes/pkg/controller/controller_utils.go
generated
vendored
|
|
@ -34,7 +34,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/controller/framework"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/util"
|
||||
"k8s.io/kubernetes/pkg/util/clock"
|
||||
"k8s.io/kubernetes/pkg/util/integer"
|
||||
"k8s.io/kubernetes/pkg/util/sets"
|
||||
)
|
||||
|
|
@ -167,12 +167,12 @@ func (r *ControllerExpectations) SatisfiedExpectations(controllerKey string) boo
|
|||
// TODO: Make this possible to disable in tests.
|
||||
// TODO: Support injection of clock.
|
||||
func (exp *ControlleeExpectations) isExpired() bool {
|
||||
return util.RealClock{}.Since(exp.timestamp) > ExpectationsTimeout
|
||||
return clock.RealClock{}.Since(exp.timestamp) > ExpectationsTimeout
|
||||
}
|
||||
|
||||
// SetExpectations registers new expectations for the given controller. Forgets existing expectations.
|
||||
func (r *ControllerExpectations) SetExpectations(controllerKey string, add, del int) error {
|
||||
exp := &ControlleeExpectations{add: int64(add), del: int64(del), key: controllerKey, timestamp: util.RealClock{}.Now()}
|
||||
exp := &ControlleeExpectations{add: int64(add), del: int64(del), key: controllerKey, timestamp: clock.RealClock{}.Now()}
|
||||
glog.V(4).Infof("Setting expectations %#v", exp)
|
||||
return r.Add(exp)
|
||||
}
|
||||
|
|
@ -190,7 +190,7 @@ func (r *ControllerExpectations) LowerExpectations(controllerKey string, add, de
|
|||
if exp, exists, err := r.GetExpectations(controllerKey); err == nil && exists {
|
||||
exp.Add(int64(-add), int64(-del))
|
||||
// The expectations might've been modified since the update on the previous line.
|
||||
glog.V(4).Infof("Lowered expectations %+v", exp)
|
||||
glog.V(4).Infof("Lowered expectations %#v", exp)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -199,11 +199,11 @@ func (r *ControllerExpectations) RaiseExpectations(controllerKey string, add, de
|
|||
if exp, exists, err := r.GetExpectations(controllerKey); err == nil && exists {
|
||||
exp.Add(int64(add), int64(del))
|
||||
// The expectations might've been modified since the update on the previous line.
|
||||
glog.V(4).Infof("Raised expectations %+v", exp)
|
||||
glog.V(4).Infof("Raised expectations %#v", exp)
|
||||
}
|
||||
}
|
||||
|
||||
// CreationObserved atomically decrements the `add` expecation count of the given controller.
|
||||
// CreationObserved atomically decrements the `add` expectation count of the given controller.
|
||||
func (r *ControllerExpectations) CreationObserved(controllerKey string) {
|
||||
r.LowerExpectations(controllerKey, 1, 0)
|
||||
}
|
||||
|
|
@ -349,8 +349,12 @@ type PodControlInterface interface {
|
|||
CreatePods(namespace string, template *api.PodTemplateSpec, object runtime.Object) error
|
||||
// CreatePodsOnNode creates a new pod accorting to the spec on the specified node.
|
||||
CreatePodsOnNode(nodeName, namespace string, template *api.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
|
||||
// DeletePod deletes the pod identified by podID.
|
||||
DeletePod(namespace string, podID string, object runtime.Object) error
|
||||
// PatchPod patches the pod.
|
||||
PatchPod(namespace, name string, data []byte) error
|
||||
}
|
||||
|
||||
// RealPodControl is the default implementation of PodControlInterface.
|
||||
|
|
@ -404,14 +408,35 @@ func getPodsPrefix(controllerName string) string {
|
|||
}
|
||||
|
||||
func (r RealPodControl) CreatePods(namespace string, template *api.PodTemplateSpec, object runtime.Object) error {
|
||||
return r.createPods("", namespace, template, object)
|
||||
return r.createPods("", namespace, template, object, nil)
|
||||
}
|
||||
|
||||
func (r RealPodControl) CreatePodsWithControllerRef(namespace string, template *api.PodTemplateSpec, controllerObject runtime.Object, controllerRef *api.OwnerReference) error {
|
||||
if controllerRef == nil {
|
||||
return fmt.Errorf("controllerRef is nil")
|
||||
}
|
||||
if len(controllerRef.APIVersion) == 0 {
|
||||
return fmt.Errorf("controllerRef has empty APIVersion")
|
||||
}
|
||||
if len(controllerRef.Kind) == 0 {
|
||||
return fmt.Errorf("controllerRef has empty Kind")
|
||||
}
|
||||
if controllerRef.Controller == nil || *controllerRef.Controller != true {
|
||||
return fmt.Errorf("controllerRef.Controller is not set")
|
||||
}
|
||||
return r.createPods("", namespace, template, controllerObject, controllerRef)
|
||||
}
|
||||
|
||||
func (r RealPodControl) CreatePodsOnNode(nodeName, namespace string, template *api.PodTemplateSpec, object runtime.Object) error {
|
||||
return r.createPods(nodeName, namespace, template, object)
|
||||
return r.createPods(nodeName, namespace, template, object, nil)
|
||||
}
|
||||
|
||||
func GetPodFromTemplate(template *api.PodTemplateSpec, parentObject runtime.Object) (*api.Pod, error) {
|
||||
func (r RealPodControl) PatchPod(namespace, name string, data []byte) error {
|
||||
_, err := r.KubeClient.Core().Pods(namespace).Patch(name, api.StrategicMergePatchType, data)
|
||||
return err
|
||||
}
|
||||
|
||||
func GetPodFromTemplate(template *api.PodTemplateSpec, parentObject runtime.Object, controllerRef *api.OwnerReference) (*api.Pod, error) {
|
||||
desiredLabels := getPodsLabelSet(template)
|
||||
desiredAnnotations, err := getPodsAnnotationSet(template, parentObject)
|
||||
if err != nil {
|
||||
|
|
@ -430,21 +455,24 @@ func GetPodFromTemplate(template *api.PodTemplateSpec, parentObject runtime.Obje
|
|||
GenerateName: prefix,
|
||||
},
|
||||
}
|
||||
if err := api.Scheme.Convert(&template.Spec, &pod.Spec); err != nil {
|
||||
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)
|
||||
}
|
||||
return pod, nil
|
||||
}
|
||||
|
||||
func (r RealPodControl) createPods(nodeName, namespace string, template *api.PodTemplateSpec, object runtime.Object) error {
|
||||
pod, err := GetPodFromTemplate(template, object)
|
||||
func (r RealPodControl) createPods(nodeName, namespace string, template *api.PodTemplateSpec, object runtime.Object, controllerRef *api.OwnerReference) error {
|
||||
pod, err := GetPodFromTemplate(template, object, controllerRef)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(nodeName) != 0 {
|
||||
pod.Spec.NodeName = nodeName
|
||||
}
|
||||
if labels.Set(pod.Labels).AsSelector().Empty() {
|
||||
if labels.Set(pod.Labels).AsSelectorPreValidated().Empty() {
|
||||
return fmt.Errorf("unable to create pods, no labels")
|
||||
}
|
||||
if newPod, err := r.KubeClient.Core().Pods(namespace).Create(pod); err != nil {
|
||||
|
|
@ -479,40 +507,63 @@ func (r RealPodControl) DeletePod(namespace string, podID string, object runtime
|
|||
|
||||
type FakePodControl struct {
|
||||
sync.Mutex
|
||||
Templates []api.PodTemplateSpec
|
||||
DeletePodName []string
|
||||
Err error
|
||||
Templates []api.PodTemplateSpec
|
||||
ControllerRefs []api.OwnerReference
|
||||
DeletePodName []string
|
||||
Patches [][]byte
|
||||
Err error
|
||||
}
|
||||
|
||||
var _ PodControlInterface = &FakePodControl{}
|
||||
|
||||
func (f *FakePodControl) CreatePods(namespace string, spec *api.PodTemplateSpec, object runtime.Object) error {
|
||||
func (f *FakePodControl) PatchPod(namespace, name string, data []byte) error {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.Patches = append(f.Patches, data)
|
||||
if f.Err != nil {
|
||||
return f.Err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FakePodControl) CreatePods(namespace string, spec *api.PodTemplateSpec, object runtime.Object) error {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.Templates = append(f.Templates, *spec)
|
||||
if f.Err != nil {
|
||||
return f.Err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FakePodControl) CreatePodsWithControllerRef(namespace string, spec *api.PodTemplateSpec, object runtime.Object, controllerRef *api.OwnerReference) error {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.Templates = append(f.Templates, *spec)
|
||||
f.ControllerRefs = append(f.ControllerRefs, *controllerRef)
|
||||
if f.Err != nil {
|
||||
return f.Err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FakePodControl) CreatePodsOnNode(nodeName, namespace string, template *api.PodTemplateSpec, object runtime.Object) error {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.Templates = append(f.Templates, *template)
|
||||
if f.Err != nil {
|
||||
return f.Err
|
||||
}
|
||||
f.Templates = append(f.Templates, *template)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FakePodControl) DeletePod(namespace string, podID string, object runtime.Object) error {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.DeletePodName = append(f.DeletePodName, podID)
|
||||
if f.Err != nil {
|
||||
return f.Err
|
||||
}
|
||||
f.DeletePodName = append(f.DeletePodName, podID)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -521,6 +572,8 @@ func (f *FakePodControl) Clear() {
|
|||
defer f.Unlock()
|
||||
f.DeletePodName = []string{}
|
||||
f.Templates = []api.PodTemplateSpec{}
|
||||
f.ControllerRefs = []api.OwnerReference{}
|
||||
f.Patches = [][]byte{}
|
||||
}
|
||||
|
||||
// ByLogging allows custom sorting of pods so the best one can be picked for getting its logs.
|
||||
|
|
@ -630,12 +683,11 @@ func maxContainerRestarts(pod *api.Pod) int {
|
|||
}
|
||||
|
||||
// FilterActivePods returns pods that have not terminated.
|
||||
func FilterActivePods(pods []api.Pod) []*api.Pod {
|
||||
func FilterActivePods(pods []*api.Pod) []*api.Pod {
|
||||
var result []*api.Pod
|
||||
for i := range pods {
|
||||
p := pods[i]
|
||||
for _, p := range pods {
|
||||
if IsPodActive(p) {
|
||||
result = append(result, &p)
|
||||
result = append(result, p)
|
||||
} else {
|
||||
glog.V(4).Infof("Ignoring inactive pod %v/%v in state %v, deletion time %v",
|
||||
p.Namespace, p.Name, p.Status.Phase, p.DeletionTimestamp)
|
||||
|
|
@ -644,7 +696,7 @@ func FilterActivePods(pods []api.Pod) []*api.Pod {
|
|||
return result
|
||||
}
|
||||
|
||||
func IsPodActive(p api.Pod) bool {
|
||||
func IsPodActive(p *api.Pod) bool {
|
||||
return api.PodSucceeded != p.Status.Phase &&
|
||||
api.PodFailed != p.Status.Phase &&
|
||||
p.DeletionTimestamp == nil
|
||||
|
|
@ -666,7 +718,7 @@ func FilterActiveReplicaSets(replicaSets []*extensions.ReplicaSet) []*extensions
|
|||
// PodKey returns a key unique to the given pod within a cluster.
|
||||
// It's used so we consistently use the same key scheme in this module.
|
||||
// It does exactly what cache.MetaNamespaceKeyFunc would have done
|
||||
// expcept there's not possibility for error since we know the exact type.
|
||||
// except there's not possibility for error since we know the exact type.
|
||||
func PodKey(pod *api.Pod) string {
|
||||
return fmt.Sprintf("%v/%v", pod.Namespace, pod.Name)
|
||||
}
|
||||
|
|
|
|||
54
vendor/k8s.io/kubernetes/pkg/controller/deployment/util/deployment_util.go
generated
vendored
54
vendor/k8s.io/kubernetes/pkg/controller/deployment/util/deployment_util.go
generated
vendored
|
|
@ -247,6 +247,14 @@ func MaxUnavailable(deployment extensions.Deployment) int32 {
|
|||
return maxUnavailable
|
||||
}
|
||||
|
||||
// MinAvailable returns the minimum vailable pods of a given deployment
|
||||
func MinAvailable(deployment *extensions.Deployment) int32 {
|
||||
if !IsRollingUpdate(deployment) {
|
||||
return int32(0)
|
||||
}
|
||||
return deployment.Spec.Replicas - MaxUnavailable(*deployment)
|
||||
}
|
||||
|
||||
// MaxSurge returns the maximum surge pods a rolling deployment can take.
|
||||
func MaxSurge(deployment extensions.Deployment) int32 {
|
||||
if !IsRollingUpdate(&deployment) {
|
||||
|
|
@ -402,17 +410,26 @@ func ListPods(deployment *extensions.Deployment, getPodList podListFunc) (*api.P
|
|||
// (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
|
||||
func equalIgnoreHash(template1, template2 api.PodTemplateSpec) (bool, error) {
|
||||
// First, compare template.Labels (ignoring hash)
|
||||
labels1, labels2 := template1.Labels, template2.Labels
|
||||
// The podTemplateSpec must have a non-empty label so that label selectors can find them.
|
||||
// This is checked by validation (of resources contain a podTemplateSpec).
|
||||
if len(template1.Labels) == 0 || len(template2.Labels) == 0 {
|
||||
if len(labels1) == 0 || len(labels2) == 0 {
|
||||
return false, fmt.Errorf("Unexpected empty labels found in given template")
|
||||
}
|
||||
hash1 := template1.Labels[extensions.DefaultDeploymentUniqueLabelKey]
|
||||
hash2 := template2.Labels[extensions.DefaultDeploymentUniqueLabelKey]
|
||||
// compare equality ignoring pod-template-hash
|
||||
template1.Labels[extensions.DefaultDeploymentUniqueLabelKey] = hash2
|
||||
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, nil
|
||||
}
|
||||
}
|
||||
|
||||
// Then, compare the templates without comparing their labels
|
||||
template1.Labels, template2.Labels = nil, nil
|
||||
result := api.Semantic.DeepEqual(template1, template2)
|
||||
template1.Labels[extensions.DefaultDeploymentUniqueLabelKey] = hash1
|
||||
return result, nil
|
||||
}
|
||||
|
||||
|
|
@ -585,7 +602,7 @@ func GetAvailablePodsForReplicaSets(c clientset.Interface, deployment *extension
|
|||
// CountAvailablePodsForReplicaSets returns the number of available pods corresponding to the given pod list and replica sets.
|
||||
// Note that the input pod list should be the pods targeted by the deployment of input replica sets.
|
||||
func CountAvailablePodsForReplicaSets(podList *api.PodList, rss []*extensions.ReplicaSet, minReadySeconds int32) (int32, error) {
|
||||
rsPods, err := filterPodsMatchingReplicaSets(rss, podList)
|
||||
rsPods, err := filterPodsMatchingReplicaSets(rss, podList, minReadySeconds)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
|
@ -593,18 +610,19 @@ func CountAvailablePodsForReplicaSets(podList *api.PodList, rss []*extensions.Re
|
|||
}
|
||||
|
||||
// GetAvailablePodsForDeployment returns the number of available pods (listed from clientset) corresponding to the given deployment.
|
||||
func GetAvailablePodsForDeployment(c clientset.Interface, deployment *extensions.Deployment, minReadySeconds int32) (int32, error) {
|
||||
func GetAvailablePodsForDeployment(c clientset.Interface, deployment *extensions.Deployment) (int32, error) {
|
||||
podList, err := listPods(deployment, c)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return countAvailablePods(podList.Items, minReadySeconds), nil
|
||||
return countAvailablePods(podList.Items, deployment.Spec.MinReadySeconds), nil
|
||||
}
|
||||
|
||||
func countAvailablePods(pods []api.Pod, minReadySeconds int32) int32 {
|
||||
availablePodCount := int32(0)
|
||||
for _, pod := range pods {
|
||||
// TODO: Make the time.Now() as argument to allow unit test this.
|
||||
// FIXME: avoid using time.Now
|
||||
if IsPodAvailable(&pod, minReadySeconds, time.Now()) {
|
||||
glog.V(4).Infof("Pod %s/%s is available.", pod.Namespace, pod.Name)
|
||||
availablePodCount++
|
||||
|
|
@ -615,7 +633,7 @@ func countAvailablePods(pods []api.Pod, minReadySeconds int32) int32 {
|
|||
|
||||
// IsPodAvailable return true if the pod is available.
|
||||
func IsPodAvailable(pod *api.Pod, minReadySeconds int32, now time.Time) bool {
|
||||
if !controller.IsPodActive(*pod) {
|
||||
if !controller.IsPodActive(pod) {
|
||||
return false
|
||||
}
|
||||
// Check if we've passed minReadySeconds since LastTransitionTime
|
||||
|
|
@ -623,6 +641,7 @@ func IsPodAvailable(pod *api.Pod, minReadySeconds int32, now time.Time) bool {
|
|||
for _, c := range pod.Status.Conditions {
|
||||
// we only care about pod ready conditions
|
||||
if c.Type == api.PodReady && c.Status == api.ConditionTrue {
|
||||
glog.V(4).Infof("Comparing pod %s/%s ready condition last transition time %s + minReadySeconds %d with now %s.", pod.Namespace, pod.Name, c.LastTransitionTime.String(), minReadySeconds, now.String())
|
||||
// 2 cases that this ready condition is valid (passed minReadySeconds, i.e. the pod is available):
|
||||
// 1. minReadySeconds == 0, or
|
||||
// 2. LastTransitionTime (is set) + minReadySeconds (>0) < current time
|
||||
|
|
@ -636,8 +655,8 @@ func IsPodAvailable(pod *api.Pod, minReadySeconds int32, now time.Time) bool {
|
|||
}
|
||||
|
||||
// filterPodsMatchingReplicaSets filters the given pod list and only return the ones targeted by the input replicasets
|
||||
func filterPodsMatchingReplicaSets(replicaSets []*extensions.ReplicaSet, podList *api.PodList) ([]api.Pod, error) {
|
||||
rsPods := []api.Pod{}
|
||||
func filterPodsMatchingReplicaSets(replicaSets []*extensions.ReplicaSet, podList *api.PodList, minReadySeconds int32) ([]api.Pod, error) {
|
||||
allRSPods := []api.Pod{}
|
||||
for _, rs := range replicaSets {
|
||||
matchingFunc, err := rsutil.MatchingPodsFunc(rs)
|
||||
if err != nil {
|
||||
|
|
@ -646,9 +665,16 @@ func filterPodsMatchingReplicaSets(replicaSets []*extensions.ReplicaSet, podList
|
|||
if matchingFunc == nil {
|
||||
continue
|
||||
}
|
||||
rsPods = append(rsPods, podutil.Filter(podList, matchingFunc)...)
|
||||
rsPods := podutil.Filter(podList, matchingFunc)
|
||||
avaPodsCount := countAvailablePods(rsPods, minReadySeconds)
|
||||
if avaPodsCount > rs.Spec.Replicas {
|
||||
msg := fmt.Sprintf("Found %s/%s with %d available pods, more than its spec replicas %d", rs.Namespace, rs.Name, avaPodsCount, rs.Spec.Replicas)
|
||||
glog.Errorf("ERROR: %s", msg)
|
||||
return nil, fmt.Errorf(msg)
|
||||
}
|
||||
allRSPods = append(allRSPods, podutil.Filter(podList, matchingFunc)...)
|
||||
}
|
||||
return rsPods, nil
|
||||
return allRSPods, nil
|
||||
}
|
||||
|
||||
// Revision returns the revision number of the input replica set
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue