wait.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  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 job
  14. import (
  15. "fmt"
  16. "strings"
  17. "time"
  18. batchv1 "k8s.io/api/batch/v1"
  19. "k8s.io/api/core/v1"
  20. "k8s.io/apimachinery/pkg/api/errors"
  21. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  22. "k8s.io/apimachinery/pkg/labels"
  23. "k8s.io/apimachinery/pkg/util/wait"
  24. clientset "k8s.io/client-go/kubernetes"
  25. jobutil "k8s.io/kubernetes/pkg/controller/job"
  26. "k8s.io/kubernetes/test/e2e/framework"
  27. )
  28. // WaitForAllJobPodsRunning wait for all pods for the Job named JobName in namespace ns to become Running. Only use
  29. // when pods will run for a long time, or it will be racy.
  30. func WaitForAllJobPodsRunning(c clientset.Interface, ns, jobName string, parallelism int32) error {
  31. return wait.Poll(framework.Poll, JobTimeout, func() (bool, error) {
  32. pods, err := GetJobPods(c, ns, jobName)
  33. if err != nil {
  34. return false, err
  35. }
  36. count := int32(0)
  37. for _, p := range pods.Items {
  38. if p.Status.Phase == v1.PodRunning {
  39. count++
  40. }
  41. }
  42. return count == parallelism, nil
  43. })
  44. }
  45. // WaitForJobComplete uses c to wait for completions to complete for the Job jobName in namespace ns.
  46. func WaitForJobComplete(c clientset.Interface, ns, jobName string, completions int32) error {
  47. return wait.Poll(framework.Poll, JobTimeout, func() (bool, error) {
  48. curr, err := c.BatchV1().Jobs(ns).Get(jobName, metav1.GetOptions{})
  49. if err != nil {
  50. return false, err
  51. }
  52. return curr.Status.Succeeded == completions, nil
  53. })
  54. }
  55. // WaitForJobFinish uses c to wait for the Job jobName in namespace ns to finish (either Failed or Complete).
  56. func WaitForJobFinish(c clientset.Interface, ns, jobName string) error {
  57. return wait.PollImmediate(framework.Poll, JobTimeout, func() (bool, error) {
  58. curr, err := c.BatchV1().Jobs(ns).Get(jobName, metav1.GetOptions{})
  59. if err != nil {
  60. return false, err
  61. }
  62. return jobutil.IsJobFinished(curr), nil
  63. })
  64. }
  65. // WaitForJobFailure uses c to wait for up to timeout for the Job named jobName in namespace ns to fail.
  66. func WaitForJobFailure(c clientset.Interface, ns, jobName string, timeout time.Duration, reason string) error {
  67. return wait.Poll(framework.Poll, timeout, func() (bool, error) {
  68. curr, err := c.BatchV1().Jobs(ns).Get(jobName, metav1.GetOptions{})
  69. if err != nil {
  70. return false, err
  71. }
  72. for _, c := range curr.Status.Conditions {
  73. if c.Type == batchv1.JobFailed && c.Status == v1.ConditionTrue {
  74. if reason == "" || reason == c.Reason {
  75. return true, nil
  76. }
  77. }
  78. }
  79. return false, nil
  80. })
  81. }
  82. // WaitForJobGone uses c to wait for up to timeout for the Job named jobName in namespace ns to be removed.
  83. func WaitForJobGone(c clientset.Interface, ns, jobName string, timeout time.Duration) error {
  84. return wait.Poll(framework.Poll, timeout, func() (bool, error) {
  85. _, err := c.BatchV1().Jobs(ns).Get(jobName, metav1.GetOptions{})
  86. if errors.IsNotFound(err) {
  87. return true, nil
  88. }
  89. return false, err
  90. })
  91. }
  92. // EnsureAllJobPodsRunning uses c to check in the Job named jobName in ns
  93. // is running, returning an error if the expected parallelism is not
  94. // satisfied.
  95. func EnsureAllJobPodsRunning(c clientset.Interface, ns, jobName string, parallelism int32) error {
  96. label := labels.SelectorFromSet(labels.Set(map[string]string{JobSelectorKey: jobName}))
  97. options := metav1.ListOptions{LabelSelector: label.String()}
  98. pods, err := c.CoreV1().Pods(ns).List(options)
  99. if err != nil {
  100. return err
  101. }
  102. podsSummary := make([]string, 0, parallelism)
  103. count := int32(0)
  104. for _, p := range pods.Items {
  105. if p.Status.Phase == v1.PodRunning {
  106. count++
  107. }
  108. podsSummary = append(podsSummary, fmt.Sprintf("%s (%s: %s)", p.ObjectMeta.Name, p.Status.Phase, p.Status.Message))
  109. }
  110. if count != parallelism {
  111. return fmt.Errorf("job has %d of %d expected running pods: %s", count, parallelism, strings.Join(podsSummary, ", "))
  112. }
  113. return nil
  114. }
  115. // WaitForAllJobPodsGone waits for all pods for the Job named jobName in namespace ns
  116. // to be deleted.
  117. func WaitForAllJobPodsGone(c clientset.Interface, ns, jobName string) error {
  118. return wait.PollImmediate(framework.Poll, JobTimeout, func() (bool, error) {
  119. pods, err := GetJobPods(c, ns, jobName)
  120. if err != nil {
  121. return false, err
  122. }
  123. return len(pods.Items) == 0, nil
  124. })
  125. }
  126. // WaitForJobDeleting uses c to wait for the Job jobName in namespace ns to have
  127. // a non-nil deletionTimestamp (i.e. being deleted).
  128. func WaitForJobDeleting(c clientset.Interface, ns, jobName string) error {
  129. return wait.PollImmediate(framework.Poll, JobTimeout, func() (bool, error) {
  130. curr, err := c.BatchV1().Jobs(ns).Get(jobName, metav1.GetOptions{})
  131. if err != nil {
  132. return false, err
  133. }
  134. return curr.ObjectMeta.DeletionTimestamp != nil, nil
  135. })
  136. }