Skip to content

Commit

Permalink
feat: add jobset TerminalState field
Browse files Browse the repository at this point in the history
Signed-off-by: googs1025 <googs1025@gmail.com>
  • Loading branch information
googs1025 committed Jun 20, 2024
1 parent c45851b commit 95adaea
Show file tree
Hide file tree
Showing 15 changed files with 80 additions and 84 deletions.
10 changes: 4 additions & 6 deletions api/jobset/v1alpha2/jobset_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,6 @@ type JobSetConditionType string

// These are built-in conditions of a JobSet.
const (
// JobSetRunning means the job is running.
JobSetRunning JobSetConditionType = "Running"
// JobSetCompleted means the job has completed its execution.
JobSetCompleted JobSetConditionType = "Completed"
// JobSetFailed means the job has failed its execution.
Expand Down Expand Up @@ -136,9 +134,9 @@ type JobSetStatus struct {
// RestartsCountTowardsMax tracks the number of times the JobSet has restarted that counts towards the maximum allowed number of restarts.
RestartsCountTowardsMax int32 `json:"restartsCountTowardsMax,omitempty"`

// Phase of the JobSet.
// +kubebuilder:default="Running"
Phase string `json:"phase,omitempty"`
// TerminalState the state of the JobSet when it finishes execution.
// It can be either Complete or Failed. Otherwise, it is empty by default.
TerminalState string `json:"terminalState,omitempty"`

// ReplicatedJobsStatus track the number of JobsReady for each replicatedJob.
// +optional
Expand Down Expand Up @@ -175,7 +173,7 @@ type ReplicatedJobStatus struct {
// +k8s:openapi-gen=true
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Phase",JSONPath=".status.phase",type=string,description="Phase of the JobSet"
// +kubebuilder:printcolumn:name="TerminalState",JSONPath=".status.terminalState",type=string,description="Final state of JobSet"
// +kubebuilder:printcolumn:name="Restarts",JSONPath=".status.restarts",type=string,description="Number of restarts"
// +kubebuilder:printcolumn:name="Completed",type="string",priority=0,JSONPath=".status.conditions[?(@.type==\"Completed\")].status"
// +kubebuilder:printcolumn:name="Suspended",type="string",JSONPath=".spec.suspend",description="JobSet suspended"
Expand Down
4 changes: 2 additions & 2 deletions api/jobset/v1alpha2/openapi_generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions client-go/applyconfiguration/jobset/v1alpha2/jobsetstatus.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 8 additions & 7 deletions config/components/crd/bases/jobset.x-k8s.io_jobsets.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ spec:
scope: Namespaced
versions:
- additionalPrinterColumns:
- description: Phase of the JobSet
jsonPath: .status.phase
name: Phase
- description: Final state of JobSet
jsonPath: .status.terminalState
name: TerminalState
type: string
- description: Number of restarts
jsonPath: .status.restarts
Expand Down Expand Up @@ -8491,10 +8491,6 @@ spec:
x-kubernetes-list-map-keys:
- type
x-kubernetes-list-type: map
phase:
default: Running
description: Phase of the JobSet.
type: string
replicatedJobsStatus:
description: ReplicatedJobsStatus track the number of JobsReady for
each replicatedJob.
Expand Down Expand Up @@ -8555,6 +8551,11 @@ spec:
of restarts.
format: int32
type: integer
terminalState:
description: |-
TerminalState the state of the JobSet when it finishes execution.
It can be either Complete or Failed. Otherwise, it is empty by default.
type: string
type: object
type: object
served: true
Expand Down
8 changes: 4 additions & 4 deletions hack/python-sdk/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -179,10 +179,6 @@
],
"x-kubernetes-list-type": "map"
},
"phase": {
"description": "Phase of the JobSet.",
"type": "string"
},
"replicatedJobsStatus": {
"description": "ReplicatedJobsStatus track the number of JobsReady for each replicatedJob.",
"type": "array",
Expand All @@ -204,6 +200,10 @@
"description": "RestartsCountTowardsMax tracks the number of times the JobSet has restarted that counts towards the maximum allowed number of restarts.",
"type": "integer",
"format": "int32"
},
"terminalState": {
"description": "TerminalState the state of the JobSet when it finishes execution. It can be either Complete or Failed. Otherwise, it is empty by default.",
"type": "string"
}
}
},
Expand Down
4 changes: 2 additions & 2 deletions pkg/controllers/failure_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,8 @@ func makeFailedConditionOpts(reason, msg string) *conditionOpts {
Reason: reason,
Message: msg,
},
phase: string(jobset.JobSetFailed),
eventType: corev1.EventTypeWarning,
terminalState: string(jobset.JobSetFailed),
eventType: corev1.EventTypeWarning,
}
}

Expand Down
18 changes: 8 additions & 10 deletions pkg/controllers/jobset_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -866,12 +866,12 @@ func enqueueEvent(updateStatusOpts *statusUpdateOpts, event *eventParams) {

// function parameters for setCondition
type conditionOpts struct {
eventType string
phase string
condition *metav1.Condition
eventType string
terminalState string
condition *metav1.Condition
}

// setCondition will add a new condition and phase to the JobSet status (or update an existing one),
// setCondition will add a new condition and terminalState to the JobSet status (or update an existing one),
// and enqueue an event for emission if the status update succeeds at the end of the reconcile.
func setCondition(js *jobset.JobSet, condOpts *conditionOpts, updateStatusOpts *statusUpdateOpts) {
// Return early if no status update is required for this condition and phase.
Expand Down Expand Up @@ -945,9 +945,9 @@ func updateConditionAndPhase(js *jobset.JobSet, opts *conditionOpts) bool {
shouldUpdate = true
}

// Update the JobSet Status Phase if necessary.
if opts.phase != "" && js.Status.Phase != opts.phase {
js.Status.Phase = opts.phase
// If the jobset is in a terminal state, set the terminal state on the jobset.
if opts.terminalState != "" && js.Status.TerminalState != opts.terminalState {
js.Status.TerminalState = opts.terminalState
shouldUpdate = true
}

Expand Down Expand Up @@ -980,7 +980,7 @@ func makeCompletedConditionsOpts() *conditionOpts {
Reason: constants.AllJobsCompletedReason,
Message: constants.AllJobsCompletedMessage,
},
phase: string(jobset.JobSetCompleted),
terminalState: string(jobset.JobSetCompleted),
}
}

Expand All @@ -995,7 +995,6 @@ func makeSuspendedConditionOpts() *conditionOpts {
Reason: constants.JobSetSuspendedReason,
Message: constants.JobSetSuspendedMessage,
},
phase: string(jobset.JobSetSuspended),
}
}

Expand All @@ -1010,7 +1009,6 @@ func makeResumedConditionOpts() *conditionOpts {
Reason: constants.JobSetResumedReason,
Message: constants.JobSetResumedMessage,
},
phase: string(jobset.JobSetRunning),
}
}

Expand Down
8 changes: 4 additions & 4 deletions pkg/controllers/jobset_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -696,7 +696,7 @@ func TestUpdateConditions(t *testing.T) {
ReplicatedJob(testutils.MakeReplicatedJob(replicatedJobName).
Job(testutils.MakeJobTemplate(jobName, ns).Obj()).
Replicas(1).
Obj()).Phase(jobset.JobSetRunning).Obj(),
Obj()).Obj(),
opts: makeCompletedConditionsOpts(),
expectedUpdate: true,
},
Expand All @@ -706,7 +706,7 @@ func TestUpdateConditions(t *testing.T) {
ReplicatedJob(testutils.MakeReplicatedJob(replicatedJobName).
Job(testutils.MakeJobTemplate(jobName, ns).Obj()).
Replicas(1).
Obj()).Phase(jobset.JobSetRunning).Obj(),
Obj()).Obj(),
opts: makeSuspendedConditionOpts(),
expectedUpdate: true,
},
Expand All @@ -716,7 +716,7 @@ func TestUpdateConditions(t *testing.T) {
ReplicatedJob(testutils.MakeReplicatedJob(replicatedJobName).
Job(testutils.MakeJobTemplate(jobName, ns).Obj()).
Replicas(1).
Obj()).Phase(jobset.JobSetRunning).
Obj()).
Conditions([]metav1.Condition{
// JobSet is currrently suspended.
{
Expand All @@ -736,7 +736,7 @@ func TestUpdateConditions(t *testing.T) {
ReplicatedJob(testutils.MakeReplicatedJob(replicatedJobName).
Job(testutils.MakeJobTemplate(jobName, ns).Obj()).
Replicas(1).
Obj()).Phase(jobset.JobSetCompleted).
Obj()).TerminalState(jobset.JobSetCompleted).
Conditions([]metav1.Condition{
// JobSet is completed..
{
Expand Down
6 changes: 3 additions & 3 deletions pkg/util/testing/wrappers.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,9 @@ func (j *JobSetWrapper) FailedCondition(failedAt metav1.Time) *JobSetWrapper {
return j
}

// Phase sets the value of JobSet.Status.Phase.
func (j *JobSetWrapper) Phase(phase jobset.JobSetConditionType) *JobSetWrapper {
j.Status.Phase = string(phase)
// TerminalState sets the value of JobSet.Status.TerminalState.
func (j *JobSetWrapper) TerminalState(terminalState jobset.JobSetConditionType) *JobSetWrapper {
j.Status.TerminalState = string(terminalState)
return j
}

Expand Down
2 changes: 1 addition & 1 deletion sdk/python/docs/JobsetV1alpha2JobSetStatus.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ JobSetStatus defines the observed state of JobSet
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**conditions** | [**list[V1Condition]**](V1Condition.md) | | [optional]
**phase** | **str** | Phase of the JobSet. | [optional]
**replicated_jobs_status** | [**list[JobsetV1alpha2ReplicatedJobStatus]**](JobsetV1alpha2ReplicatedJobStatus.md) | ReplicatedJobsStatus track the number of JobsReady for each replicatedJob. | [optional]
**restarts** | **int** | Restarts tracks the number of times the JobSet has restarted (i.e. recreated in case of RecreateAll policy). | [optional]
**restarts_count_towards_max** | **int** | RestartsCountTowardsMax tracks the number of times the JobSet has restarted that counts towards the maximum allowed number of restarts. | [optional]
**terminal_state** | **str** | TerminalState the state of the JobSet when it finishes execution. It can be either Complete or Failed. Otherwise, it is empty by default. | [optional]

[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

Expand Down
62 changes: 31 additions & 31 deletions sdk/python/jobset/models/jobset_v1alpha2_job_set_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,43 +34,43 @@ class JobsetV1alpha2JobSetStatus(object):
"""
openapi_types = {
'conditions': 'list[V1Condition]',
'phase': 'str',
'replicated_jobs_status': 'list[JobsetV1alpha2ReplicatedJobStatus]',
'restarts': 'int',
'restarts_count_towards_max': 'int'
'restarts_count_towards_max': 'int',
'terminal_state': 'str'
}

attribute_map = {
'conditions': 'conditions',
'phase': 'phase',
'replicated_jobs_status': 'replicatedJobsStatus',
'restarts': 'restarts',
'restarts_count_towards_max': 'restartsCountTowardsMax'
'restarts_count_towards_max': 'restartsCountTowardsMax',
'terminal_state': 'terminalState'
}

def __init__(self, conditions=None, phase=None, replicated_jobs_status=None, restarts=None, restarts_count_towards_max=None, local_vars_configuration=None): # noqa: E501
def __init__(self, conditions=None, replicated_jobs_status=None, restarts=None, restarts_count_towards_max=None, terminal_state=None, local_vars_configuration=None): # noqa: E501
"""JobsetV1alpha2JobSetStatus - a model defined in OpenAPI""" # noqa: E501
if local_vars_configuration is None:
local_vars_configuration = Configuration()
self.local_vars_configuration = local_vars_configuration

self._conditions = None
self._phase = None
self._replicated_jobs_status = None
self._restarts = None
self._restarts_count_towards_max = None
self._terminal_state = None
self.discriminator = None

if conditions is not None:
self.conditions = conditions
if phase is not None:
self.phase = phase
if replicated_jobs_status is not None:
self.replicated_jobs_status = replicated_jobs_status
if restarts is not None:
self.restarts = restarts
if restarts_count_towards_max is not None:
self.restarts_count_towards_max = restarts_count_towards_max
if terminal_state is not None:
self.terminal_state = terminal_state

@property
def conditions(self):
Expand All @@ -93,29 +93,6 @@ def conditions(self, conditions):

self._conditions = conditions

@property
def phase(self):
"""Gets the phase of this JobsetV1alpha2JobSetStatus. # noqa: E501
Phase of the JobSet. # noqa: E501
:return: The phase of this JobsetV1alpha2JobSetStatus. # noqa: E501
:rtype: str
"""
return self._phase

@phase.setter
def phase(self, phase):
"""Sets the phase of this JobsetV1alpha2JobSetStatus.
Phase of the JobSet. # noqa: E501
:param phase: The phase of this JobsetV1alpha2JobSetStatus. # noqa: E501
:type: str
"""

self._phase = phase

@property
def replicated_jobs_status(self):
"""Gets the replicated_jobs_status of this JobsetV1alpha2JobSetStatus. # noqa: E501
Expand Down Expand Up @@ -185,6 +162,29 @@ def restarts_count_towards_max(self, restarts_count_towards_max):

self._restarts_count_towards_max = restarts_count_towards_max

@property
def terminal_state(self):
"""Gets the terminal_state of this JobsetV1alpha2JobSetStatus. # noqa: E501
TerminalState the state of the JobSet when it finishes execution. It can be either Complete or Failed. Otherwise, it is empty by default. # noqa: E501
:return: The terminal_state of this JobsetV1alpha2JobSetStatus. # noqa: E501
:rtype: str
"""
return self._terminal_state

@terminal_state.setter
def terminal_state(self, terminal_state):
"""Sets the terminal_state of this JobsetV1alpha2JobSetStatus.
TerminalState the state of the JobSet when it finishes execution. It can be either Complete or Failed. Otherwise, it is empty by default. # noqa: E501
:param terminal_state: The terminal_state of this JobsetV1alpha2JobSetStatus. # noqa: E501
:type: str
"""

self._terminal_state = terminal_state

def to_dict(self):
"""Returns the model properties as a dict"""
result = {}
Expand Down
4 changes: 2 additions & 2 deletions sdk/python/test/test_jobset_v1alpha2_job_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ def make_instance(self, include_optional):
conditions = [
None
],
phase = '0',
replicated_jobs_status = [
jobset.models.jobset_v1alpha2_replicated_job_status.JobsetV1alpha2ReplicatedJobStatus(
active = 56,
Expand All @@ -87,7 +86,8 @@ def make_instance(self, include_optional):
suspended = 56, )
],
restarts = 56,
restarts_count_towards_max = 56, )
restarts_count_towards_max = 56,
terminal_state = '0', )
)
else :
return JobsetV1alpha2JobSet(
Expand Down
Loading

0 comments on commit 95adaea

Please sign in to comment.