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.
- DIRAC/FrameworkSystem/DB/InstalledComponentsDB.py +1 -1
- DIRAC/FrameworkSystem/Utilities/MonitoringUtilities.py +1 -0
- DIRAC/Resources/Computing/BatchSystems/Condor.py +0 -3
- DIRAC/Resources/Computing/BatchSystems/executeBatch.py +15 -7
- DIRAC/Resources/Computing/LocalComputingElement.py +0 -2
- DIRAC/Resources/Computing/SSHComputingElement.py +61 -38
- DIRAC/TransformationSystem/Agent/TransformationCleaningAgent.py +33 -6
- DIRAC/WorkloadManagementSystem/Agent/StalledJobAgent.py +39 -7
- DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_StalledJobAgent.py +24 -4
- DIRAC/WorkloadManagementSystem/DB/StatusUtils.py +48 -21
- DIRAC/WorkloadManagementSystem/DB/tests/Test_StatusUtils.py +19 -4
- DIRAC/WorkloadManagementSystem/Service/JobManagerHandler.py +25 -2
- {dirac-9.0.10.dist-info → dirac-9.0.11.dist-info}/METADATA +2 -2
- {dirac-9.0.10.dist-info → dirac-9.0.11.dist-info}/RECORD +18 -18
- {dirac-9.0.10.dist-info → dirac-9.0.11.dist-info}/WHEEL +0 -0
- {dirac-9.0.10.dist-info → dirac-9.0.11.dist-info}/entry_points.txt +0 -0
- {dirac-9.0.10.dist-info → dirac-9.0.11.dist-info}/licenses/LICENSE +0 -0
- {dirac-9.0.10.dist-info → dirac-9.0.11.dist-info}/top_level.txt +0 -0
|
@@ -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(
|
|
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
|
|
|
@@ -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
|
-
|
|
39
|
-
|
|
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
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
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
|
|
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
|
-
|
|
488
|
-
|
|
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
|
-
|
|
491
|
-
|
|
492
|
-
|
|
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
|
-
|
|
511
|
+
self.log.verbose(f"CE submission command: {cmd}")
|
|
496
512
|
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
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
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
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
|
-
# #
|
|
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
|
-
# #
|
|
129
|
-
|
|
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
|
-
|
|
55
|
-
|
|
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(
|
|
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 =
|
|
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
|
-
|
|
27
|
-
|
|
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.
|
|
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 :=
|
|
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 :=
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 :=
|
|
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 :=
|
|
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 :=
|
|
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(
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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(
|
|
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(
|
|
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.
|
|
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.
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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.
|
|
1300
|
-
dirac-9.0.
|
|
1301
|
-
dirac-9.0.
|
|
1302
|
-
dirac-9.0.
|
|
1303
|
-
dirac-9.0.
|
|
1304
|
-
dirac-9.0.
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|