2121from DIRAC .Core .Utilities .JEncode import strToIntDict
2222from DIRAC .Core .Utilities .ObjectLoader import ObjectLoader
2323from DIRAC .FrameworkSystem .Client .ProxyManagerClient import gProxyManager
24- from DIRAC .StorageManagementSystem .DB .StorageManagementDB import StorageManagementDB
2524from DIRAC .WorkloadManagementSystem .Client import JobStatus
26- from DIRAC .WorkloadManagementSystem .Client .JobStatus import filterJobStateTransition
2725from DIRAC .WorkloadManagementSystem .Service .JobPolicy import (
2826 RIGHT_DELETE ,
2927 RIGHT_KILL ,
3230 RIGHT_SUBMIT ,
3331 JobPolicy ,
3432)
33+ from DIRAC .WorkloadManagementSystem .Utilities .jobAdministration import kill_delete_jobs
3534from DIRAC .WorkloadManagementSystem .Utilities .JobModel import JobDescriptionModel
3635from DIRAC .WorkloadManagementSystem .Utilities .ParametricJob import generateParametricJobs , getParameterVectorLength
3736from DIRAC .WorkloadManagementSystem .Utilities .Utils import rescheduleJobs
@@ -389,6 +388,8 @@ def export_removeJob(self, jobIDs):
389388 :return: S_OK()/S_ERROR() -- confirmed job IDs
390389 """
391390
391+ # FIXME: extract the logic to a utility function
392+
392393 jobList = self .__getJobList (jobIDs )
393394 if not jobList :
394395 return S_ERROR ("Invalid job specification: " + str (jobIDs ))
@@ -440,131 +441,28 @@ def export_removeJob(self, jobIDs):
440441
441442 return S_OK (validJobList )
442443
443- def __deleteJob (self , jobID , force = False ):
444- """Set the job status to "Deleted"
445- and remove the pilot that ran and its logging info if the pilot is finished.
446-
447- :param int jobID: job ID
448- :return: S_OK()/S_ERROR()
449- """
450- if not (result := self .jobDB .setJobStatus (jobID , JobStatus .DELETED , "Checking accounting" , force = force ))["OK" ]:
451- return result
452-
453- if not (result := self .taskQueueDB .deleteJob (jobID ))["OK" ]:
454- self .log .warn ("Failed to delete job from the TaskQueue" )
455-
456- # if it was the last job for the pilot
457- result = self .pilotAgentsDB .getPilotsForJobID (jobID )
458- if not result ["OK" ]:
459- self .log .error ("Failed to get Pilots for JobID" , result ["Message" ])
460- return result
461- for pilot in result ["Value" ]:
462- res = self .pilotAgentsDB .getJobsForPilot (pilot )
463- if not res ["OK" ]:
464- self .log .error ("Failed to get jobs for pilot" , res ["Message" ])
465- return res
466- if not res ["Value" ]: # if list of jobs for pilot is empty, delete pilot
467- result = self .pilotAgentsDB .getPilotInfo (pilotID = pilot )
468- if not result ["OK" ]:
469- self .log .error ("Failed to get pilot info" , result ["Message" ])
470- return result
471- ret = self .pilotAgentsDB .deletePilot (result ["Value" ]["PilotJobReference" ])
472- if not ret ["OK" ]:
473- self .log .error ("Failed to delete pilot from PilotAgentsDB" , ret ["Message" ])
474- return ret
475-
476- return S_OK ()
444+ ###########################################################################
445+ types_deleteJob = []
477446
478- def __killJob (self , jobID , sendKillCommand = True , force = False ):
479- """Kill one job
447+ def export_deleteJob (self , jobIDs , force = False ):
448+ """Delete jobs specified in the jobIDs list
480449
481- :param int jobID: job ID
482- :param bool sendKillCommand: send kill command
450+ :param list jobIDs: list of job IDs
483451
484- :return: S_OK() /S_ERROR()
452+ :return: S_OK/S_ERROR
485453 """
486- if sendKillCommand :
487- if not (result := self .jobDB .setJobCommand (jobID , "Kill" ))["OK" ]:
488- return result
489454
490- self .log .info ("Job marked for termination" , jobID )
491- if not (result := self .jobDB .setJobStatus (jobID , JobStatus .KILLED , "Marked for termination" , force = force ))[
492- "OK"
493- ]:
494- self .log .warn ("Failed to set job Killed status" , result ["Message" ])
495- if not (result := self .taskQueueDB .deleteJob (jobID ))["OK" ]:
496- self .log .warn ("Failed to delete job from the TaskQueue" , result ["Message" ])
497-
498- return S_OK ()
499-
500- def _kill_delete_jobs (self , jobIDList , right , force = False ):
501- """Kill (== set the status to "KILLED") or delete (== set the status to "DELETED") jobs as necessary
502-
503- :param list jobIDList: job IDs
504- :param str right: RIGHT_KILL or RIGHT_DELETE
505-
506- :return: S_OK()/S_ERROR()
507- """
508- jobList = self .__getJobList (jobIDList )
455+ jobList = self .__getJobList (jobIDs )
509456 if not jobList :
510457 self .log .warn ("No jobs specified" )
511458 return S_OK ([])
512459
513- validJobList , invalidJobList , nonauthJobList , ownerJobList = self .jobPolicy .evaluateJobRights (jobList , right )
514-
515- badIDs = []
516-
517- killJobList = []
518- deleteJobList = []
519- if validJobList :
520- # Get the jobs allowed to transition to the Killed state
521- filterRes = filterJobStateTransition (validJobList , JobStatus .KILLED )
522- if not filterRes ["OK" ]:
523- return filterRes
524- killJobList .extend (filterRes ["Value" ])
525-
526- if not right == RIGHT_KILL :
527- # Get the jobs allowed to transition to the Deleted state
528- filterRes = filterJobStateTransition (validJobList , JobStatus .DELETED )
529- if not filterRes ["OK" ]:
530- return filterRes
531- deleteJobList .extend (filterRes ["Value" ])
532-
533- # Look for jobs that are in the Staging state to send kill signal to the stager
534- result = self .jobDB .getJobsAttributes (killJobList , ["Status" ])
535- if not result ["OK" ]:
536- return result
537- stagingJobList = [jobID for jobID , sDict in result ["Value" ].items () if sDict ["Status" ] == JobStatus .STAGING ]
538-
539- for jobID in killJobList :
540- result = self .__killJob (jobID , force = force )
541- if not result ["OK" ]:
542- badIDs .append (jobID )
543-
544- for jobID in deleteJobList :
545- result = self .__deleteJob (jobID , force = force )
546- if not result ["OK" ]:
547- badIDs .append (jobID )
460+ validJobList , invalidJobList , nonauthJobList , ownerJobList = self .jobPolicy .evaluateJobRights (
461+ jobList , RIGHT_DELETE
462+ )
548463
549- if stagingJobList :
550- stagerDB = StorageManagementDB ()
551- self .log .info ("Going to send killing signal to stager as well!" )
552- result = stagerDB .killTasksBySourceTaskID (stagingJobList )
553- if not result ["OK" ]:
554- self .log .warn ("Failed to kill some Stager tasks" , result ["Message" ])
464+ result = kill_delete_jobs (RIGHT_DELETE , validJobList , nonauthJobList , force = force )
555465
556- if nonauthJobList or badIDs :
557- result = S_ERROR ("Some jobs failed deletion" )
558- if nonauthJobList :
559- self .log .warn ("Non-authorized JobIDs won't be deleted" , str (nonauthJobList ))
560- result ["NonauthorizedJobIDs" ] = nonauthJobList
561- if badIDs :
562- self .log .warn ("JobIDs failed to be deleted" , str (badIDs ))
563- result ["FailedJobIDs" ] = badIDs
564- return result
565-
566- jobsList = killJobList if right == RIGHT_KILL else deleteJobList
567- result = S_OK (jobsList )
568466 result ["requireProxyUpload" ] = len (ownerJobList ) > 0 and self .__checkIfProxyUploadIsRequired ()
569467
570468 if invalidJobList :
@@ -573,30 +471,33 @@ def _kill_delete_jobs(self, jobIDList, right, force=False):
573471 return result
574472
575473 ###########################################################################
576- types_deleteJob = []
474+ types_killJob = []
577475
578- def export_deleteJob (self , jobIDs , force = False ):
579- """Delete jobs specified in the jobIDs list
476+ def export_killJob (self , jobIDs , force = False ):
477+ """Kill jobs specified in the jobIDs list
580478
581479 :param list jobIDs: list of job IDs
582480
583481 :return: S_OK/S_ERROR
584482 """
585483
586- return self ._kill_delete_jobs (jobIDs , RIGHT_DELETE , force = force )
484+ jobList = self .__getJobList (jobIDs )
485+ if not jobList :
486+ self .log .warn ("No jobs specified" )
487+ return S_OK ([])
587488
588- ###########################################################################
589- types_killJob = []
489+ validJobList , invalidJobList , nonauthJobList , ownerJobList = self .jobPolicy .evaluateJobRights (
490+ jobList , RIGHT_KILL
491+ )
590492
591- def export_killJob (self , jobIDs , force = False ):
592- """Kill jobs specified in the jobIDs list
493+ result = kill_delete_jobs (RIGHT_KILL , validJobList , nonauthJobList , force = force )
593494
594- :param list jobIDs: list of job IDs
495+ result [ "requireProxyUpload" ] = len ( ownerJobList ) > 0 and self . __checkIfProxyUploadIsRequired ()
595496
596- :return: S_OK/S_ERROR
597- """
497+ if invalidJobList :
498+ result [ "InvalidJobIDs" ] = invalidJobList
598499
599- return self . _kill_delete_jobs ( jobIDs , RIGHT_KILL , force = force )
500+ return result
600501
601502 ###########################################################################
602503 types_resetJob = []
0 commit comments