wait.go 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /*
  2. Copyright 2019 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 apps
  14. import (
  15. appsv1 "k8s.io/api/apps/v1"
  16. v1 "k8s.io/api/core/v1"
  17. clientset "k8s.io/client-go/kubernetes"
  18. podutil "k8s.io/kubernetes/pkg/api/v1/pod"
  19. "k8s.io/kubernetes/test/e2e/framework"
  20. e2esset "k8s.io/kubernetes/test/e2e/framework/statefulset"
  21. )
  22. // waitForPartitionedRollingUpdate waits for all Pods in set to exist and have the correct revision. set must have
  23. // a RollingUpdateStatefulSetStrategyType with a non-nil RollingUpdate and Partition. All Pods with ordinals less
  24. // than or equal to the Partition are expected to be at set's current revision. All other Pods are expected to be
  25. // at its update revision.
  26. func waitForPartitionedRollingUpdate(c clientset.Interface, set *appsv1.StatefulSet) (*appsv1.StatefulSet, *v1.PodList) {
  27. var pods *v1.PodList
  28. if set.Spec.UpdateStrategy.Type != appsv1.RollingUpdateStatefulSetStrategyType {
  29. framework.Failf("StatefulSet %s/%s attempt to wait for partitioned update with updateStrategy %s",
  30. set.Namespace,
  31. set.Name,
  32. set.Spec.UpdateStrategy.Type)
  33. }
  34. if set.Spec.UpdateStrategy.RollingUpdate == nil || set.Spec.UpdateStrategy.RollingUpdate.Partition == nil {
  35. framework.Failf("StatefulSet %s/%s attempt to wait for partitioned update with nil RollingUpdate or nil Partition",
  36. set.Namespace,
  37. set.Name)
  38. }
  39. e2esset.WaitForState(c, set, func(set2 *appsv1.StatefulSet, pods2 *v1.PodList) (bool, error) {
  40. set = set2
  41. pods = pods2
  42. partition := int(*set.Spec.UpdateStrategy.RollingUpdate.Partition)
  43. if len(pods.Items) < int(*set.Spec.Replicas) {
  44. return false, nil
  45. }
  46. if partition <= 0 && set.Status.UpdateRevision != set.Status.CurrentRevision {
  47. framework.Logf("Waiting for StatefulSet %s/%s to complete update",
  48. set.Namespace,
  49. set.Name,
  50. )
  51. e2esset.SortStatefulPods(pods)
  52. for i := range pods.Items {
  53. if pods.Items[i].Labels[appsv1.StatefulSetRevisionLabel] != set.Status.UpdateRevision {
  54. framework.Logf("Waiting for Pod %s/%s to have revision %s update revision %s",
  55. pods.Items[i].Namespace,
  56. pods.Items[i].Name,
  57. set.Status.UpdateRevision,
  58. pods.Items[i].Labels[appsv1.StatefulSetRevisionLabel])
  59. }
  60. }
  61. return false, nil
  62. }
  63. for i := int(*set.Spec.Replicas) - 1; i >= partition; i-- {
  64. if pods.Items[i].Labels[appsv1.StatefulSetRevisionLabel] != set.Status.UpdateRevision {
  65. framework.Logf("Waiting for Pod %s/%s to have revision %s update revision %s",
  66. pods.Items[i].Namespace,
  67. pods.Items[i].Name,
  68. set.Status.UpdateRevision,
  69. pods.Items[i].Labels[appsv1.StatefulSetRevisionLabel])
  70. return false, nil
  71. }
  72. }
  73. return true, nil
  74. })
  75. return set, pods
  76. }
  77. // waitForStatus waits for the StatefulSetStatus's ObservedGeneration to be greater than or equal to set's Generation.
  78. // The returned StatefulSet contains such a StatefulSetStatus
  79. func waitForStatus(c clientset.Interface, set *appsv1.StatefulSet) *appsv1.StatefulSet {
  80. e2esset.WaitForState(c, set, func(set2 *appsv1.StatefulSet, pods *v1.PodList) (bool, error) {
  81. if set2.Status.ObservedGeneration >= set.Generation {
  82. set = set2
  83. return true, nil
  84. }
  85. return false, nil
  86. })
  87. return set
  88. }
  89. // waitForPodNotReady waits for the Pod named podName in set to exist and to not have a Ready condition.
  90. func waitForPodNotReady(c clientset.Interface, set *appsv1.StatefulSet, podName string) (*appsv1.StatefulSet, *v1.PodList) {
  91. var pods *v1.PodList
  92. e2esset.WaitForState(c, set, func(set2 *appsv1.StatefulSet, pods2 *v1.PodList) (bool, error) {
  93. set = set2
  94. pods = pods2
  95. for i := range pods.Items {
  96. if pods.Items[i].Name == podName {
  97. return !podutil.IsPodReady(&pods.Items[i]), nil
  98. }
  99. }
  100. return false, nil
  101. })
  102. return set, pods
  103. }
  104. // waitForRollingUpdate waits for all Pods in set to exist and have the correct revision and for the RollingUpdate to
  105. // complete. set must have a RollingUpdateStatefulSetStrategyType.
  106. func waitForRollingUpdate(c clientset.Interface, set *appsv1.StatefulSet) (*appsv1.StatefulSet, *v1.PodList) {
  107. var pods *v1.PodList
  108. if set.Spec.UpdateStrategy.Type != appsv1.RollingUpdateStatefulSetStrategyType {
  109. framework.Failf("StatefulSet %s/%s attempt to wait for rolling update with updateStrategy %s",
  110. set.Namespace,
  111. set.Name,
  112. set.Spec.UpdateStrategy.Type)
  113. }
  114. e2esset.WaitForState(c, set, func(set2 *appsv1.StatefulSet, pods2 *v1.PodList) (bool, error) {
  115. set = set2
  116. pods = pods2
  117. if len(pods.Items) < int(*set.Spec.Replicas) {
  118. return false, nil
  119. }
  120. if set.Status.UpdateRevision != set.Status.CurrentRevision {
  121. framework.Logf("Waiting for StatefulSet %s/%s to complete update",
  122. set.Namespace,
  123. set.Name,
  124. )
  125. e2esset.SortStatefulPods(pods)
  126. for i := range pods.Items {
  127. if pods.Items[i].Labels[appsv1.StatefulSetRevisionLabel] != set.Status.UpdateRevision {
  128. framework.Logf("Waiting for Pod %s/%s to have revision %s update revision %s",
  129. pods.Items[i].Namespace,
  130. pods.Items[i].Name,
  131. set.Status.UpdateRevision,
  132. pods.Items[i].Labels[appsv1.StatefulSetRevisionLabel])
  133. }
  134. }
  135. return false, nil
  136. }
  137. return true, nil
  138. })
  139. return set, pods
  140. }
  141. // waitForRunningAndNotReady waits for numStatefulPods in ss to be Running and not Ready.
  142. func waitForRunningAndNotReady(c clientset.Interface, numStatefulPods int32, ss *appsv1.StatefulSet) {
  143. e2esset.WaitForRunning(c, numStatefulPods, 0, ss)
  144. }