printers: add status to jobs table

This commit is contained in:
Ivan Valdes 2024-02-16 13:02:23 -08:00
parent 24267f6aa7
commit 8854d360a5
No known key found for this signature in database
GPG Key ID: 4037D37741ED0CC5
2 changed files with 145 additions and 14 deletions

View File

@ -167,6 +167,7 @@ func AddHandlers(h printers.PrintHandler) {
jobColumnDefinitions := []metav1.TableColumnDefinition{ jobColumnDefinitions := []metav1.TableColumnDefinition{
{Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]}, {Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]},
{Name: "Status", Type: "string", Description: "Status of the job."},
{Name: "Completions", Type: "string", Description: batchv1.JobStatus{}.SwaggerDoc()["succeeded"]}, {Name: "Completions", Type: "string", Description: batchv1.JobStatus{}.SwaggerDoc()["succeeded"]},
{Name: "Duration", Type: "string", Description: "Time required to complete the job."}, {Name: "Duration", Type: "string", Description: "Time required to complete the job."},
{Name: "Age", Type: "string", Description: metav1.ObjectMeta{}.SwaggerDoc()["creationTimestamp"]}, {Name: "Age", Type: "string", Description: metav1.ObjectMeta{}.SwaggerDoc()["creationTimestamp"]},
@ -1013,6 +1014,15 @@ func hasPodReadyCondition(conditions []api.PodCondition) bool {
return false return false
} }
func hasJobCondition(conditions []batch.JobCondition, conditionType batch.JobConditionType) bool {
for _, condition := range conditions {
if condition.Type == conditionType {
return condition.Status == api.ConditionTrue
}
}
return false
}
func printPodTemplate(obj *api.PodTemplate, options printers.GenerateOptions) ([]metav1.TableRow, error) { func printPodTemplate(obj *api.PodTemplate, options printers.GenerateOptions) ([]metav1.TableRow, error) {
row := metav1.TableRow{ row := metav1.TableRow{
Object: runtime.RawExtension{Object: obj}, Object: runtime.RawExtension{Object: obj},
@ -1155,8 +1165,22 @@ func printJob(obj *batch.Job, options printers.GenerateOptions) ([]metav1.TableR
default: default:
jobDuration = duration.HumanDuration(obj.Status.CompletionTime.Sub(obj.Status.StartTime.Time)) jobDuration = duration.HumanDuration(obj.Status.CompletionTime.Sub(obj.Status.StartTime.Time))
} }
var status string
if hasJobCondition(obj.Status.Conditions, batch.JobComplete) {
status = "Complete"
} else if hasJobCondition(obj.Status.Conditions, batch.JobFailed) {
status = "Failed"
} else if obj.ObjectMeta.DeletionTimestamp != nil {
status = "Terminating"
} else if hasJobCondition(obj.Status.Conditions, batch.JobSuspended) {
status = "Suspended"
} else if hasJobCondition(obj.Status.Conditions, batch.JobFailureTarget) {
status = "FailureTarget"
} else {
status = "Running"
}
row.Cells = append(row.Cells, obj.Name, completions, jobDuration, translateTimestampSince(obj.CreationTimestamp)) row.Cells = append(row.Cells, obj.Name, status, completions, jobDuration, translateTimestampSince(obj.CreationTimestamp))
if options.Wide { if options.Wide {
names, images := layoutContainerCells(obj.Spec.Template.Spec.Containers) names, images := layoutContainerCells(obj.Spec.Template.Spec.Containers)
row.Cells = append(row.Cells, names, images, metav1.FormatLabelSelector(obj.Spec.Selector)) row.Cells = append(row.Cells, names, images, metav1.FormatLabelSelector(obj.Spec.Selector))

View File

@ -2527,8 +2527,8 @@ func TestPrintJob(t *testing.T) {
}, },
}, },
options: printers.GenerateOptions{}, options: printers.GenerateOptions{},
// Columns: Name, Completions, Duration, Age // Columns: Name, Status, Completions, Duration, Age
expected: []metav1.TableRow{{Cells: []interface{}{"job1", "1/2", "", "0s"}}}, expected: []metav1.TableRow{{Cells: []interface{}{"job1", "Running", "1/2", "", "0s"}}},
}, },
// Generate table rows for Job with generate options "Wide". // Generate table rows for Job with generate options "Wide".
{ {
@ -2560,10 +2560,10 @@ func TestPrintJob(t *testing.T) {
}, },
}, },
options: printers.GenerateOptions{Wide: true}, options: printers.GenerateOptions{Wide: true},
// Columns: Name, Completions, Duration, Age, Containers, Images, Selectors // Columns: Name, Status, Completions, Duration, Age, Containers, Images, Selectors
expected: []metav1.TableRow{ expected: []metav1.TableRow{
{ {
Cells: []interface{}{"job1", "1/2", "", "0s", "fake-job-container1,fake-job-container2", "fake-job-image1,fake-job-image2", "job-label=job-label-value"}, Cells: []interface{}{"job1", "Running", "1/2", "", "0s", "fake-job-container1,fake-job-container2", "fake-job-image1,fake-job-image2", "job-label=job-label-value"},
}, },
}, },
}, },
@ -2582,8 +2582,8 @@ func TestPrintJob(t *testing.T) {
}, },
}, },
options: printers.GenerateOptions{}, options: printers.GenerateOptions{},
// Columns: Name, Completions, Duration, Age // Columns: Name, Status, Completions, Duration, Age
expected: []metav1.TableRow{{Cells: []interface{}{"job2", "0/1", "", "10y"}}}, expected: []metav1.TableRow{{Cells: []interface{}{"job2", "Running", "0/1", "", "10y"}}},
}, },
// Job with duration. // Job with duration.
{ {
@ -2602,8 +2602,8 @@ func TestPrintJob(t *testing.T) {
}, },
}, },
options: printers.GenerateOptions{}, options: printers.GenerateOptions{},
// Columns: Name, Completions, Duration, Age // Columns: Name, Status, Completions, Duration, Age
expected: []metav1.TableRow{{Cells: []interface{}{"job3", "0/1", "30m", "10y"}}}, expected: []metav1.TableRow{{Cells: []interface{}{"job3", "Running", "0/1", "30m", "10y"}}},
}, },
{ {
job: batch.Job{ job: batch.Job{
@ -2620,8 +2620,115 @@ func TestPrintJob(t *testing.T) {
}, },
}, },
options: printers.GenerateOptions{}, options: printers.GenerateOptions{},
// Columns: Name, Completions, Duration, Age // Columns: Name, Status, Completions, Duration, Age
expected: []metav1.TableRow{{Cells: []interface{}{"job4", "0/1", "20m", "10y"}}}, expected: []metav1.TableRow{{Cells: []interface{}{"job4", "Running", "0/1", "20m", "10y"}}},
},
{
job: batch.Job{
ObjectMeta: metav1.ObjectMeta{
Name: "job5",
CreationTimestamp: metav1.Time{Time: time.Now().Add(1.9e9)},
},
Spec: batch.JobSpec{
Completions: nil,
},
Status: batch.JobStatus{
Succeeded: 0,
Conditions: []batch.JobCondition{
{
Type: batch.JobComplete,
Status: api.ConditionTrue,
},
},
},
},
options: printers.GenerateOptions{},
// Columns: Name, Status, Completions, Duration, Age
expected: []metav1.TableRow{{Cells: []interface{}{"job5", "Complete", "0/1", "", "0s"}}},
},
{
job: batch.Job{
ObjectMeta: metav1.ObjectMeta{
Name: "job6",
CreationTimestamp: metav1.Time{Time: time.Now().Add(1.9e9)},
},
Spec: batch.JobSpec{
Completions: nil,
},
Status: batch.JobStatus{
Succeeded: 0,
Conditions: []batch.JobCondition{
{
Type: batch.JobFailed,
Status: api.ConditionTrue,
},
},
},
},
options: printers.GenerateOptions{},
// Columns: Name, Status, Completions, Duration, Age
expected: []metav1.TableRow{{Cells: []interface{}{"job6", "Failed", "0/1", "", "0s"}}},
},
{
job: batch.Job{
ObjectMeta: metav1.ObjectMeta{
Name: "job7",
CreationTimestamp: metav1.Time{Time: time.Now().Add(1.9e9)},
},
Spec: batch.JobSpec{
Completions: nil,
},
Status: batch.JobStatus{
Succeeded: 0,
Conditions: []batch.JobCondition{
{
Type: batch.JobSuspended,
Status: api.ConditionTrue,
},
},
},
},
options: printers.GenerateOptions{},
// Columns: Name, Status, Completions, Duration, Age
expected: []metav1.TableRow{{Cells: []interface{}{"job7", "Suspended", "0/1", "", "0s"}}},
},
{
job: batch.Job{
ObjectMeta: metav1.ObjectMeta{
Name: "job8",
CreationTimestamp: metav1.Time{Time: time.Now().Add(1.9e9)},
},
Spec: batch.JobSpec{
Completions: nil,
},
Status: batch.JobStatus{
Succeeded: 0,
Conditions: []batch.JobCondition{
{
Type: batch.JobFailureTarget,
Status: api.ConditionTrue,
},
},
},
},
options: printers.GenerateOptions{},
// Columns: Name, Status, Completions, Duration, Age
expected: []metav1.TableRow{{Cells: []interface{}{"job8", "FailureTarget", "0/1", "", "0s"}}},
},
{
job: batch.Job{
ObjectMeta: metav1.ObjectMeta{
Name: "job9",
CreationTimestamp: metav1.Time{Time: time.Now().Add(1.9e9)},
DeletionTimestamp: &metav1.Time{Time: time.Now().Add(1.9e9)},
},
Spec: batch.JobSpec{
Completions: nil,
},
},
options: printers.GenerateOptions{},
// Columns: Name, Status, Completions, Duration, Age
expected: []metav1.TableRow{{Cells: []interface{}{"job9", "Terminating", "0/1", "", "0s"}}},
}, },
} }
@ -2701,10 +2808,10 @@ func TestPrintJobList(t *testing.T) {
}, },
} }
// Columns: Name, Completions, Duration, Age // Columns: Name, Status, Completions, Duration, Age
expectedRows := []metav1.TableRow{ expectedRows := []metav1.TableRow{
{Cells: []interface{}{"job1", "1/2", "", "0s"}}, {Cells: []interface{}{"job1", "Running", "1/2", "", "0s"}},
{Cells: []interface{}{"job2", "2/2", "20m", "0s"}}, {Cells: []interface{}{"job2", "Running", "2/2", "20m", "0s"}},
} }
rows, err := printJobList(&jobList, printers.GenerateOptions{}) rows, err := printJobList(&jobList, printers.GenerateOptions{})