@@ -87,13 +87,25 @@ func NewClient(k kubernetes.Interface, root *cobra.Command, config *viper.Viper,
8787 return c , nil
8888}
8989
90- // Create creates (and queues) a Kubernetes job with the given name that executes
90+ // RunJob creates (and queues) a Kubernetes job with the given name that executes
9191// the given command with the given command-line arguments on the given container
9292// image. resources specifies the minimum required resources for execution.
9393func (c * Client ) RunJob (ctx context.Context , job * cloudrpc.JobSpec ) (* cloudrpc.JobStatus , error ) {
9494 if job .Version != inmap .Version {
9595 return nil , fmt .Errorf ("incorrect InMAP version: %s != %s" , job .Version , inmap .Version )
9696 }
97+
98+ status , err := c .Status (ctx , & cloudrpc.JobName {Name : job .Name , Version : job .Version })
99+ if err != nil {
100+ return nil , err
101+ }
102+ if status .Status != cloudrpc .Status_Failed { //TODO: status.Status != cloudrpc.Status_Missing && {
103+ // Only create the job if it is missing or failed.
104+ return status , nil
105+ }
106+ // TODO: Is this necessary?
107+ c .Delete (ctx , & cloudrpc.JobName {Name : job .Name , Version : job .Version })
108+
97109 if err := c .stageInputs (ctx , job ); err != nil {
98110 return nil , err
99111 }
@@ -107,20 +119,11 @@ func (c *Client) RunJob(ctx context.Context, job *cloudrpc.JobSpec) (*cloudrpc.J
107119 k8sJob := createJob (userJobName (user , job .Name ), job .Cmd , job .Args , c .Image , core.ResourceList {
108120 core .ResourceMemory : resource .MustParse (fmt .Sprintf ("%dGi" , job .MemoryGB )),
109121 })
110- k8sJobResult , err : = c .jobControl .Create (k8sJob )
122+ _ , err = c .jobControl .Create (k8sJob )
111123 if err != nil {
112124 return nil , err
113125 }
114- return c .jobStatus (k8sJobResult )
115- }
116-
117- // Status returns the status of the given job.
118- func (c * Client ) Status (ctx context.Context , job * cloudrpc.JobName ) (* cloudrpc.JobStatus , error ) {
119- k8sJob , err := c .getk8sJob (ctx , job )
120- if err != nil {
121- return nil , err
122- }
123- return c .jobStatus (k8sJob )
126+ return c .Status (ctx , & cloudrpc.JobName {Name : job .Name , Version : job .Version })
124127}
125128
126129// Delete deletes the given job.
@@ -167,10 +170,36 @@ func userJobName(user, name string) string {
167170 return strings .Replace (user , "_" , "-" , - 1 ) + "-" + strings .Replace (name , "_" , "-" , - 1 )
168171}
169172
170- func (c * Client ) jobStatus (j * batch.Job ) (* cloudrpc.JobStatus , error ) {
171- return & cloudrpc.JobStatus {
172- Status : j .Status .String (),
173- }, nil
173+ // Status returns the status of the given job.
174+ func (c * Client ) Status (ctx context.Context , job * cloudrpc.JobName ) (* cloudrpc.JobStatus , error ) {
175+ s := new (cloudrpc.JobStatus )
176+ /*k8sJob, err := c.getk8sJob(ctx, job)
177+ if err != nil {
178+ return &cloudrpc.JobStatus{
179+ Status: cloudrpc.Status_Missing,
180+ Message: err.Error(),
181+ }, nil
182+ }
183+ for _, c := range k8sJob.Status.Conditions {
184+ if c.Type == batch.JobComplete && c.Status == core.ConditionTrue {
185+ s.Status = cloudrpc.Status_Complete
186+ s.StartTime = k8sJob.Status.StartTime.Time.Unix()
187+ s.CompletionTime = k8sJob.Status.CompletionTime.Time.Unix()
188+ } else if c.Type == batch.JobFailed && c.Status == core.ConditionTrue {
189+ s.Status = cloudrpc.Status_Failed
190+ }
191+ }
192+ if k8sJob.Status.Active > 0 {
193+ s.Status = cloudrpc.Status_Running
194+ s.StartTime = k8sJob.Status.StartTime.Time.Unix()
195+ }*/
196+ //TODO: err = c.checkOutputs(ctx, name, k8sJob.Spec.Template.Spec.Containers[0].Command)
197+ err := c .checkOutputs (ctx , job .Name , []string {"inmap" , "run" , "steady" })
198+ if err != nil {
199+ s .Status = cloudrpc .Status_Failed
200+ s .Message = fmt .Sprintf ("job completed but the following error occurred when checking outputs: %s" , err )
201+ }
202+ return s , nil
174203}
175204
176205// createJob creates a Kubernetes job specification with the given name that executes the
0 commit comments