21
21
from DIRAC .Core .Utilities .JEncode import strToIntDict
22
22
from DIRAC .Core .Utilities .ObjectLoader import ObjectLoader
23
23
from DIRAC .FrameworkSystem .Client .ProxyManagerClient import gProxyManager
24
- from DIRAC .StorageManagementSystem .DB .StorageManagementDB import StorageManagementDB
25
24
from DIRAC .WorkloadManagementSystem .Client import JobStatus
26
- from DIRAC .WorkloadManagementSystem .Client .JobStatus import filterJobStateTransition
27
25
from DIRAC .WorkloadManagementSystem .Service .JobPolicy import (
28
26
RIGHT_DELETE ,
29
27
RIGHT_KILL ,
32
30
RIGHT_SUBMIT ,
33
31
JobPolicy ,
34
32
)
33
+ from DIRAC .WorkloadManagementSystem .Utilities .jobAdministration import kill_delete_jobs
35
34
from DIRAC .WorkloadManagementSystem .Utilities .JobModel import JobDescriptionModel
36
35
from DIRAC .WorkloadManagementSystem .Utilities .ParametricJob import generateParametricJobs , getParameterVectorLength
37
36
from DIRAC .WorkloadManagementSystem .Utilities .Utils import rescheduleJobs
@@ -379,6 +378,8 @@ def export_removeJob(self, jobIDs):
379
378
:return: S_OK()/S_ERROR() -- confirmed job IDs
380
379
"""
381
380
381
+ # FIXME: extract the logic to a utility function
382
+
382
383
jobList = self .__getJobList (jobIDs )
383
384
if not jobList :
384
385
return S_ERROR ("Invalid job specification: " + str (jobIDs ))
@@ -430,131 +431,28 @@ def export_removeJob(self, jobIDs):
430
431
431
432
return S_OK (validJobList )
432
433
433
- def __deleteJob (self , jobID , force = False ):
434
- """Set the job status to "Deleted"
435
- and remove the pilot that ran and its logging info if the pilot is finished.
436
-
437
- :param int jobID: job ID
438
- :return: S_OK()/S_ERROR()
439
- """
440
- if not (result := self .jobDB .setJobStatus (jobID , JobStatus .DELETED , "Checking accounting" , force = force ))["OK" ]:
441
- return result
442
-
443
- if not (result := self .taskQueueDB .deleteJob (jobID ))["OK" ]:
444
- self .log .warn ("Failed to delete job from the TaskQueue" )
445
-
446
- # if it was the last job for the pilot
447
- result = self .pilotAgentsDB .getPilotsForJobID (jobID )
448
- if not result ["OK" ]:
449
- self .log .error ("Failed to get Pilots for JobID" , result ["Message" ])
450
- return result
451
- for pilot in result ["Value" ]:
452
- res = self .pilotAgentsDB .getJobsForPilot (pilot )
453
- if not res ["OK" ]:
454
- self .log .error ("Failed to get jobs for pilot" , res ["Message" ])
455
- return res
456
- if not res ["Value" ]: # if list of jobs for pilot is empty, delete pilot
457
- result = self .pilotAgentsDB .getPilotInfo (pilotID = pilot )
458
- if not result ["OK" ]:
459
- self .log .error ("Failed to get pilot info" , result ["Message" ])
460
- return result
461
- ret = self .pilotAgentsDB .deletePilot (result ["Value" ]["PilotJobReference" ])
462
- if not ret ["OK" ]:
463
- self .log .error ("Failed to delete pilot from PilotAgentsDB" , ret ["Message" ])
464
- return ret
465
-
466
- return S_OK ()
434
+ ###########################################################################
435
+ types_deleteJob = []
467
436
468
- def __killJob (self , jobID , sendKillCommand = True , force = False ):
469
- """Kill one job
437
+ def export_deleteJob (self , jobIDs , force = False ):
438
+ """Delete jobs specified in the jobIDs list
470
439
471
- :param int jobID: job ID
472
- :param bool sendKillCommand: send kill command
440
+ :param list jobIDs: list of job IDs
473
441
474
- :return: S_OK() /S_ERROR()
442
+ :return: S_OK/S_ERROR
475
443
"""
476
- if sendKillCommand :
477
- if not (result := self .jobDB .setJobCommand (jobID , "Kill" ))["OK" ]:
478
- return result
479
-
480
- self .log .info ("Job marked for termination" , jobID )
481
- if not (result := self .jobDB .setJobStatus (jobID , JobStatus .KILLED , "Marked for termination" , force = force ))[
482
- "OK"
483
- ]:
484
- self .log .warn ("Failed to set job Killed status" , result ["Message" ])
485
- if not (result := self .taskQueueDB .deleteJob (jobID ))["OK" ]:
486
- self .log .warn ("Failed to delete job from the TaskQueue" , result ["Message" ])
487
-
488
- return S_OK ()
489
444
490
- def _kill_delete_jobs (self , jobIDList , right , force = False ):
491
- """Kill (== set the status to "KILLED") or delete (== set the status to "DELETED") jobs as necessary
492
-
493
- :param list jobIDList: job IDs
494
- :param str right: RIGHT_KILL or RIGHT_DELETE
495
-
496
- :return: S_OK()/S_ERROR()
497
- """
498
- jobList = self .__getJobList (jobIDList )
445
+ jobList = self .__getJobList (jobIDs )
499
446
if not jobList :
500
447
self .log .warn ("No jobs specified" )
501
448
return S_OK ([])
502
449
503
- validJobList , invalidJobList , nonauthJobList , ownerJobList = self .jobPolicy .evaluateJobRights (jobList , right )
504
-
505
- badIDs = []
506
-
507
- killJobList = []
508
- deleteJobList = []
509
- if validJobList :
510
- # Get the jobs allowed to transition to the Killed state
511
- filterRes = filterJobStateTransition (validJobList , JobStatus .KILLED )
512
- if not filterRes ["OK" ]:
513
- return filterRes
514
- killJobList .extend (filterRes ["Value" ])
515
-
516
- if not right == RIGHT_KILL :
517
- # Get the jobs allowed to transition to the Deleted state
518
- filterRes = filterJobStateTransition (validJobList , JobStatus .DELETED )
519
- if not filterRes ["OK" ]:
520
- return filterRes
521
- deleteJobList .extend (filterRes ["Value" ])
522
-
523
- # Look for jobs that are in the Staging state to send kill signal to the stager
524
- result = self .jobDB .getJobsAttributes (killJobList , ["Status" ])
525
- if not result ["OK" ]:
526
- return result
527
- stagingJobList = [jobID for jobID , sDict in result ["Value" ].items () if sDict ["Status" ] == JobStatus .STAGING ]
528
-
529
- for jobID in killJobList :
530
- result = self .__killJob (jobID , force = force )
531
- if not result ["OK" ]:
532
- badIDs .append (jobID )
533
-
534
- for jobID in deleteJobList :
535
- result = self .__deleteJob (jobID , force = force )
536
- if not result ["OK" ]:
537
- badIDs .append (jobID )
538
-
539
- if stagingJobList :
540
- stagerDB = StorageManagementDB ()
541
- self .log .info ("Going to send killing signal to stager as well!" )
542
- result = stagerDB .killTasksBySourceTaskID (stagingJobList )
543
- if not result ["OK" ]:
544
- self .log .warn ("Failed to kill some Stager tasks" , result ["Message" ])
450
+ validJobList , invalidJobList , nonauthJobList , ownerJobList = self .jobPolicy .evaluateJobRights (
451
+ jobList , RIGHT_DELETE
452
+ )
545
453
546
- if nonauthJobList or badIDs :
547
- result = S_ERROR ("Some jobs failed deletion" )
548
- if nonauthJobList :
549
- self .log .warn ("Non-authorized JobIDs won't be deleted" , str (nonauthJobList ))
550
- result ["NonauthorizedJobIDs" ] = nonauthJobList
551
- if badIDs :
552
- self .log .warn ("JobIDs failed to be deleted" , str (badIDs ))
553
- result ["FailedJobIDs" ] = badIDs
554
- return result
454
+ result = kill_delete_jobs (RIGHT_DELETE , validJobList , nonauthJobList , force = force )
555
455
556
- jobsList = killJobList if right == RIGHT_KILL else deleteJobList
557
- result = S_OK (jobsList )
558
456
result ["requireProxyUpload" ] = len (ownerJobList ) > 0 and self .__checkIfProxyUploadIsRequired ()
559
457
560
458
if invalidJobList :
@@ -563,30 +461,33 @@ def _kill_delete_jobs(self, jobIDList, right, force=False):
563
461
return result
564
462
565
463
###########################################################################
566
- types_deleteJob = []
464
+ types_killJob = []
567
465
568
- def export_deleteJob (self , jobIDs , force = False ):
569
- """Delete jobs specified in the jobIDs list
466
+ def export_killJob (self , jobIDs , force = False ):
467
+ """Kill jobs specified in the jobIDs list
570
468
571
469
:param list jobIDs: list of job IDs
572
470
573
471
:return: S_OK/S_ERROR
574
472
"""
575
473
576
- return self ._kill_delete_jobs (jobIDs , RIGHT_DELETE , force = force )
474
+ jobList = self .__getJobList (jobIDs )
475
+ if not jobList :
476
+ self .log .warn ("No jobs specified" )
477
+ return S_OK ([])
577
478
578
- ###########################################################################
579
- types_killJob = []
479
+ validJobList , invalidJobList , nonauthJobList , ownerJobList = self .jobPolicy .evaluateJobRights (
480
+ jobList , RIGHT_KILL
481
+ )
580
482
581
- def export_killJob (self , jobIDs , force = False ):
582
- """Kill jobs specified in the jobIDs list
483
+ result = kill_delete_jobs (RIGHT_KILL , validJobList , nonauthJobList , force = force )
583
484
584
- :param list jobIDs: list of job IDs
485
+ result [ "requireProxyUpload" ] = len ( ownerJobList ) > 0 and self . __checkIfProxyUploadIsRequired ()
585
486
586
- :return: S_OK/S_ERROR
587
- """
487
+ if invalidJobList :
488
+ result [ "InvalidJobIDs" ] = invalidJobList
588
489
589
- return self . _kill_delete_jobs ( jobIDs , RIGHT_KILL , force = force )
490
+ return result
590
491
591
492
###########################################################################
592
493
types_resetJob = []
0 commit comments