DIRAC 9.0.10__py3-none-any.whl → 9.0.11__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -90,7 +90,7 @@ class Host(componentsBase):
90
90
  __table_args__ = {"mysql_engine": "InnoDB", "mysql_charset": "utf8mb4"}
91
91
 
92
92
  hostID = Column("HostID", Integer, primary_key=True)
93
- hostName = Column("HostName", String(32), nullable=False)
93
+ hostName = Column("HostName", String(64), nullable=False)
94
94
  cpu = Column("CPU", String(64), nullable=False)
95
95
  installationList = relationship("InstalledComponent", backref="installationHost")
96
96
 
@@ -30,6 +30,7 @@ def monitorInstallation(componentType, system, component, module=None, cpu=None,
30
30
 
31
31
  if not hostname:
32
32
  hostname = socket.getfqdn()
33
+ hostname = hostname[0:64]
33
34
  instance = component[0:32]
34
35
 
35
36
  result = monitoringClient.installationExists(
@@ -203,9 +203,6 @@ class Condor(object):
203
203
  resultDict["Jobs"] = []
204
204
  for i in range(submittedJobs):
205
205
  resultDict["Jobs"].append(".".join([cluster, str(i)]))
206
- # Executable is transferred afterward
207
- # Inform the caller that Condor cannot delete it before the end of the execution
208
- resultDict["ExecutableToKeep"] = executable
209
206
  else:
210
207
  resultDict["Status"] = status
211
208
  resultDict["Message"] = error
@@ -35,8 +35,10 @@ if __name__ == "__main__":
35
35
  from urllib.parse import unquote as urlunquote
36
36
 
37
37
 
38
- arguments = sys.argv[1]
39
- inputDict = json.loads(urlunquote(arguments))
38
+ # Read options from JSON file
39
+ optionsFilePath = sys.argv[1]
40
+ with open(optionsFilePath, 'r') as f:
41
+ inputDict = json.load(f)
40
42
 
41
43
  method = inputDict.pop('Method')
42
44
  batchSystem = inputDict.pop('BatchSystem')
@@ -45,9 +47,15 @@ if __name__ == "__main__":
45
47
  try:
46
48
  result = getattr(batch, method)(**inputDict)
47
49
  except Exception:
48
- result = traceback.format_exc()
49
-
50
- resultJson = urlquote(json.dumps(result))
51
- print("============= Start output ===============")
52
- print(resultJson)
50
+ # Wrap the traceback in a proper error structure
51
+ result = {
52
+ 'Status': -1,
53
+ 'Message': 'Exception during batch method execution',
54
+ 'Traceback': traceback.format_exc()
55
+ }
56
+
57
+ # Write result to JSON file
58
+ resultFilePath = optionsFilePath.replace('.json', '_result.json')
59
+ with open(resultFilePath, 'w') as f:
60
+ json.dump(result, f)
53
61
  """
@@ -182,8 +182,6 @@ class LocalComputingElement(ComputingElement):
182
182
  batchSystemName = self.batchSystem.__class__.__name__.lower()
183
183
  jobIDs = ["ssh" + batchSystemName + "://" + self.ceName + "/" + _id for _id in resultSubmit["Jobs"]]
184
184
  result = S_OK(jobIDs)
185
- if "ExecutableToKeep" in resultSubmit:
186
- result["ExecutableToKeep"] = resultSubmit["ExecutableToKeep"]
187
185
  else:
188
186
  result = S_ERROR(resultSubmit["Message"])
189
187
 
@@ -67,9 +67,10 @@ import json
67
67
  import os
68
68
  import shutil
69
69
  import stat
70
+ import tempfile
70
71
  import uuid
71
72
  from shlex import quote as shlex_quote
72
- from urllib.parse import quote, unquote, urlparse
73
+ from urllib.parse import urlparse
73
74
 
74
75
  import pexpect
75
76
 
@@ -484,47 +485,69 @@ class SSHComputingElement(ComputingElement):
484
485
  options["User"] = self.user
485
486
  options["Queue"] = self.queue
486
487
 
487
- options = json.dumps(options)
488
- options = quote(options)
488
+ localOptionsFile = None
489
+ remoteOptionsFile = None
490
+ localResultFile = None
491
+ remoteResultFile = None
492
+ try:
493
+ # Write options to a local temporary file
494
+ with tempfile.NamedTemporaryFile(mode="w", suffix=".json", delete=False) as f:
495
+ json.dump(options, f)
496
+ localOptionsFile = f.name
497
+
498
+ # Upload the options file to the remote host
499
+ remoteOptionsFile = f"{self.sharedArea}/batch_options_{uuid.uuid4().hex}.json"
500
+ result = ssh.scpCall(30, localOptionsFile, remoteOptionsFile)
501
+ if not result["OK"]:
502
+ return result
489
503
 
490
- cmd = (
491
- "bash --login -c 'python3 %s/execute_batch %s || python %s/execute_batch %s || python2 %s/execute_batch %s'"
492
- % (self.sharedArea, options, self.sharedArea, options, self.sharedArea, options)
493
- )
504
+ # Execute the batch command with the options file path
505
+ cmd = (
506
+ f"bash --login -c 'python3 {self.sharedArea}/execute_batch {remoteOptionsFile} || "
507
+ f"python {self.sharedArea}/execute_batch {remoteOptionsFile} || "
508
+ f"python2 {self.sharedArea}/execute_batch {remoteOptionsFile}'"
509
+ )
494
510
 
495
- self.log.verbose(f"CE submission command: {cmd}")
511
+ self.log.verbose(f"CE submission command: {cmd}")
496
512
 
497
- result = ssh.sshCall(120, cmd)
498
- if not result["OK"]:
499
- self.log.error(f"{self.ceType} CE job submission failed", result["Message"])
500
- return result
513
+ result = ssh.sshCall(120, cmd)
514
+ if not result["OK"]:
515
+ self.log.error(f"{self.ceType} CE job submission failed", result["Message"])
516
+ return result
501
517
 
502
- sshStatus = result["Value"][0]
503
- sshStdout = result["Value"][1]
504
- sshStderr = result["Value"][2]
505
-
506
- # Examine results of the job submission
507
- if sshStatus == 0:
508
- output = sshStdout.strip().replace("\r", "").strip()
509
- if not output:
510
- return S_ERROR("No output from remote command")
511
-
512
- try:
513
- index = output.index("============= Start output ===============")
514
- output = output[index + 42 :]
515
- except ValueError:
516
- return S_ERROR(f"Invalid output from remote command: {output}")
517
-
518
- try:
519
- output = unquote(output)
520
- result = json.loads(output)
521
- if isinstance(result, str) and result.startswith("Exception:"):
522
- return S_ERROR(result)
523
- return S_OK(result)
524
- except Exception:
525
- return S_ERROR("Invalid return structure from job submission")
526
- else:
527
- return S_ERROR("\n".join([sshStdout, sshStderr]))
518
+ sshStatus = result["Value"][0]
519
+ if sshStatus != 0:
520
+ sshStdout = result["Value"][1]
521
+ sshStderr = result["Value"][2]
522
+ return S_ERROR(f"CE job submission command failed with status {sshStatus}: {sshStdout} {sshStderr}")
523
+
524
+ # The result should be written to a JSON file by execute_batch
525
+ # Compute the expected result file path
526
+ remoteResultFile = remoteOptionsFile.replace(".json", "_result.json")
527
+
528
+ # Try to download the result file
529
+ with tempfile.NamedTemporaryFile(mode="r", suffix=".json", delete=False) as f:
530
+ localResultFile = f.name
531
+
532
+ result = ssh.scpCall(30, localResultFile, remoteResultFile, upload=False)
533
+ if not result["OK"]:
534
+ return result
535
+
536
+ # Read the result from the downloaded file
537
+ with open(localResultFile) as f:
538
+ result = json.load(f)
539
+ return S_OK(result)
540
+ finally:
541
+ # Clean up local temporary file
542
+ if localOptionsFile and os.path.exists(localOptionsFile):
543
+ os.remove(localOptionsFile)
544
+ if localResultFile and os.path.exists(localResultFile):
545
+ os.remove(localResultFile)
546
+ # Clean up remote temporary files
547
+ if remoteOptionsFile:
548
+ ssh.sshCall(30, f"rm -f {remoteOptionsFile}")
549
+ if remoteResultFile:
550
+ ssh.sshCall(30, f"rm -f {remoteResultFile}")
528
551
 
529
552
  def submitJob(self, executableFile, proxy, numberOfJobs=1):
530
553
  # self.log.verbose( "Executable file path: %s" % executableFile )
@@ -20,6 +20,7 @@ from DIRAC.ConfigurationSystem.Client.Helpers.Operations import Operations
20
20
  from DIRAC.Core.Base.AgentModule import AgentModule
21
21
  from DIRAC.Core.Utilities.DErrno import cmpError
22
22
  from DIRAC.Core.Utilities.List import breakListIntoChunks
23
+ from DIRAC.Core.Utilities.ObjectLoader import ObjectLoader
23
24
  from DIRAC.Core.Utilities.Proxy import executeWithUserProxy
24
25
  from DIRAC.Core.Utilities.ReturnValues import returnSingleResult
25
26
  from DIRAC.RequestManagementSystem.Client.File import File
@@ -32,7 +33,6 @@ from DIRAC.Resources.Catalog.FileCatalogClient import FileCatalogClient
32
33
  from DIRAC.Resources.Storage.StorageElement import StorageElement
33
34
  from DIRAC.TransformationSystem.Client import TransformationStatus
34
35
  from DIRAC.TransformationSystem.Client.TransformationClient import TransformationClient
35
- from DIRAC.WorkloadManagementSystem.DB.JobDB import JobDB
36
36
  from DIRAC.WorkloadManagementSystem.Service.JobPolicy import (
37
37
  RIGHT_DELETE,
38
38
  RIGHT_KILL,
@@ -65,8 +65,11 @@ class TransformationCleaningAgent(AgentModule):
65
65
  self.reqClient = None
66
66
  # # file catalog client
67
67
  self.metadataClient = None
68
- # # JobDB
68
+ # # databases
69
69
  self.jobDB = None
70
+ self.pilotAgentsDB = None
71
+ self.taskQueueDB = None
72
+ self.storageManagementDB = None
70
73
 
71
74
  # # transformations types
72
75
  self.transformationTypes = None
@@ -125,8 +128,26 @@ class TransformationCleaningAgent(AgentModule):
125
128
  self.reqClient = ReqClient()
126
129
  # # file catalog client
127
130
  self.metadataClient = FileCatalogClient()
128
- # # job DB
129
- self.jobDB = JobDB()
131
+ # # databases
132
+ result = ObjectLoader().loadObject("WorkloadManagementSystem.DB.JobDB", "JobDB")
133
+ if not result["OK"]:
134
+ return result
135
+ self.jobDB = result["Value"]()
136
+
137
+ result = ObjectLoader().loadObject("WorkloadManagementSystem.DB.PilotAgentsDB", "PilotAgentsDB")
138
+ if not result["OK"]:
139
+ return result
140
+ self.pilotAgentsDB = result["Value"]()
141
+
142
+ result = ObjectLoader().loadObject("WorkloadManagementSystem.DB.TaskQueueDB", "TaskQueueDB")
143
+ if not result["OK"]:
144
+ return result
145
+ self.taskQueueDB = result["Value"]()
146
+
147
+ result = ObjectLoader().loadObject("StorageManagementSystem.DB.StorageManagementDB", "StorageManagementDB")
148
+ if not result["OK"]:
149
+ return result
150
+ self.storageManagementDB = result["Value"]()
130
151
 
131
152
  return S_OK()
132
153
 
@@ -615,11 +636,17 @@ class TransformationCleaningAgent(AgentModule):
615
636
  :param self: self reference
616
637
  :param list trasnJobIDs: job IDs
617
638
  """
639
+ db_kwargs = dict(
640
+ jobdb=self.jobDB,
641
+ taskqueuedb=self.taskQueueDB,
642
+ pilotagentsdb=self.pilotAgentsDB,
643
+ storagemanagementdb=self.storageManagementDB,
644
+ )
618
645
  # Prevent 0 job IDs
619
646
  jobIDs = [int(j) for j in transJobIDs if int(j)]
620
647
  allRemove = True
621
648
  for jobList in breakListIntoChunks(jobIDs, 1000):
622
- res = kill_delete_jobs(RIGHT_KILL, jobList, force=True)
649
+ res = kill_delete_jobs(RIGHT_KILL, jobList, force=True, **db_kwargs)
623
650
  if res["OK"]:
624
651
  self.log.info(f"Successfully killed {len(jobList)} jobs from WMS")
625
652
  elif ("InvalidJobIDs" in res) and ("NonauthorizedJobIDs" not in res) and ("FailedJobIDs" not in res):
@@ -631,7 +658,7 @@ class TransformationCleaningAgent(AgentModule):
631
658
  self.log.error("Failed to kill jobs", f"(n={len(res['FailedJobIDs'])})")
632
659
  allRemove = False
633
660
 
634
- res = kill_delete_jobs(RIGHT_DELETE, jobList, force=True)
661
+ res = kill_delete_jobs(RIGHT_DELETE, jobList, force=True, **db_kwargs)
635
662
  if res["OK"]:
636
663
  self.log.info("Successfully deleted jobs from WMS", f"(n={len(jobList)})")
637
664
  elif ("InvalidJobIDs" in res) and ("NonauthorizedJobIDs" not in res) and ("FailedJobIDs" not in res):
@@ -17,11 +17,9 @@ from DIRAC.ConfigurationSystem.Client.Helpers import cfgPath
17
17
  from DIRAC.Core.Base.AgentModule import AgentModule
18
18
  from DIRAC.Core.Utilities import DErrno
19
19
  from DIRAC.Core.Utilities.ClassAd.ClassAdLight import ClassAd
20
+ from DIRAC.Core.Utilities.ObjectLoader import ObjectLoader
20
21
  from DIRAC.Core.Utilities.TimeUtilities import fromString, second, toEpoch
21
22
  from DIRAC.WorkloadManagementSystem.Client import JobMinorStatus, JobStatus
22
- from DIRAC.WorkloadManagementSystem.DB.JobDB import JobDB
23
- from DIRAC.WorkloadManagementSystem.DB.JobLoggingDB import JobLoggingDB
24
- from DIRAC.WorkloadManagementSystem.DB.PilotAgentsDB import PilotAgentsDB
25
23
  from DIRAC.WorkloadManagementSystem.Service.JobPolicy import RIGHT_KILL
26
24
  from DIRAC.WorkloadManagementSystem.DB.StatusUtils import kill_delete_jobs
27
25
  from DIRAC.WorkloadManagementSystem.Utilities.JobParameters import getJobParameters
@@ -40,6 +38,9 @@ class StalledJobAgent(AgentModule):
40
38
 
41
39
  self.jobDB = None
42
40
  self.logDB = None
41
+ self.taskQueueDB = None
42
+ self.pilotAgentsDB = None
43
+ self.storageManagementDB = None
43
44
  self.matchedTime = 7200
44
45
  self.rescheduledTime = 600
45
46
  self.submittingTime = 300
@@ -51,8 +52,30 @@ class StalledJobAgent(AgentModule):
51
52
  #############################################################################
52
53
  def initialize(self):
53
54
  """Sets default parameters."""
54
- self.jobDB = JobDB()
55
- self.logDB = JobLoggingDB()
55
+ result = ObjectLoader().loadObject("WorkloadManagementSystem.DB.JobDB", "JobDB")
56
+ if not result["OK"]:
57
+ return result
58
+ self.jobDB = result["Value"]()
59
+
60
+ result = ObjectLoader().loadObject("WorkloadManagementSystem.DB.JobLoggingDB", "JobLoggingDB")
61
+ if not result["OK"]:
62
+ return result
63
+ self.logDB = result["Value"]()
64
+
65
+ result = ObjectLoader().loadObject("WorkloadManagementSystem.DB.TaskQueueDB", "TaskQueueDB")
66
+ if not result["OK"]:
67
+ return result
68
+ self.taskQueueDB = result["Value"]()
69
+
70
+ result = ObjectLoader().loadObject("WorkloadManagementSystem.DB.PilotAgentsDB", "PilotAgentsDB")
71
+ if not result["OK"]:
72
+ return result
73
+ self.pilotAgentsDB = result["Value"]()
74
+
75
+ result = ObjectLoader().loadObject("StorageManagementSystem.DB.StorageManagementDB", "StorageManagementDB")
76
+ if not result["OK"]:
77
+ return result
78
+ self.storageManagementDB = result["Value"]()
56
79
 
57
80
  # getting parameters
58
81
 
@@ -235,7 +258,16 @@ class StalledJobAgent(AgentModule):
235
258
  # Set the jobs Failed, send them a kill signal in case they are not really dead
236
259
  # and send accounting info
237
260
  if setFailed:
238
- res = kill_delete_jobs(RIGHT_KILL, [jobID], nonauthJobList=[], force=True)
261
+ res = kill_delete_jobs(
262
+ RIGHT_KILL,
263
+ [jobID],
264
+ nonauthJobList=[],
265
+ force=True,
266
+ jobdb=self.jobDB,
267
+ taskqueuedb=self.taskQueueDB,
268
+ pilotagentsdb=self.pilotAgentsDB,
269
+ storagemanagementdb=self.storageManagementDB,
270
+ )
239
271
  if not res["OK"]:
240
272
  self.log.error("Failed to kill job", jobID)
241
273
 
@@ -262,7 +294,7 @@ class StalledJobAgent(AgentModule):
262
294
  # There is no pilot reference, hence its status is unknown
263
295
  return S_OK("NoPilot")
264
296
 
265
- result = PilotAgentsDB().getPilotInfo(pilotReference)
297
+ result = self.pilotAgentsDB.getPilotInfo(pilotReference)
266
298
  if not result["OK"]:
267
299
  if DErrno.cmpError(result, DErrno.EWMSNOPILOT):
268
300
  self.log.warn("No pilot found", f"for job {jobID}: {result['Message']}")
@@ -23,10 +23,31 @@ def sja(mocker):
23
23
  side_effect=lambda x, y=None: y,
24
24
  create=True,
25
25
  )
26
- mocker.patch("DIRAC.WorkloadManagementSystem.Agent.StalledJobAgent.JobDB")
27
- mocker.patch("DIRAC.WorkloadManagementSystem.Agent.StalledJobAgent.JobLoggingDB")
26
+
27
+ # Mock ObjectLoader to return mock DB instances
28
+ mockJobDB = MagicMock()
29
+ mockJobDB.log = gLogger
30
+ mockJobLoggingDB = MagicMock()
31
+ mockTaskQueueDB = MagicMock()
32
+ mockPilotAgentsDB = MagicMock()
33
+ mockStorageManagementDB = MagicMock()
34
+
35
+ def mock_load_object(module_path, class_name):
36
+ mocks = {
37
+ "JobDB": mockJobDB,
38
+ "JobLoggingDB": mockJobLoggingDB,
39
+ "TaskQueueDB": mockTaskQueueDB,
40
+ "PilotAgentsDB": mockPilotAgentsDB,
41
+ "StorageManagementDB": mockStorageManagementDB,
42
+ }
43
+ return {"OK": True, "Value": lambda: mocks[class_name]}
44
+
45
+ mocker.patch(
46
+ "DIRAC.WorkloadManagementSystem.Agent.StalledJobAgent.ObjectLoader.loadObject",
47
+ side_effect=mock_load_object,
48
+ )
49
+
28
50
  mocker.patch("DIRAC.WorkloadManagementSystem.Agent.StalledJobAgent.rescheduleJobs", return_value=MagicMock())
29
- mocker.patch("DIRAC.WorkloadManagementSystem.Agent.StalledJobAgent.PilotAgentsDB", return_value=MagicMock())
30
51
  mocker.patch("DIRAC.WorkloadManagementSystem.Agent.StalledJobAgent.getJobParameters", return_value=MagicMock())
31
52
  mocker.patch("DIRAC.WorkloadManagementSystem.Agent.StalledJobAgent.kill_delete_jobs", return_value=MagicMock())
32
53
 
@@ -34,7 +55,6 @@ def sja(mocker):
34
55
  stalledJobAgent._AgentModule__configDefaults = mockAM
35
56
  stalledJobAgent.log = gLogger
36
57
  stalledJobAgent.initialize()
37
- stalledJobAgent.jobDB.log = gLogger
38
58
  stalledJobAgent.log.setLevel("DEBUG")
39
59
  stalledJobAgent.stalledTime = 120
40
60
 
@@ -1,43 +1,40 @@
1
1
  from DIRAC import S_ERROR, S_OK, gLogger
2
- from DIRAC.StorageManagementSystem.DB.StorageManagementDB import StorageManagementDB
3
2
  from DIRAC.WorkloadManagementSystem.Client import JobStatus
4
- from DIRAC.WorkloadManagementSystem.DB.JobDB import JobDB
5
- from DIRAC.WorkloadManagementSystem.DB.PilotAgentsDB import PilotAgentsDB
6
- from DIRAC.WorkloadManagementSystem.DB.TaskQueueDB import TaskQueueDB
3
+ from DIRAC.Core.Utilities.ObjectLoader import ObjectLoader
7
4
  from DIRAC.WorkloadManagementSystem.Service.JobPolicy import RIGHT_DELETE, RIGHT_KILL
8
5
  from DIRAC.WorkloadManagementSystem.Utilities.jobAdministration import _filterJobStateTransition
9
6
 
10
7
 
11
- def _deleteJob(jobID, force=False):
8
+ def _deleteJob(jobID, force=False, *, jobdb, taskqueuedb, pilotagentsdb):
12
9
  """Set the job status to "Deleted"
13
10
  and remove the pilot that ran and its logging info if the pilot is finished.
14
11
 
15
12
  :param int jobID: job ID
16
13
  :return: S_OK()/S_ERROR()
17
14
  """
18
- if not (result := JobDB().setJobStatus(jobID, JobStatus.DELETED, "Checking accounting", force=force))["OK"]:
15
+ if not (result := jobdb.setJobStatus(jobID, JobStatus.DELETED, "Checking accounting", force=force))["OK"]:
19
16
  gLogger.warn("Failed to set job Deleted status", result["Message"])
20
17
  return result
21
18
 
22
- if not (result := TaskQueueDB().deleteJob(jobID))["OK"]:
19
+ if not (result := taskqueuedb.deleteJob(jobID))["OK"]:
23
20
  gLogger.warn("Failed to delete job from the TaskQueue")
24
21
 
25
22
  # if it was the last job for the pilot
26
- result = PilotAgentsDB().getPilotsForJobID(jobID)
23
+ result = pilotagentsdb.getPilotsForJobID(jobID)
27
24
  if not result["OK"]:
28
25
  gLogger.error("Failed to get Pilots for JobID", result["Message"])
29
26
  return result
30
27
  for pilot in result["Value"]:
31
- res = PilotAgentsDB().getJobsForPilot(pilot)
28
+ res = pilotagentsdb.getJobsForPilot(pilot)
32
29
  if not res["OK"]:
33
30
  gLogger.error("Failed to get jobs for pilot", res["Message"])
34
31
  return res
35
32
  if not res["Value"]: # if list of jobs for pilot is empty, delete pilot
36
- result = PilotAgentsDB().getPilotInfo(pilotID=pilot)
33
+ result = pilotagentsdb.getPilotInfo(pilotID=pilot)
37
34
  if not result["OK"]:
38
35
  gLogger.error("Failed to get pilot info", result["Message"])
39
36
  return result
40
- ret = PilotAgentsDB().deletePilot(result["Value"]["PilotJobReference"])
37
+ ret = pilotagentsdb.deletePilot(result["Value"]["PilotJobReference"])
41
38
  if not ret["OK"]:
42
39
  gLogger.error("Failed to delete pilot from PilotAgentsDB", ret["Message"])
43
40
  return ret
@@ -45,7 +42,7 @@ def _deleteJob(jobID, force=False):
45
42
  return S_OK()
46
43
 
47
44
 
48
- def _killJob(jobID, sendKillCommand=True, force=False):
45
+ def _killJob(jobID, sendKillCommand=True, force=False, *, jobdb, taskqueuedb):
49
46
  """Kill one job
50
47
 
51
48
  :param int jobID: job ID
@@ -54,32 +51,63 @@ def _killJob(jobID, sendKillCommand=True, force=False):
54
51
  :return: S_OK()/S_ERROR()
55
52
  """
56
53
  if sendKillCommand:
57
- if not (result := JobDB().setJobCommand(jobID, "Kill"))["OK"]:
54
+ if not (result := jobdb.setJobCommand(jobID, "Kill"))["OK"]:
58
55
  gLogger.warn("Failed to set job Kill command", result["Message"])
59
56
  return result
60
57
 
61
58
  gLogger.info("Job marked for termination", jobID)
62
- if not (result := JobDB().setJobStatus(jobID, JobStatus.KILLED, "Marked for termination", force=force))["OK"]:
59
+ if not (result := jobdb.setJobStatus(jobID, JobStatus.KILLED, "Marked for termination", force=force))["OK"]:
63
60
  gLogger.warn("Failed to set job Killed status", result["Message"])
64
- if not (result := TaskQueueDB().deleteJob(jobID))["OK"]:
61
+ if not (result := taskqueuedb.deleteJob(jobID))["OK"]:
65
62
  gLogger.warn("Failed to delete job from the TaskQueue", result["Message"])
66
63
 
67
64
  return S_OK()
68
65
 
69
66
 
70
- def kill_delete_jobs(right, validJobList, nonauthJobList=[], force=False):
67
+ def kill_delete_jobs(
68
+ right,
69
+ validJobList,
70
+ nonauthJobList=[],
71
+ force=False,
72
+ *,
73
+ jobdb=None,
74
+ taskqueuedb=None,
75
+ pilotagentsdb=None,
76
+ storagemanagementdb=None,
77
+ ):
71
78
  """Kill (== set the status to "KILLED") or delete (== set the status to "DELETED") jobs as necessary
72
79
 
73
80
  :param str right: RIGHT_KILL or RIGHT_DELETE
74
81
 
75
82
  :return: S_OK()/S_ERROR()
76
83
  """
84
+ if jobdb is None:
85
+ result = ObjectLoader().loadObject("WorkloadManagementSystem.DB.JobDB", "JobDB")
86
+ if not result["OK"]:
87
+ return result
88
+ jobdb = result["Value"]()
89
+ if taskqueuedb is None:
90
+ result = ObjectLoader().loadObject("WorkloadManagementSystem.DB.TaskQueueDB", "TaskQueueDB")
91
+ if not result["OK"]:
92
+ return result
93
+ taskqueuedb = result["Value"]()
94
+ if pilotagentsdb is None:
95
+ result = ObjectLoader().loadObject("WorkloadManagementSystem.DB.PilotAgentsDB", "PilotAgentsDB")
96
+ if not result["OK"]:
97
+ return result
98
+ pilotagentsdb = result["Value"]()
99
+ if storagemanagementdb is None:
100
+ result = ObjectLoader().loadObject("StorageManagementSystem.DB.StorageManagementDB", "StorageManagementDB")
101
+ if not result["OK"]:
102
+ return result
103
+ storagemanagementdb = result["Value"]()
104
+
77
105
  badIDs = []
78
106
 
79
107
  killJobList = []
80
108
  deleteJobList = []
81
109
  if validJobList:
82
- result = JobDB().getJobsAttributes(validJobList, ["Status"])
110
+ result = jobdb.getJobsAttributes(validJobList, ["Status"])
83
111
  if not result["OK"]:
84
112
  return result
85
113
  jobStates = result["Value"]
@@ -92,12 +120,12 @@ def kill_delete_jobs(right, validJobList, nonauthJobList=[], force=False):
92
120
  deleteJobList.extend(_filterJobStateTransition(jobStates, JobStatus.DELETED))
93
121
 
94
122
  for jobID in killJobList:
95
- result = _killJob(jobID, force=force)
123
+ result = _killJob(jobID, force=force, jobdb=jobdb, taskqueuedb=taskqueuedb)
96
124
  if not result["OK"]:
97
125
  badIDs.append(jobID)
98
126
 
99
127
  for jobID in deleteJobList:
100
- result = _deleteJob(jobID, force=force)
128
+ result = _deleteJob(jobID, force=force, jobdb=jobdb, taskqueuedb=taskqueuedb, pilotagentsdb=pilotagentsdb)
101
129
  if not result["OK"]:
102
130
  badIDs.append(jobID)
103
131
 
@@ -105,9 +133,8 @@ def kill_delete_jobs(right, validJobList, nonauthJobList=[], force=False):
105
133
  stagingJobList = [jobID for jobID, sDict in jobStates.items() if sDict["Status"] == JobStatus.STAGING]
106
134
 
107
135
  if stagingJobList:
108
- stagerDB = StorageManagementDB()
109
136
  gLogger.info("Going to send killing signal to stager as well!")
110
- result = stagerDB.killTasksBySourceTaskID(stagingJobList)
137
+ result = storagemanagementdb.killTasksBySourceTaskID(stagingJobList)
111
138
  if not result["OK"]:
112
139
  gLogger.warn("Failed to kill some Stager tasks", result["Message"])
113
140
 
@@ -19,10 +19,25 @@ from DIRAC.WorkloadManagementSystem.DB.StatusUtils import kill_delete_jobs
19
19
  ],
20
20
  )
21
21
  def test___kill_delete_jobs(mocker, jobIDs_list, right):
22
- mocker.patch("DIRAC.WorkloadManagementSystem.DB.StatusUtils.JobDB", MagicMock())
23
- mocker.patch("DIRAC.WorkloadManagementSystem.DB.StatusUtils.TaskQueueDB", MagicMock())
24
- mocker.patch("DIRAC.WorkloadManagementSystem.DB.StatusUtils.PilotAgentsDB", MagicMock())
25
- mocker.patch("DIRAC.WorkloadManagementSystem.DB.StatusUtils.StorageManagementDB", MagicMock())
22
+ # Mock ObjectLoader to return mock DB instances
23
+ mockJobDB = MagicMock()
24
+ mockTaskQueueDB = MagicMock()
25
+ mockPilotAgentsDB = MagicMock()
26
+ mockStorageManagementDB = MagicMock()
27
+
28
+ def mock_load_object(module_path, class_name):
29
+ mocks = {
30
+ "JobDB": mockJobDB,
31
+ "TaskQueueDB": mockTaskQueueDB,
32
+ "PilotAgentsDB": mockPilotAgentsDB,
33
+ "StorageManagementDB": mockStorageManagementDB,
34
+ }
35
+ return {"OK": True, "Value": lambda: mocks[class_name]}
36
+
37
+ mocker.patch(
38
+ "DIRAC.WorkloadManagementSystem.DB.StatusUtils.ObjectLoader.loadObject",
39
+ side_effect=mock_load_object,
40
+ )
26
41
 
27
42
  res = kill_delete_jobs(right, jobIDs_list)
28
43
  assert res["OK"]
@@ -65,6 +65,11 @@ class JobManagerHandlerMixin:
65
65
  return result
66
66
  cls.pilotAgentsDB = result["Value"](parentLogger=cls.log)
67
67
 
68
+ result = ObjectLoader().loadObject("StorageManagementSystem.DB.StorageManagementDB", "StorageManagementDB")
69
+ if not result["OK"]:
70
+ return result
71
+ cls.storageManagementDB = result["Value"](parentLogger=cls.log)
72
+
68
73
  except RuntimeError as excp:
69
74
  return S_ERROR(f"Can't connect to DB: {excp!r}")
70
75
 
@@ -449,7 +454,16 @@ class JobManagerHandlerMixin:
449
454
  jobList, RIGHT_DELETE
450
455
  )
451
456
 
452
- result = kill_delete_jobs(RIGHT_DELETE, validJobList, nonauthJobList, force=force)
457
+ result = kill_delete_jobs(
458
+ RIGHT_DELETE,
459
+ validJobList,
460
+ nonauthJobList,
461
+ force=force,
462
+ jobdb=self.jobDB,
463
+ taskqueuedb=self.taskQueueDB,
464
+ pilotagentsdb=self.pilotAgentsDB,
465
+ storagemanagementdb=self.storageManagementDB,
466
+ )
453
467
 
454
468
  result["requireProxyUpload"] = len(ownerJobList) > 0 and self.__checkIfProxyUploadIsRequired()
455
469
 
@@ -478,7 +492,16 @@ class JobManagerHandlerMixin:
478
492
  jobList, RIGHT_KILL
479
493
  )
480
494
 
481
- result = kill_delete_jobs(RIGHT_KILL, validJobList, nonauthJobList, force=force)
495
+ result = kill_delete_jobs(
496
+ RIGHT_KILL,
497
+ validJobList,
498
+ nonauthJobList,
499
+ force=force,
500
+ jobdb=self.jobDB,
501
+ taskqueuedb=self.taskQueueDB,
502
+ pilotagentsdb=self.pilotAgentsDB,
503
+ storagemanagementdb=self.storageManagementDB,
504
+ )
482
505
 
483
506
  result["requireProxyUpload"] = len(ownerJobList) > 0 and self.__checkIfProxyUploadIsRequired()
484
507
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: DIRAC
3
- Version: 9.0.10
3
+ Version: 9.0.11
4
4
  Summary: DIRAC is an interware, meaning a software framework for distributed computing.
5
5
  Home-page: https://github.com/DIRACGrid/DIRAC/
6
6
  License: GPL-3.0-only
@@ -19,7 +19,7 @@ Requires-Dist: cachetools
19
19
  Requires-Dist: certifi
20
20
  Requires-Dist: cwltool
21
21
  Requires-Dist: diraccfg
22
- Requires-Dist: DIRACCommon==v9.0.10
22
+ Requires-Dist: DIRACCommon==v9.0.11
23
23
  Requires-Dist: diracx-client>=v0.0.1
24
24
  Requires-Dist: diracx-core>=v0.0.1
25
25
  Requires-Dist: diracx-cli>=v0.0.1
@@ -508,7 +508,7 @@ DIRAC/FrameworkSystem/Client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NM
508
508
  DIRAC/FrameworkSystem/Client/test/Test_ComponentInstaller.py,sha256=OUIbwU5ypLpSDA-LhSlK-_Z3wPV_ZBMk5n4Y_jiipd0,505
509
509
  DIRAC/FrameworkSystem/DB/AuthDB.py,sha256=QLotpINMq45FNoFO2AV3OH5Ij5i__HHk-p-m-b_ieaQ,11938
510
510
  DIRAC/FrameworkSystem/DB/AuthDB.sql,sha256=tcAnRmBBEDxljAXILp8tlLzuEb7vOoN190KQK7NSbQQ,95
511
- DIRAC/FrameworkSystem/DB/InstalledComponentsDB.py,sha256=rVarVs61K1kPHZIf1U_kfia-5pxR5uSXsuDutr8EcFY,43156
511
+ DIRAC/FrameworkSystem/DB/InstalledComponentsDB.py,sha256=ZmDW-gXKg7syzCNo53zELYMM8vtz7vz2LlMYUh69_fs,43156
512
512
  DIRAC/FrameworkSystem/DB/InstalledComponentsDB.sql,sha256=-LFjjn1gRQo7zDOclKmFwmbZi_lXXnx_B17cZPLBUak,113
513
513
  DIRAC/FrameworkSystem/DB/ProxyDB.py,sha256=wt72y-ZtHyes1oLGgB-LiLuyZRNBelmCaEijad3raxI,39934
514
514
  DIRAC/FrameworkSystem/DB/ProxyDB.sql,sha256=QwWe_mRX_NbZQVBo3TzA60L3FemI-oLY8G7_4uRFPzU,96
@@ -531,7 +531,7 @@ DIRAC/FrameworkSystem/Service/TornadoTokenManagerHandler.py,sha256=9DnxtK0Tam_9W
531
531
  DIRAC/FrameworkSystem/Service/TornadoUserProfileManagerHandler.py,sha256=9z8Vky8YJ0reR_5E6RtxStakfg22qiGCvq-tUjojRzo,559
532
532
  DIRAC/FrameworkSystem/Service/UserProfileManagerHandler.py,sha256=DyZFvqFeKjxVYNXqGYLkTlYgj3raUsfsb68GE4FX5x4,5707
533
533
  DIRAC/FrameworkSystem/Service/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
534
- DIRAC/FrameworkSystem/Utilities/MonitoringUtilities.py,sha256=wt6QhJ6A_ifRP8kAgRWo-vtS_jJa8e5Xi9GdrRuA-i8,2556
534
+ DIRAC/FrameworkSystem/Utilities/MonitoringUtilities.py,sha256=QS3hVXVsanmm1NsevY_D5KeBR_xjJinVBzRJhleBbao,2590
535
535
  DIRAC/FrameworkSystem/Utilities/TokenManagementUtilities.py,sha256=eEeKs9JMJOiokjDtDcRlyQiRWIM1TNYwcVy1C4oozuY,3034
536
536
  DIRAC/FrameworkSystem/Utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
537
537
  DIRAC/FrameworkSystem/Utilities/diracx.py,sha256=cyHtKuRY-maOUmY96uhj5sEKzb6nTEhNvOd2LlDhp18,3647
@@ -906,14 +906,14 @@ DIRAC/Resources/Computing/ComputingElement.py,sha256=lAvlx7AOtkftku6sekIaEK4Wp_G
906
906
  DIRAC/Resources/Computing/ComputingElementFactory.py,sha256=gaYP8TvvP7OJsL2o6IMTIYYoBn6flt3Ue7f1NX4HmNY,2541
907
907
  DIRAC/Resources/Computing/HTCondorCEComputingElement.py,sha256=zEekKBBcbAsUgZVU6H7zOKFaV3AzS549uHnEAK61nMo,26146
908
908
  DIRAC/Resources/Computing/InProcessComputingElement.py,sha256=6PTGQrAB7ROuTrO1Eq86fmDduf6IrkVInjSMzXb00eM,4620
909
- DIRAC/Resources/Computing/LocalComputingElement.py,sha256=om4cH89cZANy6VF2sYeLhmESs5XVPCpEOLFckusdAxw,12533
909
+ DIRAC/Resources/Computing/LocalComputingElement.py,sha256=pELd0UjXTNz4LcnSZOkwG-TI07vljm9qRombAfmgHHg,12404
910
910
  DIRAC/Resources/Computing/PoolComputingElement.py,sha256=QzU7R_1lmZ67lhiQseNvW493fgBL8tOkqBZxZMrFsBE,10404
911
911
  DIRAC/Resources/Computing/SSHBatchComputingElement.py,sha256=3ZEK6AkorZM0Ko32VKrcJ-ywTR0hkn5fBuGrJruEbA4,5953
912
- DIRAC/Resources/Computing/SSHComputingElement.py,sha256=Sy-Ab2Q_honFRt4Oj_Veh7uqsBAZISCIKGjW75bs0Nw,31482
912
+ DIRAC/Resources/Computing/SSHComputingElement.py,sha256=bBzIkwVNQLgL3NF0wTCur_WudRLLmoGU-RknWQ6aVXs,32669
913
913
  DIRAC/Resources/Computing/SingularityComputingElement.py,sha256=6bWkSEmPMV85JeKiqn1Q151QaG5rcW61-mnIU_MUj2A,17880
914
914
  DIRAC/Resources/Computing/__init__.py,sha256=S0glZLs-Q2srpRLELQPDHSB9CVAcBXrPnQsFi-ZsokM,43
915
915
  DIRAC/Resources/Computing/cloudinit.template,sha256=gF4yOILXXWjlrs3bcazLA2Wf2n7QYkebMcaD_kNWK5I,4025
916
- DIRAC/Resources/Computing/BatchSystems/Condor.py,sha256=58U5VbtX6XmGtefVavTtvGaVvXl_3z8xdU5Sa9nX3dI,13898
916
+ DIRAC/Resources/Computing/BatchSystems/Condor.py,sha256=CfKZOQqBkX-L4MQfQmVcMuLDkWVe-whG1ZU-FR5Q2Jk,13699
917
917
  DIRAC/Resources/Computing/BatchSystems/GE.py,sha256=XkumJZPMgqxJr3qJc5EmLXOzrfKZSKuUPKZjPumTC1U,9170
918
918
  DIRAC/Resources/Computing/BatchSystems/Host.py,sha256=NmCIn6e5ZUiXiX1qIke-3G5dEEDXUznASvfIoP8Vx5U,9638
919
919
  DIRAC/Resources/Computing/BatchSystems/LSF.py,sha256=ujM4Fd22WdwM3VZgxtxXRhdV-izDkmSDbaS8Cd7YUEs,7218
@@ -921,7 +921,7 @@ DIRAC/Resources/Computing/BatchSystems/OAR.py,sha256=uC1a4-n704bvUWhQr07QLqUMliu
921
921
  DIRAC/Resources/Computing/BatchSystems/SLURM.py,sha256=tRRRq4xHyPJdWI4yno3y1PClMN53AQeLhYGKUnab5es,13934
922
922
  DIRAC/Resources/Computing/BatchSystems/Torque.py,sha256=x35hOMt1mrCWzPdK8Pg3cipuT6y2wyGCG6HH2cbve9k,8112
923
923
  DIRAC/Resources/Computing/BatchSystems/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
924
- DIRAC/Resources/Computing/BatchSystems/executeBatch.py,sha256=E6jW8iK9LYyWpfUSWfPczQjjDGARFBIS1uHnVI_DyPw,1432
924
+ DIRAC/Resources/Computing/BatchSystems/executeBatch.py,sha256=onNjUUMntETJ2Z4Zz0EeHEs2cIojMWaaTf07oUId0n0,1695
925
925
  DIRAC/Resources/Computing/BatchSystems/TimeLeft/HTCondorResourceUsage.py,sha256=sqQLPVC9FIqV5twEcIZFJiHr7G02eddVrdvj-eCL44E,2440
926
926
  DIRAC/Resources/Computing/BatchSystems/TimeLeft/LSFResourceUsage.py,sha256=xBb6HYllb2bcVN-YtX4OS7rUtIRQlqEpOTKezWBrtRk,11290
927
927
  DIRAC/Resources/Computing/BatchSystems/TimeLeft/PBSResourceUsage.py,sha256=7aZa28OO4VIu0cono_xqIuFg9VNzaMDYJwqENNky9uY,5324
@@ -1053,7 +1053,7 @@ DIRAC/TransformationSystem/Agent/RequestTaskAgent.py,sha256=0FxuRVONDkC6DtDqfSC4
1053
1053
  DIRAC/TransformationSystem/Agent/TaskManagerAgentBase.py,sha256=I1DGxItHZ_nYs1_cGZTTrsts01rQl2_JuBHtYTljTGw,30737
1054
1054
  DIRAC/TransformationSystem/Agent/TransformationAgent.py,sha256=rUPyfX_Ip3ZUyBrmVBrYiddVmgeTx6gKiYPEzwUDOcY,33813
1055
1055
  DIRAC/TransformationSystem/Agent/TransformationAgentsUtilities.py,sha256=XrgrjQWSDQm0uxG-wyEY-W0A_MBJyIE-22TafqrLP3A,2805
1056
- DIRAC/TransformationSystem/Agent/TransformationCleaningAgent.py,sha256=FyEOWtp8_ZIMCEh1RYqLOENnB--unmKy6gmZkgLb7cM,33251
1056
+ DIRAC/TransformationSystem/Agent/TransformationCleaningAgent.py,sha256=Hj2XSW835kVhX8MzuBmPE4es4suK4zmOo5xSTXaMaSE,34392
1057
1057
  DIRAC/TransformationSystem/Agent/TransformationPlugin.py,sha256=EpWil1Bla9xdrJkhj61oUFDpGzyWfC8acW3tjBh5JpQ,11322
1058
1058
  DIRAC/TransformationSystem/Agent/ValidateOutputDataAgent.py,sha256=YzjUVECnWYvJ2zQyqMqRa4BZLqq2FUulXnI4tO6HlpU,10190
1059
1059
  DIRAC/TransformationSystem/Agent/WorkflowTaskAgent.py,sha256=UBNVVx0ZgiFnzAPCNC1dSuJXKkt2pPfpSqhy0CREFlg,1741
@@ -1128,7 +1128,7 @@ DIRAC/WorkloadManagementSystem/Agent/PilotStatusAgent.py,sha256=qY6TbYCPOFFXhHff
1128
1128
  DIRAC/WorkloadManagementSystem/Agent/PilotSyncAgent.py,sha256=qzDFCGZ8EtjxDUaPgyFDlSmJfyF2KLuyXTC7au3-p2Q,4860
1129
1129
  DIRAC/WorkloadManagementSystem/Agent/PushJobAgent.py,sha256=IvHshnw2xN0AZrruEu86C47GDez8enBD6jjNIZd6QcA,38594
1130
1130
  DIRAC/WorkloadManagementSystem/Agent/SiteDirector.py,sha256=ZSGWVKO64ztnv_R19I6TT7660jf7LMuYcff_aPq2xCM,45162
1131
- DIRAC/WorkloadManagementSystem/Agent/StalledJobAgent.py,sha256=foEbmRotEmfeQG6nyIsJv1kSJkm4flkQsPYbSylS3SM,24572
1131
+ DIRAC/WorkloadManagementSystem/Agent/StalledJobAgent.py,sha256=WCvG1nkzyv79m-jN78GE5J-1NgUVdJfRqofGaqMf7wY,25758
1132
1132
  DIRAC/WorkloadManagementSystem/Agent/StatesAccountingAgent.py,sha256=iNIlWQEDBk6R1S8oHOIusZUwxOwLtgwuzR_4s32-o5w,8707
1133
1133
  DIRAC/WorkloadManagementSystem/Agent/TaskQueuesAgent.py,sha256=ypsmo233TFXq9IC5uz6pum7_joOh2gFPUYNmmCpukAY,943
1134
1134
  DIRAC/WorkloadManagementSystem/Agent/__init__.py,sha256=Pp2qIXA0zZxJXBQwPEDUt23Y_ct5cjs77w8ZEV6Ll6M,56
@@ -1138,7 +1138,7 @@ DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_PilotLoggingAgent.py,sha256
1138
1138
  DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_PilotStatusAgent.py,sha256=qOA_U2NYvJprLdrUJirbEVSnvEF9-FuRXNi78MBoffc,2806
1139
1139
  DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_PushJobAgent.py,sha256=Uf5jlnw8mWvQJcOnJXEASEf3Ryo63wZKv8IavQVaOVY,14887
1140
1140
  DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_SiteDirector.py,sha256=o6imUULkKrvbmkfpvER8wyg0Ncn3gxvJNTNO8xKX7_w,11670
1141
- DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_StalledJobAgent.py,sha256=BgDP1um-5WLSJYDbyHgLUkZocN8TrrG6QvRcffzD02E,1829
1141
+ DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_StalledJobAgent.py,sha256=_4Y-itXpXw3Gjxy0CII3rBk-tgAUDesNcQuSsLDyksw,2293
1142
1142
  DIRAC/WorkloadManagementSystem/Client/CPUNormalization.py,sha256=txBgRfnTAY5KykpKRrK1jp5x4FInWjv-Rja4R7Dqdis,5423
1143
1143
  DIRAC/WorkloadManagementSystem/Client/DownloadInputData.py,sha256=Ug2mhig5KbC1d4fYsVLpFhE5SvWhUJpVp7TuP8GxJxs,16285
1144
1144
  DIRAC/WorkloadManagementSystem/Client/InputDataByProtocol.py,sha256=tjK6L8iNqWOBENcGJbG0yJsQYwGvFLRFcTMNnrusFAI,12837
@@ -1186,12 +1186,12 @@ DIRAC/WorkloadManagementSystem/DB/PilotAgentsDB.py,sha256=tUSuhv59CQgB7NkxsXo5r-
1186
1186
  DIRAC/WorkloadManagementSystem/DB/PilotAgentsDB.sql,sha256=RnCDCDGa__7sDxjSFGlu_5OwKbzxeK3a9TOMpV5ftRw,2738
1187
1187
  DIRAC/WorkloadManagementSystem/DB/SandboxMetadataDB.py,sha256=L_ywrVuoKlZpx07xydRY1JbMjj5-UteB1Eg8fJKF6CI,15615
1188
1188
  DIRAC/WorkloadManagementSystem/DB/SandboxMetadataDB.sql,sha256=2TcyLiewFuPWqBhD43geHG0obCFRGTSLbQwPUwENYnQ,23
1189
- DIRAC/WorkloadManagementSystem/DB/StatusUtils.py,sha256=cVVNiZlVbp0B-4MpkpXATlSLRtubsL6iGx4-U4KP2A4,5125
1189
+ DIRAC/WorkloadManagementSystem/DB/StatusUtils.py,sha256=oiqxa0DrgakejtXwUFoFnUjwOwxqWQMyU6rIRIKP440,6039
1190
1190
  DIRAC/WorkloadManagementSystem/DB/TaskQueueDB.py,sha256=4ClljoQUnHKq1KHAIFpUwL_5-NrUUuM8oHKzOZULXZg,54623
1191
1191
  DIRAC/WorkloadManagementSystem/DB/TaskQueueDB.sql,sha256=GfeceE3VY7l15pMwt6MzI8pGqdk772XuIg_DE0vkj74,541
1192
1192
  DIRAC/WorkloadManagementSystem/DB/__init__.py,sha256=1H5briNEaZlSL6pMxzjDmkZkVvGxHix8DtfkM-mOwGc,53
1193
1193
  DIRAC/WorkloadManagementSystem/DB/tests/Test_JobDB.py,sha256=PppmPBWFKQMeNUZXHcfl07hVu7hdrJcqFXFloXO2JMU,1068
1194
- DIRAC/WorkloadManagementSystem/DB/tests/Test_StatusUtils.py,sha256=nibKxynwLdJZafC0k01oE1FwOFgSlEMw2hUlrlacwEo,845
1194
+ DIRAC/WorkloadManagementSystem/DB/tests/Test_StatusUtils.py,sha256=M65KFhdgTUo_aEZMcs65Q_h5JVRq3QsPVV_OTaIXFIk,1141
1195
1195
  DIRAC/WorkloadManagementSystem/DB/tests/Test_TaskQueueDB.py,sha256=QWGxTbGez9wojkHzbpqksdKc6I6_X-Dh49tXB8gxc8s,6368
1196
1196
  DIRAC/WorkloadManagementSystem/Executor/InputData.py,sha256=ybhBMXkXf1JxLYKpNCAiyvtoiAICzvrm4UOnMSurmVA,18049
1197
1197
  DIRAC/WorkloadManagementSystem/Executor/JobPath.py,sha256=ovsRPGQiPixnTBsK4WRTZ2wqeXazK_tEloSgNwAtF80,2511
@@ -1221,7 +1221,7 @@ DIRAC/WorkloadManagementSystem/JobWrapper/test/script-RESC.sh,sha256=kiY-Af9a1bs
1221
1221
  DIRAC/WorkloadManagementSystem/JobWrapper/test/script-fail.sh,sha256=f1R0qtgJgOI3AbEoxGBqN8ClA6Y8Bz8tHlBXrxjySDs,63
1222
1222
  DIRAC/WorkloadManagementSystem/JobWrapper/test/script-long.sh,sha256=yzaSDg7P5hGv9SSCBsl8FLuj6-udCcpd0qId9kSv4Nc,41
1223
1223
  DIRAC/WorkloadManagementSystem/JobWrapper/test/script.sh,sha256=fbYLJJTVw9K7f9NdMvW_a-NkBI6SPup4NebPFYFKsbQ,9
1224
- DIRAC/WorkloadManagementSystem/Service/JobManagerHandler.py,sha256=flr1tqCQpRKb0u-RMBdCxqJJ4Ns-XL6XxPlbteRClCY,21098
1224
+ DIRAC/WorkloadManagementSystem/Service/JobManagerHandler.py,sha256=sUNdlsf5sI8GG3yjasSw5GO9OwVGGYIQA1a0Prl9Jd0,21828
1225
1225
  DIRAC/WorkloadManagementSystem/Service/JobMonitoringHandler.py,sha256=sFJOme3KDLeAppH_AF5dTt8om_g_zUSQvPnIs9BAQkc,7586
1226
1226
  DIRAC/WorkloadManagementSystem/Service/JobPolicy.py,sha256=o88xR3roe_JRB5F53oxb1LIuqY2qCCw6w5njprrJFMI,8057
1227
1227
  DIRAC/WorkloadManagementSystem/Service/JobStateUpdateHandler.py,sha256=TiSnLQTNd-HgAhPoqwebzN6G95pVXXgETJ5Hbw29XnY,9226
@@ -1296,9 +1296,9 @@ DIRAC/tests/Workflow/Integration/exe-script.py,sha256=B_slYdTocEzqfQLRhwuPiLyYUn
1296
1296
  DIRAC/tests/Workflow/Integration/helloWorld.py,sha256=tBgEHH3ZF7ZiTS57gtmm3DW-Qxgm_57HWHpM-Y8XSws,205
1297
1297
  DIRAC/tests/Workflow/Regression/helloWorld.py,sha256=69eCgFuVSYo-mK3Dj2dw1c6g86sF5FksKCf8V2aGVoM,509
1298
1298
  DIRAC/tests/Workflow/Regression/helloWorld.xml,sha256=xwydIcFTAHIX-YPfQfyxuQ7hzvIO3IhR3UAF7ORgkGg,5310
1299
- dirac-9.0.10.dist-info/licenses/LICENSE,sha256=uyr4oV6jmjUeepXZPPjkJRwa5q5MrI7jqJz5sVXNblQ,32452
1300
- dirac-9.0.10.dist-info/METADATA,sha256=2Pde9NbM-pbmGOY4PXnSp-C9eZYR-YnqbJ8ZmRqnxzQ,10018
1301
- dirac-9.0.10.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1302
- dirac-9.0.10.dist-info/entry_points.txt,sha256=hupzIL8aVmjK3nn7RLKdhcaiPmLOiD3Kulh3CSDHKmw,16492
1303
- dirac-9.0.10.dist-info/top_level.txt,sha256=RISrnN9kb_mPqmVu8_o4jF-DSX8-h6AcgfkO9cgfkHA,6
1304
- dirac-9.0.10.dist-info/RECORD,,
1299
+ dirac-9.0.11.dist-info/licenses/LICENSE,sha256=uyr4oV6jmjUeepXZPPjkJRwa5q5MrI7jqJz5sVXNblQ,32452
1300
+ dirac-9.0.11.dist-info/METADATA,sha256=T_cs5gCuIFDIbKQIZplKwcCdTEx9ij6h2miJDh1axV4,10018
1301
+ dirac-9.0.11.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1302
+ dirac-9.0.11.dist-info/entry_points.txt,sha256=hupzIL8aVmjK3nn7RLKdhcaiPmLOiD3Kulh3CSDHKmw,16492
1303
+ dirac-9.0.11.dist-info/top_level.txt,sha256=RISrnN9kb_mPqmVu8_o4jF-DSX8-h6AcgfkO9cgfkHA,6
1304
+ dirac-9.0.11.dist-info/RECORD,,
File without changes