conditions.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /*
  2. Copyright 2014 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package kubectl
  14. import (
  15. "fmt"
  16. corev1 "k8s.io/api/core/v1"
  17. "k8s.io/apimachinery/pkg/api/errors"
  18. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  19. "k8s.io/apimachinery/pkg/runtime/schema"
  20. "k8s.io/apimachinery/pkg/util/wait"
  21. "k8s.io/apimachinery/pkg/watch"
  22. corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
  23. )
  24. // ControllerHasDesiredReplicas returns a condition that will be true if and only if
  25. // the desired replica count for a controller's ReplicaSelector equals the Replicas count.
  26. func ControllerHasDesiredReplicas(rcClient corev1client.ReplicationControllersGetter, controller *corev1.ReplicationController) wait.ConditionFunc {
  27. // If we're given a controller where the status lags the spec, it either means that the controller is stale,
  28. // or that the rc manager hasn't noticed the update yet. Polling status.Replicas is not safe in the latter case.
  29. desiredGeneration := controller.Generation
  30. return func() (bool, error) {
  31. ctrl, err := rcClient.ReplicationControllers(controller.Namespace).Get(controller.Name, metav1.GetOptions{})
  32. if err != nil {
  33. return false, err
  34. }
  35. // There's a chance a concurrent update modifies the Spec.Replicas causing this check to pass,
  36. // or, after this check has passed, a modification causes the rc manager to create more pods.
  37. // This will not be an issue once we've implemented graceful delete for rcs, but till then
  38. // concurrent stop operations on the same rc might have unintended side effects.
  39. return ctrl.Status.ObservedGeneration >= desiredGeneration && ctrl.Status.Replicas == valOrZero(ctrl.Spec.Replicas), nil
  40. }
  41. }
  42. // ErrPodCompleted is returned by PodRunning or PodContainerRunning to indicate that
  43. // the pod has already reached completed state.
  44. var ErrPodCompleted = fmt.Errorf("pod ran to completion")
  45. // PodCompleted returns true if the pod has run to completion, false if the pod has not yet
  46. // reached running state, or an error in any other case.
  47. func PodCompleted(event watch.Event) (bool, error) {
  48. switch event.Type {
  49. case watch.Deleted:
  50. return false, errors.NewNotFound(schema.GroupResource{Resource: "pods"}, "")
  51. }
  52. switch t := event.Object.(type) {
  53. case *corev1.Pod:
  54. switch t.Status.Phase {
  55. case corev1.PodFailed, corev1.PodSucceeded:
  56. return true, nil
  57. }
  58. }
  59. return false, nil
  60. }
  61. // PodRunningAndReady returns true if the pod is running and ready, false if the pod has not
  62. // yet reached those states, returns ErrPodCompleted if the pod has run to completion, or
  63. // an error in any other case.
  64. func PodRunningAndReady(event watch.Event) (bool, error) {
  65. switch event.Type {
  66. case watch.Deleted:
  67. return false, errors.NewNotFound(schema.GroupResource{Resource: "pods"}, "")
  68. }
  69. switch t := event.Object.(type) {
  70. case *corev1.Pod:
  71. switch t.Status.Phase {
  72. case corev1.PodFailed, corev1.PodSucceeded:
  73. return false, ErrPodCompleted
  74. case corev1.PodRunning:
  75. conditions := t.Status.Conditions
  76. if conditions == nil {
  77. return false, nil
  78. }
  79. for i := range conditions {
  80. if conditions[i].Type == corev1.PodReady &&
  81. conditions[i].Status == corev1.ConditionTrue {
  82. return true, nil
  83. }
  84. }
  85. }
  86. }
  87. return false, nil
  88. }