1/* 2Copyright 2019 The Kubernetes Authors. 3 4Licensed under the Apache License, Version 2.0 (the "License"); 5you may not use this file except in compliance with the License. 6You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10Unless required by applicable law or agreed to in writing, software 11distributed under the License is distributed on an "AS IS" BASIS, 12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13See the License for the specific language governing permissions and 14limitations under the License. 15*/ 16 17package job 18 19import ( 20 "context" 21 "time" 22 23 batchv1 "k8s.io/api/batch/v1" 24 "k8s.io/api/core/v1" 25 apierrors "k8s.io/apimachinery/pkg/api/errors" 26 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 27 "k8s.io/apimachinery/pkg/util/wait" 28 clientset "k8s.io/client-go/kubernetes" 29 "k8s.io/kubernetes/test/e2e/framework" 30) 31 32// WaitForAllJobPodsRunning wait for all pods for the Job named JobName in namespace ns to become Running. Only use 33// when pods will run for a long time, or it will be racy. 34func WaitForAllJobPodsRunning(c clientset.Interface, ns, jobName string, parallelism int32) error { 35 return wait.Poll(framework.Poll, JobTimeout, func() (bool, error) { 36 pods, err := GetJobPods(c, ns, jobName) 37 if err != nil { 38 return false, err 39 } 40 count := int32(0) 41 for _, p := range pods.Items { 42 if p.Status.Phase == v1.PodRunning { 43 count++ 44 } 45 } 46 return count == parallelism, nil 47 }) 48} 49 50// WaitForJobComplete uses c to wait for completions to complete for the Job jobName in namespace ns. 51func WaitForJobComplete(c clientset.Interface, ns, jobName string, completions int32) error { 52 return wait.Poll(framework.Poll, JobTimeout, func() (bool, error) { 53 curr, err := c.BatchV1().Jobs(ns).Get(context.TODO(), jobName, metav1.GetOptions{}) 54 if err != nil { 55 return false, err 56 } 57 return curr.Status.Succeeded == completions, nil 58 }) 59} 60 61// WaitForJobFinish uses c to wait for the Job jobName in namespace ns to finish (either Failed or Complete). 62func WaitForJobFinish(c clientset.Interface, ns, jobName string) error { 63 return wait.PollImmediate(framework.Poll, JobTimeout, func() (bool, error) { 64 curr, err := c.BatchV1().Jobs(ns).Get(context.TODO(), jobName, metav1.GetOptions{}) 65 if err != nil { 66 return false, err 67 } 68 69 return isJobFinished(curr), nil 70 }) 71} 72 73func isJobFinished(j *batchv1.Job) bool { 74 for _, c := range j.Status.Conditions { 75 if (c.Type == batchv1.JobComplete || c.Type == batchv1.JobFailed) && c.Status == v1.ConditionTrue { 76 return true 77 } 78 } 79 80 return false 81} 82 83// WaitForJobGone uses c to wait for up to timeout for the Job named jobName in namespace ns to be removed. 84func WaitForJobGone(c clientset.Interface, ns, jobName string, timeout time.Duration) error { 85 return wait.Poll(framework.Poll, timeout, func() (bool, error) { 86 _, err := c.BatchV1().Jobs(ns).Get(context.TODO(), jobName, metav1.GetOptions{}) 87 if apierrors.IsNotFound(err) { 88 return true, nil 89 } 90 return false, err 91 }) 92} 93 94// WaitForAllJobPodsGone waits for all pods for the Job named jobName in namespace ns 95// to be deleted. 96func WaitForAllJobPodsGone(c clientset.Interface, ns, jobName string) error { 97 return wait.PollImmediate(framework.Poll, JobTimeout, func() (bool, error) { 98 pods, err := GetJobPods(c, ns, jobName) 99 if err != nil { 100 return false, err 101 } 102 return len(pods.Items) == 0, nil 103 }) 104} 105