volcano.sh/volcano@v1.9.0/pkg/controllers/job/state/running.go (about)

     1  /*
     2  Copyright 2017 The Volcano Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package state
    18  
    19  import (
    20  	v1 "k8s.io/api/core/v1"
    21  
    22  	vcbatch "volcano.sh/apis/pkg/apis/batch/v1alpha1"
    23  	"volcano.sh/apis/pkg/apis/bus/v1alpha1"
    24  	"volcano.sh/volcano/pkg/controllers/apis"
    25  )
    26  
    27  type runningState struct {
    28  	job *apis.JobInfo
    29  }
    30  
    31  func (ps *runningState) Execute(action v1alpha1.Action) error {
    32  	switch action {
    33  	case v1alpha1.RestartJobAction:
    34  		return KillJob(ps.job, PodRetainPhaseNone, func(status *vcbatch.JobStatus) bool {
    35  			status.State.Phase = vcbatch.Restarting
    36  			status.RetryCount++
    37  			return true
    38  		})
    39  	case v1alpha1.AbortJobAction:
    40  		return KillJob(ps.job, PodRetainPhaseSoft, func(status *vcbatch.JobStatus) bool {
    41  			status.State.Phase = vcbatch.Aborting
    42  			return true
    43  		})
    44  	case v1alpha1.TerminateJobAction:
    45  		return KillJob(ps.job, PodRetainPhaseSoft, func(status *vcbatch.JobStatus) bool {
    46  			status.State.Phase = vcbatch.Terminating
    47  			return true
    48  		})
    49  	case v1alpha1.CompleteJobAction:
    50  		return KillJob(ps.job, PodRetainPhaseSoft, func(status *vcbatch.JobStatus) bool {
    51  			status.State.Phase = vcbatch.Completing
    52  			return true
    53  		})
    54  	default:
    55  		return SyncJob(ps.job, func(status *vcbatch.JobStatus) bool {
    56  			jobReplicas := TotalTasks(ps.job.Job)
    57  			if jobReplicas == 0 {
    58  				// when scale down to zero, keep the current job phase
    59  				return false
    60  			}
    61  
    62  			minSuccess := ps.job.Job.Spec.MinSuccess
    63  			if minSuccess != nil && status.Succeeded >= *minSuccess {
    64  				status.State.Phase = vcbatch.Completed
    65  				return true
    66  			}
    67  
    68  			totalTaskMinAvailable := TotalTaskMinAvailable(ps.job.Job)
    69  			if status.Succeeded+status.Failed == jobReplicas {
    70  				if ps.job.Job.Spec.MinAvailable >= totalTaskMinAvailable {
    71  					for _, task := range ps.job.Job.Spec.Tasks {
    72  						if task.MinAvailable == nil {
    73  							continue
    74  						}
    75  
    76  						if taskStatus, ok := status.TaskStatusCount[task.Name]; ok {
    77  							if taskStatus.Phase[v1.PodSucceeded] < *task.MinAvailable {
    78  								status.State.Phase = vcbatch.Failed
    79  								return true
    80  							}
    81  						}
    82  					}
    83  				}
    84  
    85  				if minSuccess != nil && status.Succeeded < *minSuccess {
    86  					status.State.Phase = vcbatch.Failed
    87  				} else if status.Succeeded >= ps.job.Job.Spec.MinAvailable {
    88  					status.State.Phase = vcbatch.Completed
    89  				} else {
    90  					status.State.Phase = vcbatch.Failed
    91  				}
    92  				return true
    93  			}
    94  			if status.Pending > jobReplicas-ps.job.Job.Spec.MinAvailable {
    95  				status.State.Phase = vcbatch.Pending
    96  				return true
    97  			}
    98  			return false
    99  		})
   100  	}
   101  }