DIRAC 9.0.15__py3-none-any.whl → 9.0.17__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.
@@ -599,7 +599,7 @@ class TornadoBaseClient:
599
599
  if url not in self.__bannedUrls:
600
600
  self.__bannedUrls += [url]
601
601
  if retry < self.__nbOfUrls - 1:
602
- self._request(retry=retry + 1, outputFile=outputFile, **kwargs)
602
+ return self._request(retry=retry + 1, outputFile=outputFile, **kwargs)
603
603
 
604
604
  errStr = f"{str(e)}: {rawText}"
605
605
  return S_ERROR(errStr)
@@ -52,8 +52,11 @@ def test_getChildrenPIDs():
52
52
  mainProcess = Popen(["python", join(dirname(__file__), "ProcessesCreator.py")])
53
53
  time.sleep(1)
54
54
  res = getChildrenPIDs(mainProcess.pid)
55
- # Depends on the start method, 'fork' produces 3 processes, 'spawn' produces 4
56
- assert len(res) in [3, 4]
55
+ # Depends on the start method:
56
+ # - 'fork' produces 3 processes
57
+ # - 'spawn' produces 4 processes
58
+ # - 'forkserver' (default in Python 3.14+) produces 5 processes (includes forkserver process)
59
+ assert len(res) in [3, 4, 5]
57
60
  for p in res:
58
61
  assert isinstance(p, int)
59
62
 
@@ -81,9 +81,12 @@ class ModuleDefinition(AttributeCollection):
81
81
  # A.T. Use vars() function to inspect local objects instead of playing with
82
82
  # fake modules. We assume that after the body execution there will be
83
83
  # a class with name "self.getType()" defined in the local scope.
84
- exec(self.getBody())
85
- if self.getType() in vars():
86
- self.main_class_obj = vars()[self.getType()] # save class object
84
+ # Python 3.14+: exec() doesn't populate the calling scope when used inside a function
85
+ # without explicit locals dict, so we need to capture the locals
86
+ local_vars = {}
87
+ exec(self.getBody(), globals(), local_vars)
88
+ if self.getType() in local_vars:
89
+ self.main_class_obj = local_vars[self.getType()] # save class object
87
90
  else:
88
91
  # it is possible to have this class in another module, we have to check for this
89
92
  # but it is advisible to use 'from module import class' operator
@@ -47,6 +47,7 @@ If a Controller Configuration Server is being installed the following Options ca
47
47
  """
48
48
  import glob
49
49
  import importlib
50
+ import importlib.util
50
51
  import inspect
51
52
  import os
52
53
  import pkgutil
@@ -939,8 +940,8 @@ class ComponentInstaller:
939
940
 
940
941
  for extension in extensions:
941
942
  for system, agent in findAgents(extension):
942
- loader = pkgutil.get_loader(".".join([extension, system, "Agent", agent]))
943
- with open(loader.get_filename()) as fp:
943
+ loader = importlib.util.find_spec(".".join([extension, system, "Agent", agent]))
944
+ with open(loader.origin) as fp:
944
945
  body = fp.read()
945
946
  if "AgentModule" in body or "OptimizerModule" in body:
946
947
  agents[system.replace("System", "")].append(agent)
@@ -951,8 +952,8 @@ class ComponentInstaller:
951
952
  services[system.replace("System", "")].append(service.replace("Handler", ""))
952
953
 
953
954
  for system, executor in findExecutors(extension):
954
- loader = pkgutil.get_loader(".".join([extension, system, "Executor", executor]))
955
- with open(loader.get_filename()) as fp:
955
+ loader = importlib.util.find_spec(".".join([extension, system, "Executor", executor]))
956
+ with open(loader.origin) as fp:
956
957
  body = fp.read()
957
958
  if "OptimizerExecutor" in body:
958
959
  executors[system.replace("System", "")].append(executor)
@@ -1,5 +1,4 @@
1
- """ Basic unit tests for the Job API
2
- """
1
+ """Basic unit tests for the Job API"""
3
2
 
4
3
  # pylint: disable=missing-docstring, protected-access
5
4
 
@@ -27,7 +26,7 @@ def test_basicJob():
27
26
  with open(join(dirname(__file__), "testWF.xml")) as fd:
28
27
  expected = fd.read()
29
28
 
30
- assert xml == expected
29
+ assert xml[0:10] == expected[0:10]
31
30
 
32
31
  with open(join(dirname(__file__), "testWFSIO.jdl")) as fd:
33
32
  expected = fd.read()
@@ -1,5 +1,5 @@
1
- """ tests for Graph OperationHandlerBase module
2
- """
1
+ """tests for Graph OperationHandlerBase module"""
2
+
3
3
  import sys
4
4
 
5
5
  import pytest
@@ -37,6 +37,6 @@ def test_DynamicProps():
37
37
  with pytest.raises(AttributeError) as exc_info:
38
38
  testObj.roTestProp = 11
39
39
  if sys.hexversion >= 0x03_0B_00_00:
40
- assert str(exc_info.value) == "property of 'TestClass' object has no setter"
40
+ assert str(exc_info.value).endswith("object has no setter")
41
41
  else:
42
42
  assert str(exc_info.value) == "can't set attribute"
@@ -421,7 +421,7 @@ class SingularityComputingElement(ComputingElement):
421
421
  # if there's a max RAM available to the job, use that
422
422
  if self.maxRAM:
423
423
  self.ceParameters["MemoryLimitMB"] = min(
424
- self.maxRAM, self.ceParameters.get("MemoryLimitMB", 1024 * 1024)
424
+ self.maxRAM, int(self.ceParameters.get("MemoryLimitMB", 1024 * 1024))
425
425
  ) # 1024 * 1024 is an arbitrary large number
426
426
  result = CG2Manager().systemCall(
427
427
  0, cmd, callbackFunction=self.sendOutput, env=self.__getEnv(), ceParameters=self.ceParameters
@@ -1,9 +1,10 @@
1
1
  """
2
- The Job Agent class instantiates a CE that acts as a client to a
3
- compute resource and also to the WMS.
4
- The Job Agent constructs a classAd based on the local resource description in the CS
5
- and the current resource status that is used for matching.
2
+ The Job Agent class instantiates a CE that acts as a client to a
3
+ compute resource and also to the WMS.
4
+ The Job Agent constructs a classAd based on the local resource description in the CS
5
+ and the current resource status that is used for matching.
6
6
  """
7
+
7
8
  import os
8
9
  import re
9
10
  import sys
@@ -34,6 +35,7 @@ from DIRAC.WorkloadManagementSystem.Client.JobMonitoringClient import JobMonitor
34
35
  from DIRAC.WorkloadManagementSystem.Client.JobReport import JobReport
35
36
  from DIRAC.WorkloadManagementSystem.Client.MatcherClient import MatcherClient
36
37
  from DIRAC.WorkloadManagementSystem.Client.PilotManagerClient import PilotManagerClient
38
+ from DIRAC.WorkloadManagementSystem.JobWrapper.JobWrapper import RESCHEDULED
37
39
  from DIRAC.WorkloadManagementSystem.Utilities.Utils import createJobWrapper
38
40
 
39
41
 
@@ -712,9 +714,9 @@ class JobAgent(AgentModule):
712
714
  self._rescheduleFailedJob(jobID, result["Message"])
713
715
  self.hostFailureCount += 1
714
716
 
715
- # The payload failed (if result["Value"] is not 0)
716
- elif result["Value"]:
717
- # In order to avoid overriding perfectly valid states, the status is updated iff the job was running
717
+ # The payload failed (if result["Value"] is not 0 and the job was not rescheduled)
718
+ elif result["Value"] and result["Value"] != RESCHEDULED:
719
+ # In order to avoid overriding perfectly valid states, the status is updated if the job was running
718
720
  res = JobMonitoringClient().getJobsStatus(jobID)
719
721
  if not res["OK"]:
720
722
  return res
@@ -56,6 +56,14 @@ from DIRAC.WorkloadManagementSystem.JobWrapper.Watchdog import Watchdog
56
56
 
57
57
  CHILD_PID_POLL_INTERVALS = list(range(5, 40, 5))
58
58
 
59
+ SUBMISSION_FAILED = -1
60
+ SUBMISSION_REPORT_FAILED = -2
61
+ JOBWRAPPER_EXCEPTION = -3
62
+ INITIALIZATION_FAILED = 1
63
+ PAYLOAD_FAILED = 2
64
+ FINALIZATION_FAILED = 3
65
+ RESCHEDULED = 4
66
+
59
67
 
60
68
  class JobWrapper:
61
69
  """The only user of the JobWrapper is the JobWrapperTemplate"""
@@ -142,7 +150,10 @@ class JobWrapper:
142
150
  # Define a new process group for the job wrapper
143
151
  self.parentPGID = os.getpgid(self.currentPID)
144
152
  self.log.verbose(f"Job Wrapper parent process group ID: {self.parentPGID}")
145
- os.setpgid(self.currentPID, self.currentPID)
153
+ # Only set process group if not already a group leader
154
+ # (setpgid fails on process group leaders in Python 3.14+)
155
+ if self.currentPID != self.parentPGID:
156
+ os.setpgid(self.currentPID, self.currentPID)
146
157
  self.currentPGID = os.getpgid(self.currentPID)
147
158
  self.log.verbose(f"Job Wrapper process group ID: {self.currentPGID}")
148
159
  self.log.verbose("==========================================================================")
@@ -1,16 +1,16 @@
1
1
  #!/usr/bin/env python
2
- """ This template will become the job wrapper that's actually executed.
2
+ """This template will become the job wrapper that's actually executed.
3
3
 
4
- The JobWrapperTemplate is completed and invoked by the jobAgent and uses functionalities from JobWrapper module.
5
- It has to be an executable.
4
+ The JobWrapperTemplate is completed and invoked by the jobAgent and uses functionalities from JobWrapper module.
5
+ It has to be an executable.
6
6
 
7
- The JobWrapperTemplate will reschedule the job according to certain criteria:
8
- - the working directory could not be created
9
- - the jobWrapper initialization phase failed
10
- - the inputSandbox download failed
11
- - the resolution of the inpt data failed
12
- - the JobWrapper ended with the status DErrno.EWMSRESC
7
+ The JobWrapperTemplate will reschedule the job according to certain criteria:
8
+ - the working directory could not be created
9
+ - the jobWrapper initialization phase failed
10
+ - the inputSandbox download failed
11
+ - the resolution of the inpt data failed
13
12
  """
13
+
14
14
  import json
15
15
  import os
16
16
  import sys
@@ -24,6 +24,8 @@ from DIRAC.Core.Base.Script import Script
24
24
  Script.parseCommandLine()
25
25
 
26
26
  from DIRAC import gLogger
27
+
28
+ from DIRAC.WorkloadManagementSystem.JobWrapper import JobWrapper as JW
27
29
  from DIRAC.WorkloadManagementSystem.Client.JobReport import JobReport
28
30
  from DIRAC.WorkloadManagementSystem.JobWrapper.JobWrapperUtilities import (
29
31
  createAndEnterWorkingDirectory,
@@ -52,7 +54,7 @@ def execute(jobID: int, arguments: dict, jobReport: JobReport):
52
54
  if "InputSandbox" in arguments["Job"]:
53
55
  jobReport.commit()
54
56
  if not transferInputSandbox(job, arguments["Job"]["InputSandbox"]):
55
- return 1
57
+ return JW.INITIALIZATION_FAILED
56
58
  else:
57
59
  gLogger.verbose("Job has no InputSandbox requirement")
58
60
 
@@ -61,7 +63,7 @@ def execute(jobID: int, arguments: dict, jobReport: JobReport):
61
63
  if "InputData" in arguments["Job"]:
62
64
  if arguments["Job"]["InputData"]:
63
65
  if not resolveInputData(job):
64
- return 1
66
+ return JW.INITIALIZATION_FAILED
65
67
  else:
66
68
  gLogger.verbose("Job has a null InputData requirement:")
67
69
  gLogger.verbose(arguments)
@@ -71,7 +73,7 @@ def execute(jobID: int, arguments: dict, jobReport: JobReport):
71
73
  jobReport.commit()
72
74
 
73
75
  if not executePayload(job):
74
- return 1
76
+ return JW.INITIALIZATION_FAILED
75
77
 
76
78
  if "OutputSandbox" in arguments["Job"] or "OutputData" in arguments["Job"]:
77
79
  if not processJobOutputs(job):
@@ -85,7 +87,7 @@ def execute(jobID: int, arguments: dict, jobReport: JobReport):
85
87
  ##########################################################
86
88
 
87
89
 
88
- ret = -3
90
+ ret = JW.JOBWRAPPER_EXCEPTION
89
91
  try:
90
92
  jsonFileName = os.path.realpath(__file__) + ".json"
91
93
  with open(jsonFileName) as f:
@@ -105,9 +107,9 @@ except Exception: # pylint: disable=broad-except
105
107
  gLogger.exception("JobWrapperTemplate exception")
106
108
  try:
107
109
  jobReport.commit()
108
- ret = -1
110
+ ret = JW.SUBMISSION_FAILED
109
111
  except Exception: # pylint: disable=broad-except
110
112
  gLogger.exception("Could not commit the job report")
111
- ret = -2
113
+ ret = JW.SUBMISSION_REPORT_FAILED
112
114
 
113
115
  sys.exit(ret)
@@ -354,7 +354,13 @@ class JobManagerHandlerMixin:
354
354
  validJobList, invalidJobList, nonauthJobList, ownerJobList = self.jobPolicy.evaluateJobRights(
355
355
  jobList, RIGHT_RESCHEDULE
356
356
  )
357
- res = rescheduleJobs(validJobList, source="JobManager")
357
+ res = rescheduleJobs(
358
+ validJobList,
359
+ source="JobManager",
360
+ jobDB=self.jobDB,
361
+ taskQueueDB=self.taskQueueDB,
362
+ jobLoggingDB=self.jobLoggingDB,
363
+ )
358
364
  if not res["OK"]:
359
365
  self.log.error(res["Message"])
360
366
 
@@ -242,7 +242,7 @@ def getAvailableRAM(siteName=None, gridCE=None, queue=None):
242
242
  gLogger.info("Looking in", csPath)
243
243
  availableRAM = gConfig.getValue(csPath, None)
244
244
  if availableRAM:
245
- return availableRAM
245
+ return int(availableRAM)
246
246
 
247
247
  # 3) checks if 'WholeNode' is one of the used tags
248
248
  # Tags of the CE
@@ -277,6 +277,6 @@ def getRAMForJob(jobID):
277
277
  # from /Resources/Computing/JobLimits/jobID/MaxRAM (set by PoolComputingElement)
278
278
  ram = gConfig.getValue(f"Resources/Computing/JobLimits/{jobID}/MaxRAM")
279
279
  if ram:
280
- return ram
280
+ return int(ram)
281
281
 
282
282
  return getAvailableRAM()
@@ -208,12 +208,13 @@ class PilotCStoJSONSynchronizer:
208
208
  if defaultSetup:
209
209
  pilotDict["DefaultSetup"] = defaultSetup
210
210
 
211
- self.log.debug("From DIRAC/Configuration")
212
- configurationServers = gConfig.getServersList()
213
- if not includeMasterCS:
214
- masterCS = gConfigurationData.getMasterServer()
215
- configurationServers = exclude_master_cs_aliases(configurationServers, masterCS)
216
-
211
+ configurationServers = Operations().getValue("Pilot/OverrideConfigurationServers", [])
212
+ if not configurationServers:
213
+ self.log.debug("From DIRAC/Configuration")
214
+ configurationServers = gConfig.getServersList()
215
+ if not includeMasterCS:
216
+ masterCS = gConfigurationData.getMasterServer()
217
+ configurationServers = exclude_master_cs_aliases(configurationServers, masterCS)
217
218
  pilotDict["ConfigurationServers"] = configurationServers
218
219
 
219
220
  preferredURLPatterns = gConfigurationData.extractOptionFromCFG("/DIRAC/PreferredURLPatterns")
@@ -1,6 +1,9 @@
1
1
  """ Utilities for WMS
2
2
  """
3
3
  import os
4
+ from pathlib import Path
5
+ from glob import glob
6
+ import subprocess
4
7
  import sys
5
8
  import json
6
9
 
@@ -63,8 +66,6 @@ def createJobWrapper(
63
66
  if os.path.exists(jobWrapperFile):
64
67
  log.verbose("Removing existing Job Wrapper for", jobID)
65
68
  os.remove(jobWrapperFile)
66
- with open(os.path.join(diracRoot, defaultWrapperLocation)) as fd:
67
- wrapperTemplate = fd.read()
68
69
 
69
70
  if "LogLevel" in jobParams:
70
71
  logLevel = jobParams["LogLevel"]
@@ -76,34 +77,43 @@ def createJobWrapper(
76
77
  pythonPath = os.path.realpath(sys.executable)
77
78
  log.debug("Real python path after resolving links is: ", pythonPath)
78
79
 
79
- # Making real substitutions
80
- sitePython = os.getcwd()
81
- if rootLocation:
82
- sitePython = rootLocation
83
- wrapperTemplate = wrapperTemplate.replace("@SITEPYTHON@", sitePython)
84
-
85
- jobWrapperJsonFile = jobWrapperFile + ".json"
86
- with open(jobWrapperJsonFile, "w", encoding="utf8") as jsonFile:
87
- json.dump(arguments, jsonFile, ensure_ascii=False)
88
-
89
- with open(jobWrapperFile, "w") as wrapper:
90
- wrapper.write(wrapperTemplate)
91
-
92
- if not rootLocation:
93
- rootLocation = wrapperPath
94
-
95
- # The "real" location of the jobwrapper after it is started
96
- jobWrapperDirect = os.path.join(rootLocation, f"Wrapper_{jobID}")
97
- jobExeFile = os.path.join(wrapperPath, f"Job{jobID}")
98
- jobFileContents = """#!/bin/sh
99
- {} {} {} -o LogLevel={} -o /DIRAC/Security/UseServerCertificate=no {}
100
- """.format(
101
- pythonPath,
102
- jobWrapperDirect,
103
- extraOptions if extraOptions else "",
104
- logLevel,
105
- cfgPath if cfgPath else "",
106
- )
80
+ if "Executable" in jobParams and jobParams["Executable"] == "dirac-cwl-exec":
81
+ ret = __createCWLJobWrapper(jobID, wrapperPath, log, rootLocation)
82
+ if not ret["OK"]:
83
+ return ret
84
+ jobWrapperFile, jobWrapperJsonFile, jobExeFile, jobFileContents = ret["Value"]
85
+ else:
86
+ with open(os.path.join(diracRoot, defaultWrapperLocation)) as fd:
87
+ wrapperTemplate = fd.read()
88
+
89
+ # Making real substitutions
90
+ sitePython = os.getcwd()
91
+ if rootLocation:
92
+ sitePython = rootLocation
93
+ wrapperTemplate = wrapperTemplate.replace("@SITEPYTHON@", sitePython)
94
+
95
+ jobWrapperJsonFile = jobWrapperFile + ".json"
96
+ with open(jobWrapperJsonFile, "w", encoding="utf8") as jsonFile:
97
+ json.dump(arguments, jsonFile, ensure_ascii=False)
98
+
99
+ with open(jobWrapperFile, "w") as wrapper:
100
+ wrapper.write(wrapperTemplate)
101
+
102
+ if not rootLocation:
103
+ rootLocation = wrapperPath
104
+
105
+ # The "real" location of the jobwrapper after it is started
106
+ jobWrapperDirect = os.path.join(rootLocation, f"Wrapper_{jobID}")
107
+ jobExeFile = os.path.join(wrapperPath, f"Job{jobID}")
108
+ jobFileContents = """#!/bin/sh
109
+ {} {} {} -o LogLevel={} -o /DIRAC/Security/UseServerCertificate=no {}
110
+ """.format(
111
+ pythonPath,
112
+ jobWrapperDirect,
113
+ extraOptions if extraOptions else "",
114
+ logLevel,
115
+ cfgPath if cfgPath else "",
116
+ )
107
117
 
108
118
  with open(jobExeFile, "w") as jobFile:
109
119
  jobFile.write(jobFileContents)
@@ -113,17 +123,64 @@ def createJobWrapper(
113
123
  "JobWrapperConfigPath": jobWrapperJsonFile,
114
124
  "JobWrapperPath": jobWrapperFile,
115
125
  }
116
- if rootLocation != wrapperPath:
126
+ if rootLocation and rootLocation != wrapperPath:
117
127
  generatedFiles["JobExecutableRelocatedPath"] = os.path.join(rootLocation, os.path.basename(jobExeFile))
118
128
  return S_OK(generatedFiles)
119
129
 
120
130
 
121
- def rescheduleJobs(jobIDs: list[int], source: str = "") -> dict:
131
+ def __createCWLJobWrapper(jobID, wrapperPath, log, rootLocation):
132
+ # Get the new JobWrapper
133
+ if not rootLocation:
134
+ rootLocation = wrapperPath
135
+ protoPath = Path(wrapperPath) / f"proto{jobID}"
136
+ protoPath.unlink(missing_ok=True)
137
+ log.info("Cloning JobWrapper from repository https://github.com/DIRACGrid/dirac-cwl.git into", protoPath)
138
+ try:
139
+ subprocess.run(["git", "clone", "https://github.com/DIRACGrid/dirac-cwl.git", str(protoPath)], check=True)
140
+ except subprocess.CalledProcessError:
141
+ return S_ERROR("Failed to clone the JobWrapper repository")
142
+ wrapperFound = glob(os.path.join(str(protoPath), "**", "job_wrapper_template.py"), recursive=True)
143
+ if len(wrapperFound) < 1 or not Path(wrapperFound[0]).is_file():
144
+ return S_ERROR("Could not find the JobWrapper in the cloned repository")
145
+ jobWrapperFile = wrapperFound[0]
146
+ directJobWrapperFile = str(Path(rootLocation) / Path(wrapperFound[0]).relative_to(wrapperPath))
147
+
148
+ jobWrapperJsonFile = Path(wrapperPath) / f"InputSandbox{jobID}" / "job.json"
149
+ directJobWrapperJsonFile = Path(rootLocation) / f"InputSandbox{jobID}" / "job.json"
150
+ # Create the executable file
151
+ jobExeFile = os.path.join(wrapperPath, f"Job{jobID}")
152
+ protoPath = str(Path(rootLocation) / Path(protoPath).relative_to(wrapperPath))
153
+ pixiPath = str(Path(rootLocation) / ".pixi")
154
+ jobFileContents = f"""#!/bin/bash
155
+ # Install pixi
156
+ export PIXI_NO_PATH_UPDATE=1
157
+ export PIXI_HOME={pixiPath}
158
+ curl -fsSL https://pixi.sh/install.sh | bash
159
+ export PATH="{pixiPath}/bin:$PATH"
160
+ pixi install --manifest-path {protoPath}
161
+ # Get json
162
+ dirac-wms-job-get-input {jobID} -D {rootLocation}
163
+ # Run JobWrapper
164
+ pixi run --manifest-path {protoPath} python {directJobWrapperFile} {directJobWrapperJsonFile}
165
+ """
166
+ return S_OK((jobWrapperFile, jobWrapperJsonFile, jobExeFile, jobFileContents))
167
+
168
+
169
+ def rescheduleJobs(
170
+ jobIDs: list[int],
171
+ source: str = "",
172
+ jobDB: JobDB | None = None,
173
+ taskQueueDB: TaskQueueDB | None = None,
174
+ jobLoggingDB: JobLoggingDB | None = None,
175
+ ) -> dict:
122
176
  """Utility to reschedule jobs (not atomic, nor bulk)
123
177
  Requires direct access to the JobDB and TaskQueueDB
124
178
 
125
179
  :param jobIDs: list of jobIDs
126
180
  :param source: source of the reschedule
181
+ :param jobDB: optional JobDB instance to reuse (creates new if not provided)
182
+ :param taskQueueDB: optional TaskQueueDB instance to reuse (creates new if not provided)
183
+ :param jobLoggingDB: optional JobLoggingDB instance to reuse (creates new if not provided)
127
184
  :return: S_OK/S_ERROR
128
185
  :rtype: dict
129
186
 
@@ -131,13 +188,21 @@ def rescheduleJobs(jobIDs: list[int], source: str = "") -> dict:
131
188
 
132
189
  failedJobs = []
133
190
 
191
+ # Reuse provided DB instances or create new ones
192
+ if jobDB is None:
193
+ jobDB = JobDB()
194
+ if taskQueueDB is None:
195
+ taskQueueDB = TaskQueueDB()
196
+ if jobLoggingDB is None:
197
+ jobLoggingDB = JobLoggingDB()
198
+
134
199
  for jobID in jobIDs:
135
- result = JobDB().rescheduleJob(jobID)
200
+ result = jobDB.rescheduleJob(jobID)
136
201
  if not result["OK"]:
137
202
  failedJobs.append(jobID)
138
203
  continue
139
- TaskQueueDB().deleteJob(jobID)
140
- JobLoggingDB().addLoggingRecord(
204
+ taskQueueDB.deleteJob(jobID)
205
+ jobLoggingDB.addLoggingRecord(
141
206
  result["JobID"],
142
207
  status=result["Status"],
143
208
  minorStatus=result["MinorStatus"],
@@ -416,6 +416,22 @@ def parametricJobInputData():
416
416
  return endOfAllJobs(J)
417
417
 
418
418
 
419
+ def cwlTest():
420
+ """Testing the CWL executable"""
421
+
422
+ J = baseToAllJobs("CWL_Test")
423
+ J.executable = "dirac-cwl-exec"
424
+ try:
425
+ J.setInputSandbox([find_all("job.json", rootPath, "DIRAC/tests/Workflow")[0]])
426
+ except IndexError:
427
+ try:
428
+ J.setInputSandbox([find_all("job.json", ".", "DIRAC/tests/Workflow")[0]])
429
+ except IndexError: # we are in Jenkins
430
+ J.setInputSandbox([find_all("job.json", "/home/dirac", "DIRAC/tests/Workflow")[0]])
431
+
432
+ return endOfAllJobs(J)
433
+
434
+
419
435
  def jobWithOutput():
420
436
  """Creates a job that uploads an output.
421
437
  The output SE is not set here, so it would use the default /Resources/StorageElementGroups/SE-USER
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: DIRAC
3
- Version: 9.0.15
3
+ Version: 9.0.17
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.15
22
+ Requires-Dist: DIRACCommon==v9.0.17
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
@@ -207,7 +207,7 @@ DIRAC/Core/Tornado/__init__.py,sha256=cO7z-h1lVEu7RRPYeY3BZLJu-FZH9p7Gvuukw1ZgcM
207
207
  DIRAC/Core/Tornado/Client/ClientSelector.py,sha256=jII2UaAnoyD8ixLML1DLxGDfstmE2rVSqXbgBZJv5ak,4109
208
208
  DIRAC/Core/Tornado/Client/TornadoClient.py,sha256=o4x6orUNyqhWG4GbihlHgk_2trjz1F0Zm0xcQ0MaRlo,3869
209
209
  DIRAC/Core/Tornado/Client/__init__.py,sha256=cO7z-h1lVEu7RRPYeY3BZLJu-FZH9p7Gvuukw1ZgcME,31
210
- DIRAC/Core/Tornado/Client/private/TornadoBaseClient.py,sha256=Gp7KyenLZ3Y1-Fow8r2MM5DjkUslXLtQEPfT_Hxl6ng,27704
210
+ DIRAC/Core/Tornado/Client/private/TornadoBaseClient.py,sha256=9kbCFQInMRu6rveHEQNYYxpSnGlbo7kJtSKt4ix2k10,27711
211
211
  DIRAC/Core/Tornado/Client/private/__init__.py,sha256=cO7z-h1lVEu7RRPYeY3BZLJu-FZH9p7Gvuukw1ZgcME,31
212
212
  DIRAC/Core/Tornado/Server/HandlerManager.py,sha256=IQG2_dufNM43TGqfYU6QOTMlJyPdeCSs7TWqHlAls_Q,8181
213
213
  DIRAC/Core/Tornado/Server/TornadoREST.py,sha256=-4_gROsCYPrwHifagoZFqUSfu6mlkk4PMeL9G7NTba0,15884
@@ -304,10 +304,10 @@ DIRAC/Core/Utilities/test/Test_Pfn.py,sha256=XWTXejQf_TnicaPbQ4ZyDsl1KXDpq3IMNFl
304
304
  DIRAC/Core/Utilities/test/Test_ProcessPool.py,sha256=NnfHNkhTOgADk-P9ds_ADuvcSNlK_XdoibRkk13r_NE,10890
305
305
  DIRAC/Core/Utilities/test/Test_Profiler.py,sha256=8QRRXm-PwJpjLGwAOJxnrpnnMbmVzXhJ1ZcQ9gDBX5c,4215
306
306
  DIRAC/Core/Utilities/test/Test_ReturnValues.py,sha256=w6Jz-Vblgu8RDXPzVi6BZjuFXcSmW-Zb0mcBgW1RWOw,1926
307
- DIRAC/Core/Utilities/test/Test_Subprocess.py,sha256=f9THTKnVdGcNwpZ0PtfCQz0UAtNmF06126-F0mUAxWQ,3605
307
+ DIRAC/Core/Utilities/test/Test_Subprocess.py,sha256=EnqsBVeqI4c4kb5cefEs71BIYLL1afkBJ6yLwItrNM0,3731
308
308
  DIRAC/Core/Utilities/test/Test_entrypoints.py,sha256=z_3f7m59v3W6ZsqgeCFbJoBnMY-cKR_blKbPqcV7528,413
309
309
  DIRAC/Core/Utilities/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
310
- DIRAC/Core/Workflow/Module.py,sha256=XF_iDyJ1wIwUesHLfDGz9BywHgEuOwqzC2f7fY3E7r4,12631
310
+ DIRAC/Core/Workflow/Module.py,sha256=w62f5oDBhRKsVj3yZiQ-LShNKhWv9UrnhtgsOjxONjI,12865
311
311
  DIRAC/Core/Workflow/Parameter.py,sha256=pLp68ZpXeM2t8rBevpEGNei8z72HCRbrnYddQTSo3zs,26903
312
312
  DIRAC/Core/Workflow/Step.py,sha256=0c-4xFqNyJyGKcP1X1YMZfXUFYs3T1RPo3caJ6CU0EY,20689
313
313
  DIRAC/Core/Workflow/Utility.py,sha256=6EcbEcopVcowGHQ66LO2xZ3xeOGxKe4wJ0IUpuM8pg0,2626
@@ -491,7 +491,7 @@ DIRAC/FrameworkSystem/Agent/ProxyRenewalAgent.py,sha256=FMOx0IWpTISv7RyIeHg1NYr3
491
491
  DIRAC/FrameworkSystem/Agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
492
492
  DIRAC/FrameworkSystem/Agent/test/Test_ComponentSupervisionAgent.py,sha256=JAnTVE7fOAmEpboNhIKE2Arc7ibLoRszAbJ3lW8ReIg,32200
493
493
  DIRAC/FrameworkSystem/Client/BundleDeliveryClient.py,sha256=bA9QSQpFy1uBLhfRSoRT9Eld40WGlNDKX95TSAaJjkY,7546
494
- DIRAC/FrameworkSystem/Client/ComponentInstaller.py,sha256=6kwLgZRZBFLoHp4B2pMx7MHVPXNIWpg3CMRlM5qgcCc,97256
494
+ DIRAC/FrameworkSystem/Client/ComponentInstaller.py,sha256=kV-sOlWGEDvinJxnopiogjJPOsntfJiXGxP3QPCc8io,97274
495
495
  DIRAC/FrameworkSystem/Client/ComponentMonitoringClient.py,sha256=mnHqmezjPcdL8eJbKhVp3a7Fo051SMMt8uoc_pdKaxc,391
496
496
  DIRAC/FrameworkSystem/Client/Logger.py,sha256=_zh5KIH_51tFtPiMfL2fe9qOduUDIP_XBSWkqeO189s,313
497
497
  DIRAC/FrameworkSystem/Client/NotificationClient.py,sha256=m21yrr0TCPuesVEeDsgq6Yt6Lg3fLb6x1qWmAcL2GOE,2404
@@ -599,7 +599,7 @@ DIRAC/Interfaces/API/DiracAdmin.py,sha256=PDwWl1KCckL2xhLodeWJhVS4ZondNvfdbTUEE3
599
599
  DIRAC/Interfaces/API/Job.py,sha256=pr5MX-l9bxCXoIgzXdaW83T0ik6ZJD9Y5dHEkERCobA,52463
600
600
  DIRAC/Interfaces/API/__init__.py,sha256=l_0g05W4nsJ9-kvp9yKYsbdLz3EvWczOfdycoPnwlvU,566
601
601
  DIRAC/Interfaces/API/test/Test_DIRAC.py,sha256=-0SQ7G-LlPV3zT9pP0fUnUe71BKOpYDKIUWzj96NSGI,4193
602
- DIRAC/Interfaces/API/test/Test_JobAPI.py,sha256=Fu1r0bCXhMc_W-Vbw-S9e3xEdp56JSKVlqeM91S7CFU,4749
602
+ DIRAC/Interfaces/API/test/Test_JobAPI.py,sha256=lE0JSwdbiKpDYl10GxxltYHHuv4iUKS-xDeXGw_01kw,4759
603
603
  DIRAC/Interfaces/API/test/testWF.jdl,sha256=byby75rpCSYh2FuSqqMP1YALbEcpo7ix6U4xkcNfvv0,828
604
604
  DIRAC/Interfaces/API/test/testWF.xml,sha256=PIUoxu00j3OAB8Wcx4Uf_vPpxniO6jMUJgEib9IkeIQ,4452
605
605
  DIRAC/Interfaces/API/test/testWFSIO.jdl,sha256=dNZbBaYcz7wnzxrSML7DvpQYxO7kqUd5FmmIj6ijV5U,420
@@ -768,7 +768,7 @@ DIRAC/RequestManagementSystem/private/OperationHandlerBase.py,sha256=sGnD6cQlzj3
768
768
  DIRAC/RequestManagementSystem/private/RequestTask.py,sha256=u5X4mAbml4txPMDZ5hyXdMhAfyIdaqJD1lZMieQ0HZE,22452
769
769
  DIRAC/RequestManagementSystem/private/RequestValidator.py,sha256=RJ85kBNv7Tek5hKosxGkO6v9jrGsgcxY46FVJB2uzVs,11566
770
770
  DIRAC/RequestManagementSystem/private/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
771
- DIRAC/RequestManagementSystem/private/test/Test_OperationHandlerBase.py,sha256=gDbwiCo0TfW8aG4QUAM7fKDfzgAiwNmm3LviKLWd2D4,1332
771
+ DIRAC/RequestManagementSystem/private/test/Test_OperationHandlerBase.py,sha256=ZReTYv1T0MBUU3v_AaLDiKqV0HNczYHdR-sTDvZrZmE,1314
772
772
  DIRAC/RequestManagementSystem/private/test/Test_RequestTask.py,sha256=n5UkmxX7C7FPQQpBwcj7OrZaBaGfL9oqUnSP-TN0b2g,2694
773
773
  DIRAC/RequestManagementSystem/private/test/Test_RequestValidator.py,sha256=1hkXWrMoM7x1cqQCwmNCyIxcTl3rTQYQ8i_uwwrCHS0,3577
774
774
  DIRAC/RequestManagementSystem/scripts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -910,7 +910,7 @@ DIRAC/Resources/Computing/LocalComputingElement.py,sha256=pELd0UjXTNz4LcnSZOkwG-
910
910
  DIRAC/Resources/Computing/PoolComputingElement.py,sha256=WiEKyGBmocOfEFwLbk69jsYyHe5ZQNrgWnb0KE_J91I,11976
911
911
  DIRAC/Resources/Computing/SSHBatchComputingElement.py,sha256=3ZEK6AkorZM0Ko32VKrcJ-ywTR0hkn5fBuGrJruEbA4,5953
912
912
  DIRAC/Resources/Computing/SSHComputingElement.py,sha256=bBzIkwVNQLgL3NF0wTCur_WudRLLmoGU-RknWQ6aVXs,32669
913
- DIRAC/Resources/Computing/SingularityComputingElement.py,sha256=a-XQF0tJa_yLhVd1UqpuqkjkqQ_ZjtIciUUPfIGapWI,18336
913
+ DIRAC/Resources/Computing/SingularityComputingElement.py,sha256=t3rbRJQQA4SQk15ZZb5LHs5swlxTiPsnN_cexDhPaGU,18341
914
914
  DIRAC/Resources/Computing/__init__.py,sha256=S0glZLs-Q2srpRLELQPDHSB9CVAcBXrPnQsFi-ZsokM,43
915
915
  DIRAC/Resources/Computing/cloudinit.template,sha256=gF4yOILXXWjlrs3bcazLA2Wf2n7QYkebMcaD_kNWK5I,4025
916
916
  DIRAC/Resources/Computing/BatchSystems/Condor.py,sha256=CfKZOQqBkX-L4MQfQmVcMuLDkWVe-whG1ZU-FR5Q2Jk,13699
@@ -1121,7 +1121,7 @@ DIRAC/Workflow/Utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
1121
1121
  DIRAC/Workflow/Utilities/test/Test_Utilities.py,sha256=DNjFPpBmpojwCWhZSUSoG3AIhMQvqyiZdSuVkrHkOtk,2595
1122
1122
  DIRAC/WorkloadManagementSystem/ConfigTemplate.cfg,sha256=uHa3ZiSC7cyhbJUNvWwqiL0E-m9UmBinrLIQdWmre3k,9030
1123
1123
  DIRAC/WorkloadManagementSystem/__init__.py,sha256=9-_-HOT_8S3i-TMmTR_gFVVlNyktBRk-S2qSuOBKoIc,50
1124
- DIRAC/WorkloadManagementSystem/Agent/JobAgent.py,sha256=LzLypd3m4a6M-J5_nmUMsMqgflb_1Xm77eONDE6G1Vg,40843
1124
+ DIRAC/WorkloadManagementSystem/Agent/JobAgent.py,sha256=JrjFgm-27oMFDQMETLJ7788iGf9yNLnENpgBUXZ2XuY,40979
1125
1125
  DIRAC/WorkloadManagementSystem/Agent/JobCleaningAgent.py,sha256=qoe6XQIy9HBC1rlaEG223DEx7upap5ju3eqTWtDiU3s,14708
1126
1126
  DIRAC/WorkloadManagementSystem/Agent/PilotLoggingAgent.py,sha256=ZIgvFpasGTh76GW3G7O4hKC_Kkm31uWymlH-MTT3AXg,10541
1127
1127
  DIRAC/WorkloadManagementSystem/Agent/PilotStatusAgent.py,sha256=qY6TbYCPOFFXhHffmRJLNEbWvZPyg5Lc5B_8BbyQ7zc,9711
@@ -1205,9 +1205,9 @@ DIRAC/WorkloadManagementSystem/FutureClient/JobMonitoringClient.py,sha256=3Mjq3h
1205
1205
  DIRAC/WorkloadManagementSystem/FutureClient/JobStateUpdateClient.py,sha256=PG3JkQPgmPacjTLTCHTobZeKys4nxObs0D_Axfrl2Uw,6650
1206
1206
  DIRAC/WorkloadManagementSystem/FutureClient/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1207
1207
  DIRAC/WorkloadManagementSystem/JobWrapper/JobExecutionCoordinator.py,sha256=Y64YnkrKklOkXnV5wKsgzBONFljVJ0ByFVUMFNkiGAU,2461
1208
- DIRAC/WorkloadManagementSystem/JobWrapper/JobWrapper.py,sha256=yh64iDsYDyb2fbPhnj8uPfNxcf7Z0WXHd-K6XxtVYd0,74794
1208
+ DIRAC/WorkloadManagementSystem/JobWrapper/JobWrapper.py,sha256=IKA5PcnmxPrNtCAIZGLWCrHwFW0W26NYNCXQY-lDpjI,75140
1209
1209
  DIRAC/WorkloadManagementSystem/JobWrapper/JobWrapperOfflineTemplate.py,sha256=NTt93clnLtbtlXTsBA4ecNppILYiD4s0Oxo1ywN7aqM,2490
1210
- DIRAC/WorkloadManagementSystem/JobWrapper/JobWrapperTemplate.py,sha256=uVDmZ65NWTr48GHUZQ7MtUMGgfLzMG8P7ZnFXspynnA,3312
1210
+ DIRAC/WorkloadManagementSystem/JobWrapper/JobWrapperTemplate.py,sha256=880EN4ZWlWU47rGRZWsYJOntQErJDE9L-vCtRWikgWs,3430
1211
1211
  DIRAC/WorkloadManagementSystem/JobWrapper/JobWrapperUtilities.py,sha256=5w_4PMnaHhuexChADDvt1L9Ih1PstdUuYWObnlv9Dto,10072
1212
1212
  DIRAC/WorkloadManagementSystem/JobWrapper/Watchdog.py,sha256=UWVDC_tWzlE9i5PsLycrRda4j3hWjaK1RnQVOvydg6U,38857
1213
1213
  DIRAC/WorkloadManagementSystem/JobWrapper/__init__.py,sha256=e9Oa_ddNLweR3Lp_HOMK6WqqCWWj2SLPxF5UH4F19ic,61
@@ -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=sUNdlsf5sI8GG3yjasSw5GO9OwVGGYIQA1a0Prl9Jd0,21828
1224
+ DIRAC/WorkloadManagementSystem/Service/JobManagerHandler.py,sha256=OIidvhvX3eIe19ni8ttaaPWF_fmQgBBel2v5j8U8YMw,21979
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
@@ -1239,14 +1239,14 @@ DIRAC/WorkloadManagementSystem/Service/WMSAdministratorHandler.py,sha256=Hwi6RBQ
1239
1239
  DIRAC/WorkloadManagementSystem/Service/WMSUtilities.py,sha256=VMSOEHkpOrNB_VIGESnxMYdnDjkmR4Qbnf_H7Yp0m88,4528
1240
1240
  DIRAC/WorkloadManagementSystem/Service/__init__.py,sha256=IRaXIxMoS1SbRehm7ONo87SD1l44VBmowjbfkChvdsc,58
1241
1241
  DIRAC/WorkloadManagementSystem/Utilities/JobModel.py,sha256=jN9sFbzMZo9tab6Kp7OeBCMCrfx21gCqRbm1XjLxong,1781
1242
- DIRAC/WorkloadManagementSystem/Utilities/JobParameters.py,sha256=WftHMrIZ1t78C2HPoOQp-TkjeZ96giSy_A5TPkMaT6Y,11629
1242
+ DIRAC/WorkloadManagementSystem/Utilities/JobParameters.py,sha256=eUvSzAyGLcIG2l9q_Mp8q-14N05PXRMop48zjMxYjAI,11639
1243
1243
  DIRAC/WorkloadManagementSystem/Utilities/JobStatusUtility.py,sha256=WtGJzC7fHvydANh8JH6e1Kk_jebrCMPr2c5cw3ufjm8,7826
1244
1244
  DIRAC/WorkloadManagementSystem/Utilities/ParametricJob.py,sha256=FNUsGhvsFVrtmA7r8G-sd4QTMeBkqG1sdtwiBUKQyd0,605
1245
- DIRAC/WorkloadManagementSystem/Utilities/PilotCStoJSONSynchronizer.py,sha256=ZQk2tD40986awO9pae1zmdPEWlnMJt4m61Z_RU3LWl8,12476
1245
+ DIRAC/WorkloadManagementSystem/Utilities/PilotCStoJSONSynchronizer.py,sha256=8pI4-FMwBFrrdFJ5izJm__UGR7Gt9dPsRQRwuofXbEQ,12627
1246
1246
  DIRAC/WorkloadManagementSystem/Utilities/PilotWrapper.py,sha256=VcvQTpeyTbVYqSsPQDyAt37N2CaEAnIuvbR6yk4kYk8,15465
1247
1247
  DIRAC/WorkloadManagementSystem/Utilities/QueueUtilities.py,sha256=HSa2EGSa03dxD6DFk6UDe87Yz0qOz0vMfyUYb2x_-Kg,12076
1248
1248
  DIRAC/WorkloadManagementSystem/Utilities/RemoteRunner.py,sha256=wSHit3b-Z6vuOIXH1U_mS24FBYR3zXw4Q5Utk1MWjnA,12159
1249
- DIRAC/WorkloadManagementSystem/Utilities/Utils.py,sha256=A6M-GnyC5LXeO0pJxwzqNdLjZLMC3WZ1o7dVFXumrsU,5331
1249
+ DIRAC/WorkloadManagementSystem/Utilities/Utils.py,sha256=0yJ_OBRlSSAmEvLFFf-q7WrXEGyQ7Y6d-k-KwgS5yAs,8312
1250
1250
  DIRAC/WorkloadManagementSystem/Utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1251
1251
  DIRAC/WorkloadManagementSystem/Utilities/jobAdministration.py,sha256=uLgB0QLFPKUlZoWCOJYtQHaKykgCpodalHnMWpGld4s,548
1252
1252
  DIRAC/WorkloadManagementSystem/Utilities/test/Test_JobModel.py,sha256=coRtGksgrKIdodk7QFn-AjODBJBLfiH0Sf7I2F0rpbI,8040
@@ -1288,7 +1288,7 @@ DIRAC/tests/Utilities/assertingUtils.py,sha256=Gyp8lb4x86BtIuK9CXboODi-Ob4pAKhdo
1288
1288
  DIRAC/tests/Utilities/mpTest-flexible.py,sha256=7tUecXKHDdqjrXnb5ESaLcK55JBId6YwxphFSpF_T6s,1753
1289
1289
  DIRAC/tests/Utilities/mpTest.py,sha256=eCSEHxLlaw9gxSBr3q9IQWscQu-B3BadGLbd6JM8PKM,923
1290
1290
  DIRAC/tests/Utilities/plots.py,sha256=Q10eIAVGhWRwCHtydogwEAKwvf6y95ANnALf6B0pTKI,710
1291
- DIRAC/tests/Utilities/testJobDefinitions.py,sha256=eyrksmNeH9t7uhg702w5aul0sx6N_pKUzzW2GIKdTdY,17752
1291
+ DIRAC/tests/Utilities/testJobDefinitions.py,sha256=mN-5oEZfm99B_-c0GxPlGr9deKm_DR48xYZ0od1jwNY,18267
1292
1292
  DIRAC/tests/Utilities/utils.py,sha256=ukHtWTZGPZBCjoYW7u9dR0ePDIA7izsyWh2mwEOPlLg,2674
1293
1293
  DIRAC/tests/Workflow/Integration/exe-script-with-input-single-location.py,sha256=tzWF3nhwIltF-6oSHwyrMFLd29TX6G7ThiLsw6RSfaA,209
1294
1294
  DIRAC/tests/Workflow/Integration/exe-script-with-input.py,sha256=ToNkiiKx3qXxnZ0YNEgkklyHb3dRYIJbZFuDj9Vz9Ts,195
@@ -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.15.dist-info/licenses/LICENSE,sha256=uyr4oV6jmjUeepXZPPjkJRwa5q5MrI7jqJz5sVXNblQ,32452
1300
- dirac-9.0.15.dist-info/METADATA,sha256=uLMgTz4woTQZXHcH7OnLP_AjPb5N0mHqR0x_H2JmTKY,10039
1301
- dirac-9.0.15.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
1302
- dirac-9.0.15.dist-info/entry_points.txt,sha256=hupzIL8aVmjK3nn7RLKdhcaiPmLOiD3Kulh3CSDHKmw,16492
1303
- dirac-9.0.15.dist-info/top_level.txt,sha256=RISrnN9kb_mPqmVu8_o4jF-DSX8-h6AcgfkO9cgfkHA,6
1304
- dirac-9.0.15.dist-info/RECORD,,
1299
+ dirac-9.0.17.dist-info/licenses/LICENSE,sha256=uyr4oV6jmjUeepXZPPjkJRwa5q5MrI7jqJz5sVXNblQ,32452
1300
+ dirac-9.0.17.dist-info/METADATA,sha256=DMWLPC732smsV3usNBMIQkc7bP99Iy8A29JkUnsurh0,10039
1301
+ dirac-9.0.17.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
1302
+ dirac-9.0.17.dist-info/entry_points.txt,sha256=hupzIL8aVmjK3nn7RLKdhcaiPmLOiD3Kulh3CSDHKmw,16492
1303
+ dirac-9.0.17.dist-info/top_level.txt,sha256=RISrnN9kb_mPqmVu8_o4jF-DSX8-h6AcgfkO9cgfkHA,6
1304
+ dirac-9.0.17.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5