Add ready field to Job status

to keep a count of the pods that have the ready condition.

Also:
- Add feature gate JobReadyPods.
- Add Ready to describe.

Change-Id: Ib934730a430a8e2a2f485671e345fe2330006939
This commit is contained in:
Aldo Culquicondor
2021-09-08 14:31:59 -04:00
parent c733594040
commit 1bff5eb44d
18 changed files with 224 additions and 97 deletions

View File

@@ -241,10 +241,17 @@ type JobStatus struct {
// +optional
CompletionTime *metav1.Time
// The number of actively running pods.
// The number of pending and running pods.
// +optional
Active int32
// The number of active pods which have a Ready condition.
//
// This field is alpha-level. The job controller populates the field when
// the feature gate JobReadyPods is enabled (disabled by default).
// +optional
Ready *int32
// The number of pods which reached phase Succeeded.
// +optional
Succeeded int32

View File

@@ -434,6 +434,7 @@ func autoConvert_v1_JobStatus_To_batch_JobStatus(in *v1.JobStatus, out *batch.Jo
out.Failed = in.Failed
out.CompletedIndexes = in.CompletedIndexes
out.UncountedTerminatedPods = (*batch.UncountedTerminatedPods)(unsafe.Pointer(in.UncountedTerminatedPods))
out.Ready = (*int32)(unsafe.Pointer(in.Ready))
return nil
}
@@ -447,6 +448,7 @@ func autoConvert_batch_JobStatus_To_v1_JobStatus(in *batch.JobStatus, out *v1.Jo
out.StartTime = (*metav1.Time)(unsafe.Pointer(in.StartTime))
out.CompletionTime = (*metav1.Time)(unsafe.Pointer(in.CompletionTime))
out.Active = in.Active
out.Ready = (*int32)(unsafe.Pointer(in.Ready))
out.Succeeded = in.Succeeded
out.Failed = in.Failed
out.CompletedIndexes = in.CompletedIndexes

View File

@@ -186,6 +186,9 @@ func validateJobStatus(status *batch.JobStatus, fldPath *field.Path) field.Error
allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.Active), fldPath.Child("active"))...)
allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.Succeeded), fldPath.Child("succeeded"))...)
allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(status.Failed), fldPath.Child("failed"))...)
if status.Ready != nil {
allErrs = append(allErrs, apivalidation.ValidateNonnegativeField(int64(*status.Ready), fldPath.Child("ready"))...)
}
if status.UncountedTerminatedPods != nil {
path := fldPath.Child("uncountedTerminatedPods")
seen := sets.NewString()

View File

@@ -686,6 +686,21 @@ func TestValidateJobUpdateStatus(t *testing.T) {
},
},
update: batch.Job{
ObjectMeta: metav1.ObjectMeta{
Name: "abc",
Namespace: metav1.NamespaceDefault,
ResourceVersion: "1",
},
Status: batch.JobStatus{
Active: 2,
Succeeded: 3,
Failed: 4,
Ready: pointer.Int32(1),
},
},
},
"nil ready": {
old: batch.Job{
ObjectMeta: metav1.ObjectMeta{
Name: "abc",
Namespace: metav1.NamespaceDefault,
@@ -693,10 +708,22 @@ func TestValidateJobUpdateStatus(t *testing.T) {
},
Status: batch.JobStatus{
Active: 1,
Succeeded: 1,
Succeeded: 2,
Failed: 3,
},
},
update: batch.Job{
ObjectMeta: metav1.ObjectMeta{
Name: "abc",
Namespace: metav1.NamespaceDefault,
ResourceVersion: "1",
},
Status: batch.JobStatus{
Active: 2,
Succeeded: 3,
Failed: 4,
},
},
},
"negative counts": {
old: batch.Job{
@@ -720,12 +747,15 @@ func TestValidateJobUpdateStatus(t *testing.T) {
Status: batch.JobStatus{
Active: -1,
Succeeded: -2,
Failed: 3,
Failed: -3,
Ready: pointer.Int32(-1),
},
},
wantErrs: field.ErrorList{
{Type: field.ErrorTypeInvalid, Field: "status.active"},
{Type: field.ErrorTypeInvalid, Field: "status.succeeded"},
{Type: field.ErrorTypeInvalid, Field: "status.failed"},
{Type: field.ErrorTypeInvalid, Field: "status.ready"},
},
},
"empty and duplicated uncounted pods": {

View File

@@ -314,6 +314,11 @@ func (in *JobStatus) DeepCopyInto(out *JobStatus) {
in, out := &in.CompletionTime, &out.CompletionTime
*out = (*in).DeepCopy()
}
if in.Ready != nil {
in, out := &in.Ready, &out.Ready
*out = new(int32)
**out = **in
}
if in.UncountedTerminatedPods != nil {
in, out := &in.UncountedTerminatedPods, &out.UncountedTerminatedPods
*out = new(UncountedTerminatedPods)