Add Job.spec.completionMode and Job.status.completedIndexes
And IndexedJob feature gate, disabled by default. Update JobDescriber Kubernetes-commit: a1a5868a5ae8c18df39b386d2424ff04c89826fb
This commit is contained in:
parent
e032aa6f92
commit
3af483b7e4
|
@ -2160,6 +2160,9 @@ func describeJob(job *batchv1.Job, events *corev1.EventList) (string, error) {
|
|||
} else {
|
||||
w.Write(LEVEL_0, "Completions:\t<unset>\n")
|
||||
}
|
||||
if job.Spec.CompletionMode != "" {
|
||||
w.Write(LEVEL_0, "Completion Mode:\t%s\n", job.Spec.CompletionMode)
|
||||
}
|
||||
if job.Status.StartTime != nil {
|
||||
w.Write(LEVEL_0, "Start Time:\t%s\n", job.Status.StartTime.Time.Format(time.RFC1123Z))
|
||||
}
|
||||
|
@ -2173,6 +2176,9 @@ func describeJob(job *batchv1.Job, events *corev1.EventList) (string, error) {
|
|||
w.Write(LEVEL_0, "Active Deadline Seconds:\t%ds\n", *job.Spec.ActiveDeadlineSeconds)
|
||||
}
|
||||
w.Write(LEVEL_0, "Pods Statuses:\t%d Running / %d Succeeded / %d Failed\n", job.Status.Active, job.Status.Succeeded, job.Status.Failed)
|
||||
if job.Spec.CompletionMode == batchv1.IndexedCompletion {
|
||||
w.Write(LEVEL_0, "Completed Indexes:\t%s\n", capIndexesListOrNone(job.Status.CompletedIndexes, 50))
|
||||
}
|
||||
DescribePodTemplate(&job.Spec.Template, w)
|
||||
if events != nil {
|
||||
DescribeEvents(events, w)
|
||||
|
@ -2181,6 +2187,22 @@ func describeJob(job *batchv1.Job, events *corev1.EventList) (string, error) {
|
|||
})
|
||||
}
|
||||
|
||||
func capIndexesListOrNone(indexes string, softLimit int) string {
|
||||
if len(indexes) == 0 {
|
||||
return "<none>"
|
||||
}
|
||||
ix := softLimit
|
||||
for ; ix < len(indexes); ix++ {
|
||||
if indexes[ix] == ',' {
|
||||
break
|
||||
}
|
||||
}
|
||||
if ix >= len(indexes) {
|
||||
return indexes
|
||||
}
|
||||
return indexes[:ix+1] + "..."
|
||||
}
|
||||
|
||||
// CronJobDescriber generates information about a cron job and the jobs it has created.
|
||||
type CronJobDescriber struct {
|
||||
client clientset.Interface
|
||||
|
|
|
@ -2062,6 +2062,88 @@ func TestDescribeDeployment(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestDescribeJob(t *testing.T) {
|
||||
cases := map[string]struct {
|
||||
job *batchv1.Job
|
||||
wantCompletedIndexes string
|
||||
}{
|
||||
"not indexed": {
|
||||
job: &batchv1.Job{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "bar",
|
||||
Namespace: "foo",
|
||||
},
|
||||
Spec: batchv1.JobSpec{
|
||||
CompletionMode: batchv1.NonIndexedCompletion,
|
||||
},
|
||||
},
|
||||
},
|
||||
"no indexes": {
|
||||
job: &batchv1.Job{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "bar",
|
||||
Namespace: "foo",
|
||||
},
|
||||
Spec: batchv1.JobSpec{
|
||||
CompletionMode: batchv1.IndexedCompletion,
|
||||
},
|
||||
},
|
||||
wantCompletedIndexes: "<none>",
|
||||
},
|
||||
"few completed indexes": {
|
||||
job: &batchv1.Job{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "bar",
|
||||
Namespace: "foo",
|
||||
},
|
||||
Spec: batchv1.JobSpec{
|
||||
CompletionMode: batchv1.IndexedCompletion,
|
||||
},
|
||||
Status: batchv1.JobStatus{
|
||||
CompletedIndexes: "0-5,7,9,10,12,13,15,16,18,20,21,23,24,26,27,29,30,32",
|
||||
},
|
||||
},
|
||||
wantCompletedIndexes: "0-5,7,9,10,12,13,15,16,18,20,21,23,24,26,27,29,30,32",
|
||||
},
|
||||
"too many completed indexes": {
|
||||
job: &batchv1.Job{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "bar",
|
||||
Namespace: "foo",
|
||||
},
|
||||
Spec: batchv1.JobSpec{
|
||||
CompletionMode: batchv1.IndexedCompletion,
|
||||
},
|
||||
Status: batchv1.JobStatus{
|
||||
CompletedIndexes: "0-5,7,9,10,12,13,15,16,18,20,21,23,24,26,27,29,30,32-34,36,37",
|
||||
},
|
||||
},
|
||||
wantCompletedIndexes: "0-5,7,9,10,12,13,15,16,18,20,21,23,24,26,27,29,30,32-34,...",
|
||||
},
|
||||
}
|
||||
for name, tc := range cases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
client := &describeClient{
|
||||
T: t,
|
||||
Namespace: tc.job.Namespace,
|
||||
Interface: fake.NewSimpleClientset(tc.job),
|
||||
}
|
||||
describer := JobDescriber{Interface: client}
|
||||
out, err := describer.Describe(tc.job.Namespace, tc.job.Name, DescriberSettings{ShowEvents: true})
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error describing object: %v", err)
|
||||
}
|
||||
if tc.wantCompletedIndexes != "" {
|
||||
if !strings.Contains(out, fmt.Sprintf("Completed Indexes: %s\n", tc.wantCompletedIndexes)) {
|
||||
t.Errorf("Output didn't contain wanted Completed Indexes:\n%s", out)
|
||||
}
|
||||
} else if strings.Contains(out, fmt.Sprintf("Completed Indexes:")) {
|
||||
t.Errorf("Output contains unexpected completed indexes:\n%s", out)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDescribeIngress(t *testing.T) {
|
||||
backendV1beta1 := networkingv1beta1.IngressBackend{
|
||||
ServiceName: "default-backend",
|
||||
|
|
Loading…
Reference in New Issue