DIRAC 9.0.0a54__py3-none-any.whl → 9.0.7__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.
Files changed (166) hide show
  1. DIRAC/AccountingSystem/Client/AccountingCLI.py +0 -140
  2. DIRAC/AccountingSystem/Client/DataStoreClient.py +0 -13
  3. DIRAC/AccountingSystem/Client/Types/BaseAccountingType.py +0 -7
  4. DIRAC/AccountingSystem/ConfigTemplate.cfg +0 -5
  5. DIRAC/AccountingSystem/Service/DataStoreHandler.py +0 -72
  6. DIRAC/ConfigurationSystem/Client/Helpers/CSGlobals.py +0 -9
  7. DIRAC/ConfigurationSystem/Client/Helpers/Registry.py +34 -32
  8. DIRAC/ConfigurationSystem/Client/Helpers/Resources.py +11 -43
  9. DIRAC/ConfigurationSystem/Client/Helpers/test/Test_Helpers.py +0 -16
  10. DIRAC/ConfigurationSystem/Client/LocalConfiguration.py +14 -8
  11. DIRAC/ConfigurationSystem/Client/PathFinder.py +47 -8
  12. DIRAC/ConfigurationSystem/Client/SyncPlugins/CERNLDAPSyncPlugin.py +4 -1
  13. DIRAC/ConfigurationSystem/Client/VOMS2CSSynchronizer.py +9 -2
  14. DIRAC/ConfigurationSystem/Client/test/Test_PathFinder.py +41 -1
  15. DIRAC/ConfigurationSystem/private/RefresherBase.py +4 -2
  16. DIRAC/Core/DISET/ServiceReactor.py +11 -3
  17. DIRAC/Core/DISET/private/BaseClient.py +1 -2
  18. DIRAC/Core/DISET/private/Transports/M2SSLTransport.py +9 -7
  19. DIRAC/Core/Security/DiracX.py +12 -7
  20. DIRAC/Core/Security/IAMService.py +4 -3
  21. DIRAC/Core/Security/ProxyInfo.py +9 -5
  22. DIRAC/Core/Security/test/test_diracx_token_from_pem.py +161 -0
  23. DIRAC/Core/Tornado/Client/ClientSelector.py +4 -1
  24. DIRAC/Core/Tornado/Server/TornadoService.py +1 -1
  25. DIRAC/Core/Utilities/ClassAd/ClassAdLight.py +4 -290
  26. DIRAC/Core/Utilities/DErrno.py +5 -309
  27. DIRAC/Core/Utilities/Extensions.py +10 -1
  28. DIRAC/Core/Utilities/Graphs/GraphData.py +1 -1
  29. DIRAC/Core/Utilities/JDL.py +1 -195
  30. DIRAC/Core/Utilities/List.py +1 -124
  31. DIRAC/Core/Utilities/MySQL.py +101 -97
  32. DIRAC/Core/Utilities/Os.py +32 -1
  33. DIRAC/Core/Utilities/Platform.py +2 -107
  34. DIRAC/Core/Utilities/ReturnValues.py +7 -252
  35. DIRAC/Core/Utilities/StateMachine.py +12 -178
  36. DIRAC/Core/Utilities/TimeUtilities.py +10 -253
  37. DIRAC/Core/Utilities/test/Test_JDL.py +0 -3
  38. DIRAC/Core/Utilities/test/Test_Profiler.py +20 -20
  39. DIRAC/Core/scripts/dirac_agent.py +1 -1
  40. DIRAC/Core/scripts/dirac_apptainer_exec.py +16 -7
  41. DIRAC/Core/scripts/dirac_platform.py +1 -92
  42. DIRAC/DataManagementSystem/Agent/FTS3Agent.py +8 -7
  43. DIRAC/DataManagementSystem/Agent/RequestOperations/RemoveFile.py +7 -6
  44. DIRAC/DataManagementSystem/Client/FTS3Job.py +71 -34
  45. DIRAC/DataManagementSystem/DB/FTS3DB.py +3 -0
  46. DIRAC/DataManagementSystem/DB/FileCatalogComponents/DatasetManager/DatasetManager.py +1 -1
  47. DIRAC/DataManagementSystem/Utilities/DMSHelpers.py +6 -2
  48. DIRAC/DataManagementSystem/scripts/dirac_dms_create_moving_request.py +2 -0
  49. DIRAC/DataManagementSystem/scripts/dirac_dms_protocol_matrix.py +0 -1
  50. DIRAC/FrameworkSystem/Client/ComponentInstaller.py +4 -2
  51. DIRAC/FrameworkSystem/DB/ProxyDB.py +9 -5
  52. DIRAC/FrameworkSystem/Utilities/TokenManagementUtilities.py +3 -2
  53. DIRAC/FrameworkSystem/Utilities/diracx.py +2 -74
  54. DIRAC/FrameworkSystem/private/authorization/AuthServer.py +2 -2
  55. DIRAC/FrameworkSystem/scripts/dirac_login.py +2 -2
  56. DIRAC/FrameworkSystem/scripts/dirac_proxy_init.py +1 -1
  57. DIRAC/Interfaces/API/Dirac.py +27 -13
  58. DIRAC/Interfaces/API/DiracAdmin.py +42 -7
  59. DIRAC/Interfaces/API/Job.py +1 -0
  60. DIRAC/Interfaces/scripts/dirac_admin_allow_site.py +7 -1
  61. DIRAC/Interfaces/scripts/dirac_admin_ban_site.py +7 -1
  62. DIRAC/Interfaces/scripts/dirac_wms_job_parameters.py +0 -1
  63. DIRAC/MonitoringSystem/Client/Types/WMSHistory.py +4 -0
  64. DIRAC/MonitoringSystem/Client/WebAppClient.py +26 -0
  65. DIRAC/MonitoringSystem/ConfigTemplate.cfg +9 -0
  66. DIRAC/MonitoringSystem/DB/MonitoringDB.py +6 -25
  67. DIRAC/MonitoringSystem/Service/MonitoringHandler.py +0 -33
  68. DIRAC/MonitoringSystem/Service/WebAppHandler.py +599 -0
  69. DIRAC/MonitoringSystem/private/MainReporter.py +0 -3
  70. DIRAC/ProductionSystem/scripts/dirac_prod_get_trans.py +2 -3
  71. DIRAC/RequestManagementSystem/Agent/RequestExecutingAgent.py +8 -6
  72. DIRAC/RequestManagementSystem/ConfigTemplate.cfg +6 -6
  73. DIRAC/RequestManagementSystem/DB/test/RMSTestScenari.py +2 -0
  74. DIRAC/ResourceStatusSystem/Client/SiteStatus.py +4 -2
  75. DIRAC/ResourceStatusSystem/Command/FreeDiskSpaceCommand.py +3 -1
  76. DIRAC/ResourceStatusSystem/Utilities/CSHelpers.py +2 -31
  77. DIRAC/ResourceStatusSystem/scripts/dirac_rss_set_status.py +18 -4
  78. DIRAC/Resources/Catalog/RucioFileCatalogClient.py +1 -1
  79. DIRAC/Resources/Computing/AREXComputingElement.py +19 -3
  80. DIRAC/Resources/Computing/BatchSystems/Condor.py +126 -108
  81. DIRAC/Resources/Computing/BatchSystems/SLURM.py +5 -1
  82. DIRAC/Resources/Computing/BatchSystems/test/Test_SLURM.py +46 -0
  83. DIRAC/Resources/Computing/HTCondorCEComputingElement.py +37 -43
  84. DIRAC/Resources/Computing/SingularityComputingElement.py +6 -1
  85. DIRAC/Resources/Computing/test/Test_HTCondorCEComputingElement.py +67 -49
  86. DIRAC/Resources/Computing/test/Test_PoolComputingElement.py +2 -1
  87. DIRAC/Resources/IdProvider/CheckInIdProvider.py +13 -0
  88. DIRAC/Resources/IdProvider/IdProviderFactory.py +11 -3
  89. DIRAC/Resources/Storage/StorageBase.py +4 -2
  90. DIRAC/Resources/Storage/StorageElement.py +4 -4
  91. DIRAC/TransformationSystem/Agent/TaskManagerAgentBase.py +10 -16
  92. DIRAC/TransformationSystem/Agent/TransformationAgent.py +22 -1
  93. DIRAC/TransformationSystem/Agent/TransformationCleaningAgent.py +15 -15
  94. DIRAC/TransformationSystem/Client/Transformation.py +2 -1
  95. DIRAC/TransformationSystem/Client/TransformationClient.py +0 -7
  96. DIRAC/TransformationSystem/Client/Utilities.py +9 -0
  97. DIRAC/TransformationSystem/Service/TransformationManagerHandler.py +0 -336
  98. DIRAC/TransformationSystem/Utilities/ReplicationCLIParameters.py +3 -3
  99. DIRAC/TransformationSystem/scripts/dirac_production_runjoblocal.py +2 -4
  100. DIRAC/TransformationSystem/test/Test_replicationTransformation.py +5 -6
  101. DIRAC/Workflow/Modules/test/Test_Modules.py +5 -0
  102. DIRAC/WorkloadManagementSystem/Agent/JobAgent.py +1 -5
  103. DIRAC/WorkloadManagementSystem/Agent/JobCleaningAgent.py +11 -7
  104. DIRAC/WorkloadManagementSystem/Agent/PilotSyncAgent.py +4 -3
  105. DIRAC/WorkloadManagementSystem/Agent/PushJobAgent.py +13 -13
  106. DIRAC/WorkloadManagementSystem/Agent/SiteDirector.py +10 -13
  107. DIRAC/WorkloadManagementSystem/Agent/StalledJobAgent.py +18 -51
  108. DIRAC/WorkloadManagementSystem/Agent/StatesAccountingAgent.py +41 -1
  109. DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_JobAgent.py +2 -0
  110. DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_JobCleaningAgent.py +7 -9
  111. DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_PushJobAgent.py +1 -0
  112. DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_SiteDirector.py +8 -2
  113. DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_StalledJobAgent.py +4 -5
  114. DIRAC/WorkloadManagementSystem/Client/DownloadInputData.py +7 -5
  115. DIRAC/WorkloadManagementSystem/Client/JobMonitoringClient.py +10 -11
  116. DIRAC/WorkloadManagementSystem/Client/JobState/JobManifest.py +32 -261
  117. DIRAC/WorkloadManagementSystem/Client/JobStateUpdateClient.py +3 -0
  118. DIRAC/WorkloadManagementSystem/Client/JobStatus.py +8 -152
  119. DIRAC/WorkloadManagementSystem/Client/SandboxStoreClient.py +25 -38
  120. DIRAC/WorkloadManagementSystem/Client/WMSClient.py +2 -3
  121. DIRAC/WorkloadManagementSystem/Client/test/Test_Client_DownloadInputData.py +29 -0
  122. DIRAC/WorkloadManagementSystem/ConfigTemplate.cfg +4 -8
  123. DIRAC/WorkloadManagementSystem/DB/JobDB.py +40 -69
  124. DIRAC/WorkloadManagementSystem/DB/JobDBUtils.py +18 -147
  125. DIRAC/WorkloadManagementSystem/DB/JobParametersDB.py +9 -9
  126. DIRAC/WorkloadManagementSystem/DB/PilotAgentsDB.py +3 -2
  127. DIRAC/WorkloadManagementSystem/DB/SandboxMetadataDB.py +28 -39
  128. DIRAC/WorkloadManagementSystem/DB/StatusUtils.py +125 -0
  129. DIRAC/WorkloadManagementSystem/DB/tests/Test_JobDB.py +1 -1
  130. DIRAC/WorkloadManagementSystem/DB/tests/Test_StatusUtils.py +28 -0
  131. DIRAC/WorkloadManagementSystem/Executor/JobSanity.py +3 -3
  132. DIRAC/WorkloadManagementSystem/FutureClient/JobStateUpdateClient.py +2 -14
  133. DIRAC/WorkloadManagementSystem/JobWrapper/JobWrapper.py +14 -9
  134. DIRAC/WorkloadManagementSystem/JobWrapper/test/Test_JobWrapper.py +36 -10
  135. DIRAC/WorkloadManagementSystem/JobWrapper/test/Test_JobWrapperTemplate.py +4 -0
  136. DIRAC/WorkloadManagementSystem/Service/JobManagerHandler.py +33 -154
  137. DIRAC/WorkloadManagementSystem/Service/JobMonitoringHandler.py +5 -323
  138. DIRAC/WorkloadManagementSystem/Service/JobStateUpdateHandler.py +0 -16
  139. DIRAC/WorkloadManagementSystem/Service/PilotManagerHandler.py +6 -102
  140. DIRAC/WorkloadManagementSystem/Service/SandboxStoreHandler.py +5 -51
  141. DIRAC/WorkloadManagementSystem/Service/WMSAdministratorHandler.py +16 -79
  142. DIRAC/WorkloadManagementSystem/Utilities/JobModel.py +28 -199
  143. DIRAC/WorkloadManagementSystem/Utilities/JobParameters.py +65 -3
  144. DIRAC/WorkloadManagementSystem/Utilities/JobStatusUtility.py +2 -64
  145. DIRAC/WorkloadManagementSystem/Utilities/ParametricJob.py +7 -171
  146. DIRAC/WorkloadManagementSystem/Utilities/PilotCStoJSONSynchronizer.py +73 -7
  147. DIRAC/WorkloadManagementSystem/Utilities/PilotWrapper.py +2 -0
  148. DIRAC/WorkloadManagementSystem/Utilities/RemoteRunner.py +16 -0
  149. DIRAC/WorkloadManagementSystem/Utilities/Utils.py +36 -1
  150. DIRAC/WorkloadManagementSystem/Utilities/jobAdministration.py +15 -0
  151. DIRAC/WorkloadManagementSystem/Utilities/test/Test_JobModel.py +1 -5
  152. DIRAC/WorkloadManagementSystem/Utilities/test/Test_ParametricJob.py +45 -128
  153. DIRAC/WorkloadManagementSystem/Utilities/test/Test_PilotWrapper.py +16 -0
  154. DIRAC/__init__.py +55 -54
  155. {dirac-9.0.0a54.dist-info → dirac-9.0.7.dist-info}/METADATA +6 -4
  156. {dirac-9.0.0a54.dist-info → dirac-9.0.7.dist-info}/RECORD +160 -160
  157. {dirac-9.0.0a54.dist-info → dirac-9.0.7.dist-info}/WHEEL +1 -1
  158. {dirac-9.0.0a54.dist-info → dirac-9.0.7.dist-info}/entry_points.txt +0 -3
  159. DIRAC/Core/Utilities/test/Test_List.py +0 -150
  160. DIRAC/Core/Utilities/test/Test_Time.py +0 -88
  161. DIRAC/TransformationSystem/scripts/dirac_transformation_archive.py +0 -30
  162. DIRAC/TransformationSystem/scripts/dirac_transformation_clean.py +0 -30
  163. DIRAC/TransformationSystem/scripts/dirac_transformation_remove_output.py +0 -30
  164. DIRAC/WorkloadManagementSystem/Utilities/test/Test_JobManager.py +0 -58
  165. {dirac-9.0.0a54.dist-info → dirac-9.0.7.dist-info}/licenses/LICENSE +0 -0
  166. {dirac-9.0.0a54.dist-info → dirac-9.0.7.dist-info}/top_level.txt +0 -0
@@ -2,294 +2,8 @@
2
2
  Condor ClassAd library.
3
3
  """
4
4
 
5
+ # Import from DIRACCommon for backward compatibility
6
+ from DIRACCommon.Core.Utilities.ClassAd.ClassAdLight import ClassAd
5
7
 
6
- class ClassAd:
7
- def __init__(self, jdl):
8
- """ClassAd constructor from a JDL string"""
9
- self.contents = {}
10
- result = self.__analyse_jdl(jdl)
11
- if result:
12
- self.contents = result
13
-
14
- def __analyse_jdl(self, jdl, index=0):
15
- """Analyse one [] jdl enclosure"""
16
-
17
- jdl = jdl.strip()
18
-
19
- # Strip all the blanks first
20
- # temp = jdl.replace(' ','').replace('\n','')
21
- temp = jdl
22
-
23
- result = {}
24
-
25
- if temp[0] != "[" or temp[-1] != "]":
26
- print("Invalid JDL: it should start with [ and end with ]")
27
- return result
28
-
29
- # Parse the jdl string now
30
- body = temp[1:-1]
31
- index = 0
32
- namemode = 1
33
- valuemode = 0
34
- while index < len(body):
35
- if namemode:
36
- ind = body.find("=", index)
37
- if ind != -1:
38
- name = body[index:ind]
39
- index = ind + 1
40
- valuemode = 1
41
- namemode = 0
42
- else:
43
- break
44
- elif valuemode:
45
- ind1 = body.find("[", index)
46
- ind2 = body.find(";", index)
47
- if ind1 != -1 and ind1 < ind2:
48
- value, newind = self.__find_subjdl(body, ind1)
49
- elif ind1 == -1 and ind2 == -1:
50
- value = body[index:]
51
- newind = len(body)
52
- else:
53
- if index == ind2:
54
- return {}
55
- else:
56
- value = body[index:ind2]
57
- newind = ind2 + 1
58
-
59
- result[name.strip()] = value.strip().replace("\n", "")
60
- index = newind
61
- valuemode = 0
62
- namemode = 1
63
-
64
- return result
65
-
66
- def __find_subjdl(self, body, index):
67
- """Find a full [] enclosure starting from index"""
68
- result = ""
69
- if body[index] != "[":
70
- return (result, 0)
71
-
72
- depth = 0
73
- ind = index
74
- while depth < 10:
75
- ind1 = body.find("]", ind + 1)
76
- ind2 = body.find("[", ind + 1)
77
- if ind2 != -1 and ind2 < ind1:
78
- depth += 1
79
- ind = ind2
80
- else:
81
- if depth > 0:
82
- depth -= 1
83
- ind = ind1
84
- else:
85
- result = body[index : ind1 + 1]
86
- if body[ind1 + 1] == ";":
87
- return (result, ind1 + 2)
88
- return result, 0
89
-
90
- return result, 0
91
-
92
- def insertAttributeInt(self, name, attribute):
93
- """Insert a named integer attribute"""
94
-
95
- self.contents[name] = str(attribute)
96
-
97
- def insertAttributeBool(self, name, attribute):
98
- """Insert a named boolean attribute"""
99
-
100
- if attribute:
101
- self.contents[name] = "true"
102
- else:
103
- self.contents[name] = "false"
104
-
105
- def insertAttributeString(self, name, attribute):
106
- """Insert a named string attribute"""
107
-
108
- self.contents[name] = '"' + str(attribute) + '"'
109
-
110
- def insertAttributeVectorString(self, name, attributelist):
111
- """Insert a named string list attribute"""
112
-
113
- tmp = ['"' + x + '"' for x in attributelist]
114
- tmpstr = ",".join(tmp)
115
- self.contents[name] = "{" + tmpstr + "}"
116
-
117
- def insertAttributeVectorInt(self, name, attributelist):
118
- """Insert a named string list attribute"""
119
-
120
- tmp = [str(x) for x in attributelist]
121
- tmpstr = ",".join(tmp)
122
- self.contents[name] = "{" + tmpstr + "}"
123
-
124
- def insertAttributeVectorStringList(self, name, attributelist):
125
- """Insert a named list of string lists"""
126
-
127
- listOfLists = []
128
- for stringList in attributelist:
129
- # tmp = map ( lambda x : '"' + x + '"', stringList )
130
- tmpstr = ",".join(stringList)
131
- listOfLists.append("{" + tmpstr + "}")
132
- self.contents[name] = "{" + ",".join(listOfLists) + "}"
133
-
134
- def lookupAttribute(self, name):
135
- """Check the presence of the given attribute"""
136
-
137
- return name in self.contents
138
-
139
- def set_expression(self, name, attribute):
140
- """Insert a named expression attribute"""
141
-
142
- self.contents[name] = str(attribute)
143
-
144
- def get_expression(self, name):
145
- """Get expression corresponding to a named attribute"""
146
-
147
- if name in self.contents:
148
- if isinstance(self.contents[name], int):
149
- return str(self.contents[name])
150
- return self.contents[name]
151
- return ""
152
-
153
- def isAttributeList(self, name):
154
- """Check if the given attribute is of the List type"""
155
- attribute = self.get_expression(name).strip()
156
- return attribute.startswith("{")
157
-
158
- def getListFromExpression(self, name):
159
- """Get a list of strings from a given expression"""
160
-
161
- tempString = self.get_expression(name).strip()
162
- listMode = False
163
- if tempString.startswith("{"):
164
- tempString = tempString[1:-1]
165
- listMode = True
166
-
167
- tempString = tempString.replace(" ", "").replace("\n", "")
168
- if tempString.find("{") < 0:
169
- if not listMode:
170
- tempString = tempString.replace('"', "")
171
- if not tempString:
172
- return []
173
- return tempString.split(",")
174
-
175
- resultList = []
176
- while tempString:
177
- if tempString.find("{") == 0:
178
- end = tempString.find("}")
179
- resultList.append(tempString[: end + 1])
180
- tempString = tempString[end + 1 :]
181
- if tempString.startswith(","):
182
- tempString = tempString[1:]
183
- elif tempString.find('"') == 0:
184
- end = tempString[1:].find('"')
185
- resultList.append(tempString[1 : end + 1])
186
- tempString = tempString[end + 2 :]
187
- if tempString.startswith(","):
188
- tempString = tempString[1:]
189
- else:
190
- end = tempString.find(",")
191
- if end < 0:
192
- resultList.append(tempString.replace('"', "").replace(" ", ""))
193
- break
194
- else:
195
- resultList.append(tempString[:end].replace('"', "").replace(" ", ""))
196
- tempString = tempString[end + 1 :]
197
-
198
- return resultList
199
-
200
- def getDictionaryFromSubJDL(self, name):
201
- """Get a dictionary of the JDL attributes from a subsection"""
202
-
203
- tempList = self.get_expression(name)[1:-1]
204
- resDict = {}
205
- for item in tempList.split(";"):
206
- if len(item.split("=")) == 2:
207
- resDict[item.split("=")[0].strip()] = item.split("=")[1].strip().replace('"', "")
208
- else:
209
- return {}
210
-
211
- return resDict
212
-
213
- def deleteAttribute(self, name):
214
- """Delete a named attribute"""
215
-
216
- if name in self.contents:
217
- del self.contents[name]
218
- return 1
219
- return 0
220
-
221
- def isOK(self):
222
- """Check the JDL validity - to be defined"""
223
-
224
- if self.contents:
225
- return 1
226
- return 0
227
-
228
- def asJDL(self):
229
- """Convert the JDL description into a string"""
230
-
231
- result = []
232
- for name, value in sorted(self.contents.items()):
233
- if value[0:1] == "{":
234
- result += [4 * " " + name + " = \n"]
235
- result += [8 * " " + "{\n"]
236
- strings = value[1:-1].split(",")
237
- for st in strings:
238
- result += [12 * " " + st.strip() + ",\n"]
239
- result[-1] = result[-1][:-2]
240
- result += ["\n" + 8 * " " + "};\n"]
241
- elif value[0:1] == "[":
242
- tempad = ClassAd(value)
243
- tempjdl = tempad.asJDL() + ";"
244
- lines = tempjdl.split("\n")
245
- result += [4 * " " + name + " = \n"]
246
- for line in lines:
247
- result += [8 * " " + line + "\n"]
248
-
249
- else:
250
- result += [4 * " " + name + " = " + str(value) + ";\n"]
251
- if result:
252
- result[-1] = result[-1][:-1]
253
- return "[ \n" + "".join(result) + "\n]"
254
-
255
- def getAttributeString(self, name):
256
- """Get String type attribute value"""
257
- value = ""
258
- if self.lookupAttribute(name):
259
- value = self.get_expression(name).replace('"', "")
260
- return value
261
-
262
- def getAttributeInt(self, name):
263
- """Get Integer type attribute value"""
264
- value = None
265
- if self.lookupAttribute(name):
266
- try:
267
- value = int(self.get_expression(name).replace('"', ""))
268
- except Exception:
269
- value = None
270
- return value
271
-
272
- def getAttributeBool(self, name):
273
- """Get Boolean type attribute value"""
274
- if not self.lookupAttribute(name):
275
- return False
276
-
277
- value = self.get_expression(name).replace('"', "")
278
- return value.lower() == "true"
279
-
280
- def getAttributeFloat(self, name):
281
- """Get Float type attribute value"""
282
- value = None
283
- if self.lookupAttribute(name):
284
- try:
285
- value = float(self.get_expression(name).replace('"', ""))
286
- except Exception:
287
- value = None
288
- return value
289
-
290
- def getAttributes(self) -> list[str]:
291
- """Get the list of all the attribute names
292
-
293
- :return: list of names as strings
294
- """
295
- return list(self.contents)
8
+ # Re-export for backward compatibility
9
+ __all__ = ["ClassAd"]
@@ -37,320 +37,16 @@
37
37
  DErrno.ERRX : ['An error message for ERRX that is specific to LHCb']}
38
38
 
39
39
  """
40
- import os
41
40
  import importlib
42
41
  import sys
43
42
 
44
- from DIRAC.Core.Utilities.Extensions import extensionsByPriority
45
-
46
- # To avoid conflict, the error numbers should be greater than 1000
47
- # We decided to group the by range of 100 per system
48
-
49
- # 1000: Generic
50
- # 1100: Core
51
- # 1200: Framework
52
- # 1300: Interfaces
53
- # 1400: Config
54
- # 1500: WMS + Workflow
55
- # 1600: DMS + StorageManagement
56
- # 1700: RMS
57
- # 1800: Accounting + Monitoring
58
- # 1900: TS + Production
59
- # 2000: Resources + RSS
60
-
61
- # ## Generic (10XX)
62
- # Python related: 0X
63
- ETYPE = 1000
64
- EIMPERR = 1001
65
- ENOMETH = 1002
66
- ECONF = 1003
67
- EVALUE = 1004
68
- EEEXCEPTION = 1005
69
- # Files manipulation: 1X
70
- ECTMPF = 1010
71
- EOF = 1011
72
- ERF = 1012
73
- EWF = 1013
74
- ESPF = 1014
75
-
76
- # ## Core (11XX)
77
- # Certificates and Proxy: 0X
78
- EX509 = 1100
79
- EPROXYFIND = 1101
80
- EPROXYREAD = 1102
81
- ECERTFIND = 1103
82
- ECERTREAD = 1104
83
- ENOCERT = 1105
84
- ENOCHAIN = 1106
85
- ENOPKEY = 1107
86
- ENOGROUP = 1108
87
- # DISET: 1X
88
- EDISET = 1110
89
- ENOAUTH = 1111
90
- # 3rd party security: 2X
91
- E3RDPARTY = 1120
92
- EVOMS = 1121
93
- # Databases : 3X
94
- EDB = 1130
95
- EMYSQL = 1131
96
- ESQLA = 1132
97
- # Message Queues: 4X
98
- EMQUKN = 1140
99
- EMQNOM = 1141
100
- EMQCONN = 1142
101
- # OpenSearch
102
- EELNOFOUND = 1146
103
- # Tokens
104
- EATOKENFIND = 1150
105
- EATOKENREAD = 1151
106
- ETOKENTYPE = 1152
107
-
108
- # config
109
- ESECTION = 1400
110
-
111
- # processes
112
- EEZOMBIE = 1147
113
- EENOPID = 1148
114
-
115
- # ## WMS/Workflow
116
- EWMSUKN = 1500
117
- EWMSJDL = 1501
118
- EWMSRESC = 1502
119
- EWMSSUBM = 1503
120
- EWMSJMAN = 1504
121
- EWMSSTATUS = 1505
122
- EWMSNOMATCH = 1510
123
- EWMSPLTVER = 1511
124
- EWMSNOPILOT = 1550
125
-
126
- # ## DMS/StorageManagement (16XX)
127
- EFILESIZE = 1601
128
- EGFAL = 1602
129
- EBADCKS = 1603
130
- EFCERR = 1604
131
-
132
- # ## RMS (17XX)
133
- ERMSUKN = 1700
134
-
135
- # ## TS (19XX)
136
- ETSUKN = 1900
137
- ETSDATA = 1901
138
-
139
- # ## Resources and RSS (20XX)
140
- ERESGEN = 2000
141
- ERESUNA = 2001
142
- ERESUNK = 2002
143
-
144
- # This translates the integer number into the name of the variable
145
- dErrorCode = {
146
- # ## Generic (10XX)
147
- # 100X: Python related
148
- 1000: "ETYPE",
149
- 1001: "EIMPERR",
150
- 1002: "ENOMETH",
151
- 1003: "ECONF",
152
- 1004: "EVALUE",
153
- 1005: "EEEXCEPTION",
154
- # 101X: Files manipulation
155
- 1010: "ECTMPF",
156
- 1011: "EOF",
157
- 1012: "ERF",
158
- 1013: "EWF",
159
- 1014: "ESPF",
160
- # ## Core
161
- # 110X: Certificates and Proxy
162
- 1100: "EX509",
163
- 1101: "EPROXYFIND",
164
- 1102: "EPROXYREAD",
165
- 1103: "ECERTFIND",
166
- 1104: "ECERTREAD",
167
- 1105: "ENOCERT",
168
- 1106: "ENOCHAIN",
169
- 1107: "ENOPKEY",
170
- 1108: "ENOGROUP",
171
- # 111X: DISET
172
- 1110: "EDISET",
173
- 1111: "ENOAUTH",
174
- # 112X: 3rd party security
175
- 1120: "E3RDPARTY",
176
- 1121: "EVOMS",
177
- # 113X: Databases
178
- 1130: "EDB",
179
- 1131: "EMYSQL",
180
- 1132: "ESQLA",
181
- # 114X: Message Queues
182
- 1140: "EMQUKN",
183
- 1141: "EMQNOM",
184
- 1142: "EMQCONN",
185
- # OpenSearch
186
- 1146: "EELNOFOUND",
187
- # 115X: Tokens
188
- 1150: "EATOKENFIND",
189
- 1151: "EATOKENREAD",
190
- 1152: "ETOKENTYPE",
191
- # Config
192
- 1400: "ESECTION",
193
- # Processes
194
- 1147: "EEZOMBIE",
195
- 1148: "EENOPID",
196
- # WMS/Workflow
197
- 1500: "EWMSUKN",
198
- 1501: "EWMSJDL",
199
- 1502: "EWMSRESC",
200
- 1503: "EWMSSUBM",
201
- 1504: "EWMSJMAN",
202
- 1505: "EWMSSTATUS",
203
- 1510: "EWMSNOMATCH",
204
- 1511: "EWMSPLTVER",
205
- 1550: "EWMSNOPILOT",
206
- # DMS/StorageManagement
207
- 1601: "EFILESIZE",
208
- 1602: "EGFAL",
209
- 1603: "EBADCKS",
210
- 1604: "EFCERR",
211
- # RMS
212
- 1700: "ERMSUKN",
213
- # Resources and RSS
214
- 2000: "ERESGEN",
215
- 2001: "ERESUNA",
216
- 2002: "ERESUNK",
217
- # TS
218
- 1900: "ETSUKN",
219
- 1901: "ETSDATA",
220
- }
221
-
222
-
223
- dStrError = { # Generic (10XX)
224
- # 100X: Python related
225
- ETYPE: "Object Type Error",
226
- EIMPERR: "Failed to import library",
227
- ENOMETH: "No such method or function",
228
- ECONF: "Configuration error",
229
- EVALUE: "Wrong value passed",
230
- EEEXCEPTION: "runtime general exception",
231
- # 101X: Files manipulation
232
- ECTMPF: "Failed to create temporary file",
233
- EOF: "Cannot open file",
234
- ERF: "Cannot read from file",
235
- EWF: "Cannot write to file",
236
- ESPF: "Cannot set permissions to file",
237
- # ## Core
238
- # 110X: Certificates and Proxy
239
- EX509: "Generic Error with X509",
240
- EPROXYFIND: "Can't find proxy",
241
- EPROXYREAD: "Can't read proxy",
242
- ECERTFIND: "Can't find certificate",
243
- ECERTREAD: "Can't read certificate",
244
- ENOCERT: "No certificate loaded",
245
- ENOCHAIN: "No chain loaded",
246
- ENOPKEY: "No private key loaded",
247
- ENOGROUP: "No DIRAC group",
248
- # 111X: DISET
249
- EDISET: "DISET Error",
250
- ENOAUTH: "Unauthorized query",
251
- # 112X: 3rd party security
252
- E3RDPARTY: "3rd party security service error",
253
- EVOMS: "VOMS Error",
254
- # 113X: Databases
255
- EDB: "Database Error",
256
- EMYSQL: "MySQL Error",
257
- ESQLA: "SQLAlchemy Error",
258
- # 114X: Message Queues
259
- EMQUKN: "Unknown MQ Error",
260
- EMQNOM: "No messages",
261
- EMQCONN: "MQ connection failure",
262
- # 114X OpenSearch
263
- EELNOFOUND: "Index not found",
264
- # 115X: Tokens
265
- EATOKENFIND: "Can't find a bearer access token.",
266
- EATOKENREAD: "Can't read a bearer access token.",
267
- ETOKENTYPE: "Unsupported access token type.",
268
- # Config
269
- ESECTION: "Section is not found",
270
- # processes
271
- EEZOMBIE: "Zombie process",
272
- EENOPID: "No PID of process",
273
- # WMS/Workflow
274
- EWMSUKN: "Unknown WMS error",
275
- EWMSJDL: "Invalid job description",
276
- EWMSRESC: "Job to reschedule",
277
- EWMSSUBM: "Job submission error",
278
- EWMSJMAN: "Job management error",
279
- EWMSSTATUS: "Job status error",
280
- EWMSNOPILOT: "No pilots found",
281
- EWMSPLTVER: "Pilot version does not match",
282
- EWMSNOMATCH: "No match found",
283
- # DMS/StorageManagement
284
- EFILESIZE: "Bad file size",
285
- EGFAL: "Error with the gfal call",
286
- EBADCKS: "Bad checksum",
287
- EFCERR: "FileCatalog error",
288
- # RMS
289
- ERMSUKN: "Unknown RMS error",
290
- # Resources and RSS
291
- ERESGEN: "Unknown Resource Failure",
292
- ERESUNA: "Resource not available",
293
- ERESUNK: "Unknown Resource",
294
- # TS
295
- ETSUKN: "Unknown Transformation System Error",
296
- ETSDATA: "Invalid Input Data definition",
297
- }
43
+ # Import all the stateless parts from DIRACCommon
44
+ from DIRACCommon.Core.Utilities.DErrno import * # noqa: F401, F403
298
45
 
46
+ from DIRAC.Core.Utilities.Extensions import extensionsByPriority
299
47
 
300
- def strerror(code: int) -> str:
301
- """This method wraps up os.strerror, and behave the same way.
302
- It completes it with the DIRAC specific errors.
303
- """
304
-
305
- if code == 0:
306
- return "Undefined error"
307
-
308
- errMsg = f"Unknown error {code}"
309
-
310
- try:
311
- errMsg = dStrError[code]
312
- except KeyError:
313
- # It is not a DIRAC specific error, try the os one
314
- try:
315
- errMsg = os.strerror(code)
316
- # On some system, os.strerror raises an exception with unknown code,
317
- # on others, it returns a message...
318
- except ValueError:
319
- pass
320
-
321
- return errMsg
322
-
323
-
324
- def cmpError(inErr, candidate):
325
- """This function compares an error (in its old form (a string or dictionary) or in its int form
326
- with a candidate error code.
327
-
328
- :param inErr: a string, an integer, a S_ERROR dictionary
329
- :type inErr: str or int or S_ERROR
330
- :param int candidate: error code to compare with
331
-
332
- :return: True or False
333
-
334
- If an S_ERROR instance is passed, we compare the code with S_ERROR['Errno']
335
- If it is a Integer, we do a direct comparison
336
- If it is a String, we use strerror to check the error string
337
- """
338
-
339
- if isinstance(inErr, str): # old style
340
- # Compare error message strings
341
- errMsg = strerror(candidate)
342
- return errMsg in inErr
343
- elif isinstance(inErr, dict): # if the S_ERROR structure is given
344
- # Check if Errno defined in the dict
345
- errorNumber = inErr.get("Errno")
346
- if errorNumber:
347
- return errorNumber == candidate
348
- errMsg = strerror(candidate)
349
- return errMsg in inErr.get("Message", "")
350
- elif isinstance(inErr, int):
351
- return inErr == candidate
352
- else:
353
- raise TypeError(f"Unknown input error type {type(inErr)}")
48
+ # compatErrorString is used by the extension mechanism but not in DIRACCommon
49
+ compatErrorString = {}
354
50
 
355
51
 
356
52
  def includeExtensionErrors():
@@ -73,6 +73,15 @@ def findServices(modules):
73
73
  return findModules(modules, "Service", "*Handler")
74
74
 
75
75
 
76
+ def findFutureServices(modules):
77
+ """Find the legacy adapted services for one or more DIRAC extension(s)
78
+
79
+ :param list/str/module module: One or more Python modules or Python module names
80
+ :returns: list of tuples of the form (SystemName, ServiceName)
81
+ """
82
+ return findModules(modules, "FutureClient")
83
+
84
+
76
85
  @iterateThenSort
77
86
  def findDatabases(module):
78
87
  """Find the DB SQL schema defintions for one or more DIRAC extension(s)
@@ -182,7 +191,7 @@ def parseArgs():
182
191
  parser = argparse.ArgumentParser()
183
192
  subparsers = parser.add_subparsers(required=True, dest="function")
184
193
  defaultExtensions = extensionsByPriority()
185
- for func in [findSystems, findAgents, findExecutors, findServices, findDatabases]:
194
+ for func in [findSystems, findAgents, findExecutors, findServices, findDatabases, findFutureServices]:
186
195
  subparser = subparsers.add_parser(func.__name__)
187
196
  subparser.add_argument("--extensions", nargs="+", default=defaultExtensions)
188
197
  subparser.set_defaults(func=func)
@@ -411,7 +411,7 @@ class PlotData:
411
411
  self.num_keys.append(next)
412
412
  next += 1
413
413
  elif self.key_type == "time":
414
- self.num_keys = [date2num(datetime.datetime.fromtimestamp(to_timestamp(key))) for key in self.keys]
414
+ self.num_keys = [date2num(datetime.datetime.utcfromtimestamp(to_timestamp(key))) for key in self.keys]
415
415
  elif self.key_type == "numeric":
416
416
  self.num_keys = [float(key) for key in self.keys]
417
417