DIRAC 9.0.0a42__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 (236) 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 +38 -26
  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 +32 -19
  14. DIRAC/ConfigurationSystem/Client/test/Test_PathFinder.py +41 -1
  15. DIRAC/ConfigurationSystem/private/RefresherBase.py +4 -2
  16. DIRAC/Core/Base/API.py +4 -7
  17. DIRAC/Core/Base/SQLAlchemyDB.py +1 -0
  18. DIRAC/Core/DISET/ServiceReactor.py +11 -3
  19. DIRAC/Core/DISET/private/BaseClient.py +1 -2
  20. DIRAC/Core/DISET/private/Transports/M2SSLTransport.py +9 -7
  21. DIRAC/Core/DISET/private/Transports/SSL/M2Utils.py +3 -1
  22. DIRAC/Core/LCG/GOCDBClient.py +5 -7
  23. DIRAC/Core/Security/DiracX.py +31 -17
  24. DIRAC/Core/Security/IAMService.py +5 -10
  25. DIRAC/Core/Security/Locations.py +27 -18
  26. DIRAC/Core/Security/ProxyInfo.py +9 -5
  27. DIRAC/Core/Security/VOMSService.py +2 -4
  28. DIRAC/Core/Security/m2crypto/X509Certificate.py +4 -6
  29. DIRAC/Core/Security/m2crypto/asn1_utils.py +17 -5
  30. DIRAC/Core/Security/test/test_diracx_token_from_pem.py +161 -0
  31. DIRAC/Core/Tornado/Client/ClientSelector.py +4 -1
  32. DIRAC/Core/Tornado/Server/TornadoService.py +1 -1
  33. DIRAC/Core/Utilities/CGroups2.py +328 -0
  34. DIRAC/Core/Utilities/ClassAd/ClassAdLight.py +4 -290
  35. DIRAC/Core/Utilities/DErrno.py +5 -309
  36. DIRAC/Core/Utilities/Extensions.py +10 -1
  37. DIRAC/Core/Utilities/File.py +1 -1
  38. DIRAC/Core/Utilities/Graphs/GraphData.py +1 -1
  39. DIRAC/Core/Utilities/Graphs/GraphUtilities.py +6 -1
  40. DIRAC/Core/Utilities/JDL.py +1 -195
  41. DIRAC/Core/Utilities/List.py +1 -124
  42. DIRAC/Core/Utilities/MySQL.py +103 -99
  43. DIRAC/Core/Utilities/Os.py +32 -1
  44. DIRAC/Core/Utilities/Platform.py +2 -107
  45. DIRAC/Core/Utilities/Proxy.py +0 -4
  46. DIRAC/Core/Utilities/ReturnValues.py +7 -252
  47. DIRAC/Core/Utilities/StateMachine.py +12 -178
  48. DIRAC/Core/Utilities/Subprocess.py +35 -14
  49. DIRAC/Core/Utilities/TimeUtilities.py +10 -253
  50. DIRAC/Core/Utilities/test/Test_JDL.py +0 -3
  51. DIRAC/Core/Utilities/test/Test_Profiler.py +20 -20
  52. DIRAC/Core/scripts/dirac_agent.py +1 -1
  53. DIRAC/Core/scripts/dirac_apptainer_exec.py +72 -46
  54. DIRAC/Core/scripts/dirac_configure.py +1 -3
  55. DIRAC/Core/scripts/dirac_install_db.py +24 -6
  56. DIRAC/Core/scripts/dirac_platform.py +1 -92
  57. DIRAC/DataManagementSystem/Agent/FTS3Agent.py +8 -7
  58. DIRAC/DataManagementSystem/Agent/RequestOperations/RemoveFile.py +7 -6
  59. DIRAC/DataManagementSystem/Client/FTS3Job.py +71 -34
  60. DIRAC/DataManagementSystem/DB/FTS3DB.py +7 -3
  61. DIRAC/DataManagementSystem/DB/FileCatalogComponents/DatasetManager/DatasetManager.py +1 -1
  62. DIRAC/DataManagementSystem/DB/FileCatalogDB.sql +9 -9
  63. DIRAC/DataManagementSystem/DB/FileCatalogWithFkAndPsDB.sql +9 -9
  64. DIRAC/DataManagementSystem/Utilities/DMSHelpers.py +6 -2
  65. DIRAC/DataManagementSystem/scripts/dirac_admin_allow_se.py +13 -8
  66. DIRAC/DataManagementSystem/scripts/dirac_admin_ban_se.py +13 -8
  67. DIRAC/DataManagementSystem/scripts/dirac_dms_create_moving_request.py +2 -0
  68. DIRAC/DataManagementSystem/scripts/dirac_dms_protocol_matrix.py +0 -1
  69. DIRAC/FrameworkSystem/Client/BundleDeliveryClient.py +2 -7
  70. DIRAC/FrameworkSystem/Client/ComponentInstaller.py +9 -4
  71. DIRAC/FrameworkSystem/Client/ProxyManagerClient.py +5 -2
  72. DIRAC/FrameworkSystem/Client/SystemAdministratorClientCLI.py +11 -6
  73. DIRAC/FrameworkSystem/ConfigTemplate.cfg +2 -0
  74. DIRAC/FrameworkSystem/DB/AuthDB.py +3 -3
  75. DIRAC/FrameworkSystem/DB/InstalledComponentsDB.py +4 -4
  76. DIRAC/FrameworkSystem/DB/ProxyDB.py +11 -3
  77. DIRAC/FrameworkSystem/DB/TokenDB.py +1 -1
  78. DIRAC/FrameworkSystem/Service/ProxyManagerHandler.py +8 -6
  79. DIRAC/FrameworkSystem/Utilities/MonitoringUtilities.py +2 -19
  80. DIRAC/FrameworkSystem/Utilities/TokenManagementUtilities.py +3 -2
  81. DIRAC/FrameworkSystem/Utilities/diracx.py +36 -14
  82. DIRAC/FrameworkSystem/private/authorization/AuthServer.py +2 -2
  83. DIRAC/FrameworkSystem/scripts/dirac_admin_update_pilot.py +18 -11
  84. DIRAC/FrameworkSystem/scripts/dirac_login.py +2 -2
  85. DIRAC/FrameworkSystem/scripts/dirac_proxy_init.py +7 -8
  86. DIRAC/Interfaces/API/Dirac.py +27 -15
  87. DIRAC/Interfaces/API/DiracAdmin.py +45 -17
  88. DIRAC/Interfaces/API/Job.py +9 -13
  89. DIRAC/Interfaces/scripts/dirac_admin_allow_site.py +12 -18
  90. DIRAC/Interfaces/scripts/dirac_admin_ban_site.py +12 -10
  91. DIRAC/Interfaces/scripts/dirac_admin_get_site_mask.py +4 -13
  92. DIRAC/Interfaces/scripts/dirac_admin_reset_job.py +3 -6
  93. DIRAC/Interfaces/scripts/dirac_wms_job_parameters.py +0 -1
  94. DIRAC/MonitoringSystem/Client/Types/WMSHistory.py +4 -0
  95. DIRAC/MonitoringSystem/Client/WebAppClient.py +26 -0
  96. DIRAC/MonitoringSystem/ConfigTemplate.cfg +9 -0
  97. DIRAC/MonitoringSystem/DB/MonitoringDB.py +6 -25
  98. DIRAC/MonitoringSystem/Service/MonitoringHandler.py +0 -33
  99. DIRAC/MonitoringSystem/Service/WebAppHandler.py +599 -0
  100. DIRAC/MonitoringSystem/private/MainReporter.py +0 -3
  101. DIRAC/ProductionSystem/DB/ProductionDB.sql +4 -4
  102. DIRAC/ProductionSystem/scripts/dirac_prod_get.py +2 -2
  103. DIRAC/ProductionSystem/scripts/dirac_prod_get_all.py +2 -2
  104. DIRAC/ProductionSystem/scripts/dirac_prod_get_trans.py +2 -3
  105. DIRAC/RequestManagementSystem/Agent/RequestExecutingAgent.py +8 -6
  106. DIRAC/RequestManagementSystem/Agent/RequestOperations/ForwardDISET.py +2 -14
  107. DIRAC/RequestManagementSystem/Client/ReqClient.py +66 -13
  108. DIRAC/RequestManagementSystem/ConfigTemplate.cfg +6 -6
  109. DIRAC/RequestManagementSystem/DB/RequestDB.py +10 -5
  110. DIRAC/RequestManagementSystem/DB/test/RMSTestScenari.py +2 -0
  111. DIRAC/RequestManagementSystem/private/RequestValidator.py +40 -46
  112. DIRAC/ResourceStatusSystem/Client/SiteStatus.py +4 -2
  113. DIRAC/ResourceStatusSystem/Command/FreeDiskSpaceCommand.py +3 -1
  114. DIRAC/ResourceStatusSystem/DB/ResourceManagementDB.py +8 -8
  115. DIRAC/ResourceStatusSystem/DB/ResourceStatusDB.py +2 -2
  116. DIRAC/ResourceStatusSystem/Utilities/CSHelpers.py +2 -31
  117. DIRAC/ResourceStatusSystem/scripts/dirac_rss_set_status.py +30 -12
  118. DIRAC/Resources/Catalog/RucioFileCatalogClient.py +195 -1
  119. DIRAC/Resources/Catalog/test/Test_RucioFileCatalogClient.py +181 -0
  120. DIRAC/Resources/Computing/AREXComputingElement.py +25 -8
  121. DIRAC/Resources/Computing/BatchSystems/Condor.py +126 -108
  122. DIRAC/Resources/Computing/BatchSystems/SLURM.py +5 -1
  123. DIRAC/Resources/Computing/BatchSystems/test/Test_SLURM.py +46 -0
  124. DIRAC/Resources/Computing/ComputingElement.py +1 -1
  125. DIRAC/Resources/Computing/HTCondorCEComputingElement.py +44 -44
  126. DIRAC/Resources/Computing/InProcessComputingElement.py +4 -2
  127. DIRAC/Resources/Computing/LocalComputingElement.py +1 -18
  128. DIRAC/Resources/Computing/SSHBatchComputingElement.py +1 -17
  129. DIRAC/Resources/Computing/SSHComputingElement.py +1 -18
  130. DIRAC/Resources/Computing/SingularityComputingElement.py +19 -5
  131. DIRAC/Resources/Computing/test/Test_HTCondorCEComputingElement.py +67 -49
  132. DIRAC/Resources/Computing/test/Test_PoolComputingElement.py +2 -1
  133. DIRAC/Resources/IdProvider/CheckInIdProvider.py +13 -0
  134. DIRAC/Resources/IdProvider/IdProviderFactory.py +11 -3
  135. DIRAC/Resources/MessageQueue/StompMQConnector.py +1 -1
  136. DIRAC/Resources/Storage/GFAL2_StorageBase.py +24 -15
  137. DIRAC/Resources/Storage/OccupancyPlugins/WLCGAccountingHTTPJson.py +1 -3
  138. DIRAC/Resources/Storage/StorageBase.py +4 -2
  139. DIRAC/Resources/Storage/StorageElement.py +6 -7
  140. DIRAC/StorageManagementSystem/DB/StorageManagementDB.sql +2 -2
  141. DIRAC/TransformationSystem/Agent/TaskManagerAgentBase.py +10 -16
  142. DIRAC/TransformationSystem/Agent/TransformationAgent.py +22 -1
  143. DIRAC/TransformationSystem/Agent/TransformationCleaningAgent.py +16 -16
  144. DIRAC/TransformationSystem/Client/TaskManager.py +2 -4
  145. DIRAC/TransformationSystem/Client/Transformation.py +6 -7
  146. DIRAC/TransformationSystem/Client/TransformationClient.py +21 -11
  147. DIRAC/TransformationSystem/Client/Utilities.py +9 -0
  148. DIRAC/TransformationSystem/DB/TransformationDB.py +11 -14
  149. DIRAC/TransformationSystem/DB/TransformationDB.sql +9 -9
  150. DIRAC/TransformationSystem/Service/TransformationManagerHandler.py +0 -333
  151. DIRAC/TransformationSystem/Utilities/ReplicationCLIParameters.py +3 -3
  152. DIRAC/TransformationSystem/Utilities/TransformationInfo.py +7 -5
  153. DIRAC/TransformationSystem/scripts/dirac_production_runjoblocal.py +2 -4
  154. DIRAC/TransformationSystem/test/Test_TransformationInfo.py +22 -15
  155. DIRAC/TransformationSystem/test/Test_replicationTransformation.py +5 -6
  156. DIRAC/Workflow/Modules/test/Test_Modules.py +5 -0
  157. DIRAC/WorkloadManagementSystem/Agent/JobAgent.py +38 -26
  158. DIRAC/WorkloadManagementSystem/Agent/JobCleaningAgent.py +12 -8
  159. DIRAC/WorkloadManagementSystem/Agent/PilotSyncAgent.py +4 -3
  160. DIRAC/WorkloadManagementSystem/Agent/PushJobAgent.py +13 -13
  161. DIRAC/WorkloadManagementSystem/Agent/SiteDirector.py +18 -14
  162. DIRAC/WorkloadManagementSystem/Agent/StalledJobAgent.py +18 -51
  163. DIRAC/WorkloadManagementSystem/Agent/StatesAccountingAgent.py +41 -1
  164. DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_JobAgent.py +45 -4
  165. DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_JobCleaningAgent.py +7 -9
  166. DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_PushJobAgent.py +1 -0
  167. DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_SiteDirector.py +9 -2
  168. DIRAC/WorkloadManagementSystem/Agent/test/Test_Agent_StalledJobAgent.py +4 -5
  169. DIRAC/WorkloadManagementSystem/Client/DownloadInputData.py +9 -9
  170. DIRAC/WorkloadManagementSystem/Client/InputDataResolution.py +6 -6
  171. DIRAC/WorkloadManagementSystem/Client/JobMonitoringClient.py +10 -11
  172. DIRAC/WorkloadManagementSystem/Client/JobReport.py +1 -1
  173. DIRAC/WorkloadManagementSystem/Client/JobState/CachedJobState.py +3 -0
  174. DIRAC/WorkloadManagementSystem/Client/JobState/JobManifest.py +32 -261
  175. DIRAC/WorkloadManagementSystem/Client/JobState/JobState.py +6 -0
  176. DIRAC/WorkloadManagementSystem/Client/JobStateUpdateClient.py +3 -0
  177. DIRAC/WorkloadManagementSystem/Client/JobStatus.py +8 -152
  178. DIRAC/WorkloadManagementSystem/Client/PoolXMLSlice.py +12 -19
  179. DIRAC/WorkloadManagementSystem/Client/SandboxStoreClient.py +25 -38
  180. DIRAC/WorkloadManagementSystem/Client/WMSClient.py +2 -3
  181. DIRAC/WorkloadManagementSystem/Client/test/Test_Client_DownloadInputData.py +29 -0
  182. DIRAC/WorkloadManagementSystem/ConfigTemplate.cfg +4 -8
  183. DIRAC/WorkloadManagementSystem/DB/JobDB.py +89 -132
  184. DIRAC/WorkloadManagementSystem/DB/JobDB.sql +8 -8
  185. DIRAC/WorkloadManagementSystem/DB/JobDBUtils.py +18 -147
  186. DIRAC/WorkloadManagementSystem/DB/JobLoggingDB.py +19 -6
  187. DIRAC/WorkloadManagementSystem/DB/JobParametersDB.py +9 -9
  188. DIRAC/WorkloadManagementSystem/DB/PilotAgentsDB.py +16 -5
  189. DIRAC/WorkloadManagementSystem/DB/PilotAgentsDB.sql +3 -3
  190. DIRAC/WorkloadManagementSystem/DB/SandboxMetadataDB.py +44 -82
  191. DIRAC/WorkloadManagementSystem/DB/StatusUtils.py +125 -0
  192. DIRAC/WorkloadManagementSystem/DB/tests/Test_JobDB.py +1 -1
  193. DIRAC/WorkloadManagementSystem/DB/tests/Test_StatusUtils.py +28 -0
  194. DIRAC/WorkloadManagementSystem/Executor/JobSanity.py +5 -4
  195. DIRAC/WorkloadManagementSystem/Executor/JobScheduling.py +4 -0
  196. DIRAC/WorkloadManagementSystem/FutureClient/JobStateUpdateClient.py +75 -33
  197. DIRAC/WorkloadManagementSystem/JobWrapper/JobWrapper.py +22 -11
  198. DIRAC/WorkloadManagementSystem/JobWrapper/JobWrapperTemplate.py +9 -10
  199. DIRAC/WorkloadManagementSystem/JobWrapper/test/Test_JobWrapper.py +60 -10
  200. DIRAC/WorkloadManagementSystem/JobWrapper/test/Test_JobWrapperTemplate.py +4 -0
  201. DIRAC/WorkloadManagementSystem/Service/JobManagerHandler.py +33 -154
  202. DIRAC/WorkloadManagementSystem/Service/JobMonitoringHandler.py +5 -323
  203. DIRAC/WorkloadManagementSystem/Service/JobStateUpdateHandler.py +0 -16
  204. DIRAC/WorkloadManagementSystem/Service/PilotManagerHandler.py +6 -103
  205. DIRAC/WorkloadManagementSystem/Service/SandboxStoreHandler.py +7 -53
  206. DIRAC/WorkloadManagementSystem/Service/WMSAdministratorHandler.py +16 -79
  207. DIRAC/WorkloadManagementSystem/Service/WMSUtilities.py +4 -18
  208. DIRAC/WorkloadManagementSystem/Utilities/JobModel.py +28 -209
  209. DIRAC/WorkloadManagementSystem/Utilities/JobParameters.py +65 -3
  210. DIRAC/WorkloadManagementSystem/Utilities/JobStatusUtility.py +2 -64
  211. DIRAC/WorkloadManagementSystem/Utilities/ParametricJob.py +7 -171
  212. DIRAC/WorkloadManagementSystem/Utilities/PilotCStoJSONSynchronizer.py +73 -7
  213. DIRAC/WorkloadManagementSystem/Utilities/PilotWrapper.py +41 -11
  214. DIRAC/WorkloadManagementSystem/Utilities/RemoteRunner.py +16 -0
  215. DIRAC/WorkloadManagementSystem/Utilities/Utils.py +36 -1
  216. DIRAC/WorkloadManagementSystem/Utilities/jobAdministration.py +15 -0
  217. DIRAC/WorkloadManagementSystem/Utilities/test/Test_JobModel.py +1 -15
  218. DIRAC/WorkloadManagementSystem/Utilities/test/Test_ParametricJob.py +45 -128
  219. DIRAC/WorkloadManagementSystem/Utilities/test/Test_PilotWrapper.py +16 -0
  220. DIRAC/WorkloadManagementSystem/scripts/dirac_jobexec.py +7 -2
  221. DIRAC/WorkloadManagementSystem/scripts/dirac_wms_pilot_job_info.py +1 -1
  222. DIRAC/__init__.py +62 -60
  223. DIRAC/tests/Utilities/testJobDefinitions.py +22 -28
  224. {DIRAC-9.0.0a42.dist-info → dirac-9.0.7.dist-info}/METADATA +8 -5
  225. {DIRAC-9.0.0a42.dist-info → dirac-9.0.7.dist-info}/RECORD +229 -228
  226. {DIRAC-9.0.0a42.dist-info → dirac-9.0.7.dist-info}/WHEEL +1 -1
  227. {DIRAC-9.0.0a42.dist-info → dirac-9.0.7.dist-info}/entry_points.txt +0 -3
  228. DIRAC/Core/Utilities/test/Test_List.py +0 -150
  229. DIRAC/Core/Utilities/test/Test_Time.py +0 -88
  230. DIRAC/Resources/Computing/PilotBundle.py +0 -70
  231. DIRAC/TransformationSystem/scripts/dirac_transformation_archive.py +0 -30
  232. DIRAC/TransformationSystem/scripts/dirac_transformation_clean.py +0 -30
  233. DIRAC/TransformationSystem/scripts/dirac_transformation_remove_output.py +0 -30
  234. DIRAC/WorkloadManagementSystem/Utilities/test/Test_JobManager.py +0 -58
  235. {DIRAC-9.0.0a42.dist-info → dirac-9.0.7.dist-info/licenses}/LICENSE +0 -0
  236. {DIRAC-9.0.0a42.dist-info → dirac-9.0.7.dist-info}/top_level.txt +0 -0
@@ -16,14 +16,13 @@ def main():
16
16
  Script.registerArgument("prodID: Production ID")
17
17
  _, args = Script.parseCommandLine()
18
18
 
19
+ from DIRAC.MonitoringSystem.Client.WebAppClient import WebAppClient
19
20
  from DIRAC.ProductionSystem.Client.ProductionClient import ProductionClient
20
- from DIRAC.TransformationSystem.Client.TransformationClient import TransformationClient
21
21
 
22
22
  # get arguments
23
23
  prodID = args[0]
24
24
 
25
25
  prodClient = ProductionClient()
26
- transClient = TransformationClient()
27
26
 
28
27
  res = prodClient.getProductionTransformations(prodID)
29
28
  transIDs = []
@@ -70,7 +69,7 @@ def main():
70
69
  ]
71
70
  resList = []
72
71
 
73
- res = transClient.getTransformationSummaryWeb({"TransformationID": transIDs}, [], 0, len(transIDs))
72
+ res = WebAppClient().getTransformationSummaryWeb({"TransformationID": transIDs}, [], 0, len(transIDs))
74
73
 
75
74
  if not res["OK"]:
76
75
  DIRAC.gLogger.error(res["Message"])
@@ -48,13 +48,13 @@ from DIRAC.RequestManagementSystem.private.RequestTask import RequestTask
48
48
  # # agent name
49
49
  AGENT_NAME = "RequestManagement/RequestExecutingAgent"
50
50
  # # requests/cycle
51
- REQUESTSPERCYCLE = 100
51
+ REQUESTSPERCYCLE = 300
52
52
  # # minimal nb of subprocess running
53
- MINPROCESS = 20
53
+ MINPROCESS = 50
54
54
  # # maximal nb of subprocess executed same time
55
- MAXPROCESS = 20
55
+ MAXPROCESS = 50
56
56
  # # ProcessPool queue size
57
- QUEUESIZE = 20
57
+ QUEUESIZE = 100
58
58
  # # file timeout
59
59
  FILETIMEOUT = 300
60
60
  # # operation timeout
@@ -62,7 +62,9 @@ OPERATIONTIMEOUT = 300
62
62
  # # ProcessPool finalization timeout
63
63
  POOLTIMEOUT = 900
64
64
  # # ProcessPool sleep time
65
- POOLSLEEP = 5
65
+ POOLSLEEP = 1
66
+ # # Fetch multiple requests at once from the DB. Otherwise, one by one
67
+ BULKREQUEST = 300
66
68
 
67
69
 
68
70
  class AgentConfigError(Exception):
@@ -108,7 +110,7 @@ class RequestExecutingAgent(AgentModule):
108
110
  self.__poolSleep = POOLSLEEP
109
111
  self.__requestClient = None
110
112
  # Size of the bulk if use of getRequests. If 0, use getRequest
111
- self.__bulkRequest = 0
113
+ self.__bulkRequest = BULKREQUEST
112
114
  self.__rmsMonitoring = False
113
115
 
114
116
  def processPool(self):
@@ -1,17 +1,5 @@
1
- """ :mod: ForwardDISET
2
-
3
- ==================
4
-
5
- .. module: ForwardDISET
6
-
7
- :synopsis: DISET forwarding operation handler
8
-
9
- .. moduleauthor:: Krzysztof.Ciba@NOSPAMgmail.com
10
-
11
- DISET forwarding operation handler
12
- """
13
-
14
1
  import importlib
2
+ from collections.abc import Sequence
15
3
 
16
4
  # imports
17
5
  from DIRAC import S_ERROR, S_OK, gConfig
@@ -65,7 +53,7 @@ class ForwardDISET(OperationHandlerBase):
65
53
  return S_ERROR(str(error))
66
54
 
67
55
  # This is the DISET rpcStub
68
- if isinstance(stub, tuple):
56
+ if isinstance(stub, Sequence):
69
57
  # Ensure the forwarded request is done on behalf of the request owner
70
58
  res = getDNForUsername(self.request.Owner)
71
59
  if not res["OK"]:
@@ -6,25 +6,28 @@
6
6
 
7
7
  """
8
8
 
9
+ import datetime
10
+ import json
9
11
  import os
10
- import time
11
12
  import random
12
- import json
13
- import datetime
13
+ import time
14
+ from functools import cached_property
14
15
 
15
16
  # # from DIRAC
16
- from DIRAC import gLogger, S_OK, S_ERROR
17
- from DIRAC.Core.Utilities.List import randomize, fromChar
18
- from DIRAC.Core.Utilities.JEncode import strToIntDict
19
- from DIRAC.Core.Utilities.DEncode import ignoreEncodeWarning
17
+ from DIRAC import S_ERROR, S_OK, gLogger
20
18
  from DIRAC.ConfigurationSystem.Client import PathFinder
21
19
  from DIRAC.Core.Base.Client import Client, createClient
20
+ from DIRAC.Core.Utilities.DEncode import ignoreEncodeWarning
21
+ from DIRAC.Core.Utilities.JEncode import strToIntDict
22
+ from DIRAC.Core.Utilities.List import fromChar, randomize
23
+ from DIRAC.Core.Utilities.ObjectLoader import ObjectLoader
24
+ from DIRAC.Core.Utilities.ReturnValues import returnValueOrRaise
22
25
  from DIRAC.RequestManagementSystem.Client.Request import Request
23
26
  from DIRAC.RequestManagementSystem.private.RequestValidator import RequestValidator
24
- from DIRAC.WorkloadManagementSystem.Client import JobStatus
25
- from DIRAC.WorkloadManagementSystem.Client import JobMinorStatus
26
- from DIRAC.WorkloadManagementSystem.Client.JobStateUpdateClient import JobStateUpdateClient
27
+ from DIRAC.WorkloadManagementSystem.Client import JobMinorStatus, JobStatus
27
28
  from DIRAC.WorkloadManagementSystem.Client.JobMonitoringClient import JobMonitoringClient
29
+ from DIRAC.WorkloadManagementSystem.Client.JobStateUpdateClient import JobStateUpdateClient
30
+ from DIRAC.WorkloadManagementSystem.Utilities.JobStatusUtility import JobStatusUtility
28
31
 
29
32
 
30
33
  @createClient("RequestManagement/ReqManager")
@@ -309,8 +312,7 @@ class ReqClient(Client):
309
312
  :param str requestID: request id
310
313
  :param int jobID: job id
311
314
  """
312
-
313
- stateServer = JobStateUpdateClient(useCertificates=useCertificates)
315
+ stateServer = _JobDBInteraction(useCertificates)
314
316
 
315
317
  # Checking if to update the job status - we should fail here, so it will be re-tried later
316
318
  # Checking the state, first
@@ -632,8 +634,10 @@ def printOperation(indexOperation, verbose=True, onlyFailed=False):
632
634
  output = ""
633
635
  prettyPrint(decode, offset=10)
634
636
  prStr += "\n Arguments:\n" + output.strip("\n")
635
- else:
637
+ elif isinstance(decode, list):
636
638
  prStr += f"\n Service: {decode[0][0]}"
639
+ else:
640
+ prStr += f"\n Command: {decode['dCls']}.{decode['dMeth']}(*{decode['args']!r})"
637
641
  gLogger.always(
638
642
  " [%s] Operation Type='%s' ID=%s Order=%s Status='%s'%s%s"
639
643
  % (
@@ -688,3 +692,52 @@ def recoverableRequest(request):
688
692
  return False
689
693
  return True
690
694
  return True
695
+
696
+
697
+ class _JobDBInteraction:
698
+ """Class to handle the JobDB interaction.
699
+
700
+ This will either connect to the DB directly or use the client depending on
701
+ if use_certificates is set or not.
702
+
703
+ WARNING: This is not intended for use outside of ReqClient!
704
+ """
705
+
706
+ def __init__(self, useCertificates: bool):
707
+ self._useCertificates = useCertificates
708
+
709
+ def setJobParameter(self, jobID: int, key: str, value: str):
710
+ if self._useCertificates:
711
+ vo = returnValueOrRaise(self._jobStatusUtility.jobDB.getJobAttribute(jobID, "VO"))
712
+ return self._elasticJobParametersDB.setJobParameter(int(jobID), key, value, vo=vo)
713
+ else:
714
+ return self._client.setJobParameter(jobID, key, value)
715
+
716
+ def setJobStatus(self, jobID: int, newStatus: str, minorStatus: str, source: str):
717
+ if self._useCertificates:
718
+ return self._jobStatusUtility.setJobStatus(
719
+ int(jobID), status=newStatus, minorStatus=minorStatus, source=source
720
+ )
721
+ else:
722
+ return self._client.setJobStatus(jobID, newStatus, minorStatus, source)
723
+
724
+ def setJobApplicationStatus(self, jobID: int, appStatus: str, source: str):
725
+ if self._useCertificates:
726
+ return self._jobStatusUtility.setJobStatus(int(jobID), appStatus=appStatus, source=source)
727
+ else:
728
+ return self._client.setJobApplicationStatus(jobID, appStatus, source)
729
+
730
+ @cached_property
731
+ def _client(self):
732
+ return JobStateUpdateClient(useCertificates=False)
733
+
734
+ @cached_property
735
+ def _jobStatusUtility(self):
736
+ return JobStatusUtility()
737
+
738
+ @cached_property
739
+ def _elasticJobParametersDB(self):
740
+ result = ObjectLoader().loadObject("WorkloadManagementSystem.DB.JobParametersDB", "JobParametersDB")
741
+ if not result["OK"]:
742
+ return result
743
+ return result["Value"]()
@@ -44,19 +44,19 @@ Agents
44
44
  {
45
45
  PollingTime = 60
46
46
  # number of Requests to execute per cycle
47
- RequestsPerCycle = 100
47
+ RequestsPerCycle = 300
48
48
  # minimum number of workers process in the ProcessPool
49
- MinProcess = 20
49
+ MinProcess = 50
50
50
  # maximum number of workers process in the ProcessPool; recommended to set it to the same value as MinProcess
51
- MaxProcess = 20
51
+ MaxProcess = 50
52
52
  # queue depth of the ProcessPool
53
- ProcessPoolQueueSize = 20
53
+ ProcessPoolQueueSize = 100
54
54
  # timeout for the ProcessPool finalization
55
55
  ProcessPoolTimeout = 900
56
56
  # sleep time before retrying to get a free slot in the ProcessPool
57
- ProcessPoolSleep = 5
57
+ ProcessPoolSleep = 1
58
58
  # If a positive integer n is given, we fetch n requests at once from the DB. Otherwise, one by one
59
- BulkRequest = 0
59
+ BulkRequest = 300
60
60
  OperationHandlers
61
61
  {
62
62
  ForwardDISET
@@ -16,6 +16,8 @@ import datetime
16
16
  import errno
17
17
  import random
18
18
 
19
+ from urllib.parse import quote_plus
20
+
19
21
  from sqlalchemy import (
20
22
  TEXT,
21
23
  BigInteger,
@@ -198,7 +200,7 @@ class RequestDB:
198
200
  self.dbHost = dbParameters["Host"]
199
201
  self.dbPort = dbParameters["Port"]
200
202
  self.dbUser = dbParameters["User"]
201
- self.dbPass = dbParameters["Password"]
203
+ self.dbPass = quote_plus(dbParameters["Password"])
202
204
  self.dbName = dbParameters["DBName"]
203
205
 
204
206
  def __init__(self, parentLogger=None):
@@ -435,10 +437,13 @@ class RequestDB:
435
437
  # FIXME: code for backward compatibility
436
438
  if not request.Owner:
437
439
  # We go under the assumption that in this case OwnerDN exists
438
- res = getDNForUsername(request.OwnerDN)
439
- if not res["OK"]:
440
- return res
441
- request.Owner = res["Value"][0]
440
+ if request.OwnerDN:
441
+ res = getDNForUsername(request.OwnerDN)
442
+ if not res["OK"]:
443
+ return res
444
+ request.Owner = res["Value"][0]
445
+ else:
446
+ request.Owner = "Unknown"
442
447
  # ##
443
448
 
444
449
  return S_OK(request)
@@ -6,6 +6,7 @@ integration tests (Test_ReqDB.py)
6
6
  # pylint: disable=invalid-name,wrong-import-position
7
7
  import time
8
8
 
9
+ import pytest
9
10
 
10
11
  from DIRAC.RequestManagementSystem.Client.Request import Request
11
12
  from DIRAC.RequestManagementSystem.Client.Operation import Operation
@@ -42,6 +43,7 @@ def test_stress(reqDB):
42
43
  assert delete["OK"], delete
43
44
 
44
45
 
46
+ @pytest.mark.slow
45
47
  def test_stressBulk(reqDB):
46
48
  """stress test bulk"""
47
49
 
@@ -1,49 +1,49 @@
1
- """ :mod: RequestValidator
1
+ """:mod: RequestValidator
2
2
 
3
- ======================
3
+ ======================
4
4
 
5
- .. module: RequestValidator
5
+ .. module: RequestValidator
6
6
 
7
- :synopsis: request validator
7
+ :synopsis: request validator
8
8
 
9
- .. moduleauthor:: Krzysztof.Ciba@NOSPAMgmail.com
9
+ .. moduleauthor:: Krzysztof.Ciba@NOSPAMgmail.com
10
10
 
11
- A general and simple request validator checking for required attributes and logic.
12
- It checks if required attributes are set/unset but not for their values.
11
+ A general and simple request validator checking for required attributes and logic.
12
+ It checks if required attributes are set/unset but not for their values.
13
13
 
14
- RequestValidator class implements the DIRACSingleton pattern, no global object is
15
- required to keep a single instance.
14
+ RequestValidator class implements the DIRACSingleton pattern, no global object is
15
+ required to keep a single instance.
16
16
 
17
- If you need to extend this one with your own specific checks consider:
17
+ If you need to extend this one with your own specific checks consider:
18
18
 
19
- * for adding Operation or Files required attributes use :any:`addReqAttrsCheck` function::
19
+ * for adding Operation or Files required attributes use :any:`addReqAttrsCheck` function::
20
20
 
21
- RequestValidator().addReqAttrsCheck( "FooOperation", operationAttrs = [ "Bar", "Buzz"], filesAttrs = [ "LFN" ] )
21
+ RequestValidator().addReqAttrsCheck( "FooOperation", operationAttrs = [ "Bar", "Buzz"], filesAttrs = [ "LFN" ] )
22
22
 
23
- * for adding generic check define a new callable object ( function or functor ) which takes only one argument,
24
- say for functor::
23
+ * for adding generic check define a new callable object ( function or functor ) which takes only one argument,
24
+ say for functor::
25
25
 
26
- class MyValidator( RequestValidator ):
26
+ class MyValidator( RequestValidator ):
27
27
 
28
- @staticmethod
29
- def hasFoo( request ):
30
- if not request.Foo:
31
- return S_ERROR("Foo not set")
32
- return S_OK()
28
+ @staticmethod
29
+ def hasFoo( request ):
30
+ if not request.Foo:
31
+ return S_ERROR("Foo not set")
32
+ return S_OK()
33
33
 
34
- * or function::
34
+ * or function::
35
35
 
36
- def hasBar( request ):
37
- if not request.Bar:
38
- return S_ERROR("Bar not set")
39
- return S_OK()
36
+ def hasBar( request ):
37
+ if not request.Bar:
38
+ return S_ERROR("Bar not set")
39
+ return S_OK()
40
40
 
41
- and add this one to the validators set by calling `RequestValidator().addValidator`, i.e.::
41
+ and add this one to the validators set by calling `RequestValidator().addValidator`, i.e.::
42
42
 
43
- RequestValidator().addValidator( MyValidator.hasFoo )
44
- RequestValidator().addValidator( hasFoo )
43
+ RequestValidator().addValidator( MyValidator.hasFoo )
44
+ RequestValidator().addValidator( hasFoo )
45
45
 
46
- Notice that all validators should always return S_ERROR/S_OK, no exceptions from that whatsoever!
46
+ Notice that all validators should always return S_ERROR/S_OK, no exceptions from that whatsoever!
47
47
  """
48
48
 
49
49
  import inspect
@@ -53,6 +53,7 @@ from DIRAC import S_OK, S_ERROR, gConfig, gLogger
53
53
  from DIRAC.Core.Security.Properties import FULL_DELEGATION, LIMITED_DELEGATION
54
54
  from DIRAC.Core.Utilities.DIRACSingleton import DIRACSingleton
55
55
  from DIRAC.ConfigurationSystem.Client import PathFinder
56
+ from DIRAC.ConfigurationSystem.Client.Helpers.Registry import getUsernameForDN
56
57
 
57
58
 
58
59
  class RequestValidator(metaclass=DIRACSingleton):
@@ -268,28 +269,21 @@ class RequestValidator(metaclass=DIRACSingleton):
268
269
 
269
270
  :returns: True if everything is fine, False otherwise
270
271
  """
271
-
272
272
  credUserName = remoteCredentials["username"]
273
273
  credGroup = remoteCredentials["group"]
274
274
  credProperties = remoteCredentials["properties"]
275
- ownershipCheck = None
276
-
277
- # FIXME: code for backward compatibility with requests created by 8.0 clients
278
- # The below can be clearly simplified, leaving the extended checks for clarity
279
- if hasattr(request, "OwnerDN") and not hasattr(
280
- request, "Owner"
281
- ): # Requests created by v8.0 client for v8.0 servers
282
- ownershipCheck = request.OwnerDN
283
- if not hasattr(request, "OwnerDN") and hasattr(
284
- request, "Owner"
285
- ): # Requests created by v9 client for v9 servers
286
- ownershipCheck = request.Owner
287
- if hasattr(request, "OwnerDN") and hasattr(request, "Owner"): # Requests created by v8.0 client for v9 servers
288
- ownershipCheck = request.Owner
289
- # ##
275
+
276
+ # In case we have an old style request with only a DN and no Owner,
277
+ # get the Owner from the DN.
278
+ if getattr(request, "OwnerDN", None) and not getattr(request, "Owner", None):
279
+ res = getUsernameForDN(request.OwnerDN)
280
+ if not res["OK"]:
281
+ gLogger.error("Cannot Validate request", res)
282
+ return False
283
+ request.Owner = res["Value"]
290
284
 
291
285
  # If the owner or the group was not set, we use the one of the credentials
292
- if not ownershipCheck or not request.OwnerGroup:
286
+ if not request.Owner or not request.OwnerGroup:
293
287
  request.Owner = credUserName
294
288
  request.OwnerGroup = credGroup
295
289
  return True
@@ -1,4 +1,4 @@
1
- """ SiteStatus helper
1
+ """SiteStatus helper
2
2
 
3
3
  Module that acts as a helper for knowing the status of a site.
4
4
  It takes care of switching between the CS and the RSS.
@@ -195,7 +195,7 @@ class SiteStatus(metaclass=DIRACSingleton):
195
195
 
196
196
  return S_OK(siteList)
197
197
 
198
- def setSiteStatus(self, site, status, comment="No comment"):
198
+ def setSiteStatus(self, site, status, comment="No comment", expiry=None):
199
199
  """
200
200
  Set the status of a site in the 'SiteStatus' table of RSS
201
201
 
@@ -231,6 +231,8 @@ class SiteStatus(metaclass=DIRACSingleton):
231
231
  return S_ERROR(f"Unable to get user proxy info {result['Message']} ")
232
232
 
233
233
  tokenExpiration = datetime.utcnow() + timedelta(days=1)
234
+ if expiry:
235
+ tokenExpiration = expiry
234
236
 
235
237
  self.rssCache.acquireLock()
236
238
  try:
@@ -121,7 +121,9 @@ class FreeDiskSpaceCommand(Command):
121
121
  "Site": siteRes["Value"] if siteRes["Value"] else "unassigned",
122
122
  }
123
123
 
124
- results["Used"] = results["Total"] - results["Free"]
124
+ # There are sometimes small discrepencies which can lead to negative
125
+ # used values.
126
+ results["Used"] = max(0, results["Total"] - results["Free"])
125
127
 
126
128
  for sType in ["Total", "Free", "Used"]:
127
129
  spaceTokenAccounting = StorageOccupancy()
@@ -45,7 +45,7 @@ class AccountingCache(rmsBase):
45
45
  """AccountingCache table"""
46
46
 
47
47
  __tablename__ = "AccountingCache"
48
- __table_args__ = {"mysql_engine": "InnoDB", "mysql_charset": "utf8"}
48
+ __table_args__ = {"mysql_engine": "InnoDB", "mysql_charset": "utf8mb4"}
49
49
 
50
50
  name = Column("Name", String(64), nullable=False, primary_key=True)
51
51
  plotname = Column("PlotName", String(64), nullable=False, primary_key=True)
@@ -88,7 +88,7 @@ class DowntimeCache(rmsBase):
88
88
  """DowntimeCache table"""
89
89
 
90
90
  __tablename__ = "DowntimeCache"
91
- __table_args__ = {"mysql_engine": "InnoDB", "mysql_charset": "utf8"}
91
+ __table_args__ = {"mysql_engine": "InnoDB", "mysql_charset": "utf8mb4"}
92
92
 
93
93
  downtimeid = Column("DowntimeID", String(127), nullable=False, primary_key=True)
94
94
  name = Column("Name", String(64), nullable=False)
@@ -150,7 +150,7 @@ class GGUSTicketsCache(rmsBase):
150
150
  """GGUSTicketsCache table"""
151
151
 
152
152
  __tablename__ = "GGUSTicketsCache"
153
- __table_args__ = {"mysql_engine": "InnoDB", "mysql_charset": "utf8"}
153
+ __table_args__ = {"mysql_engine": "InnoDB", "mysql_charset": "utf8mb4"}
154
154
 
155
155
  gocsite = Column("GocSite", String(64), nullable=False, primary_key=True)
156
156
  tickets = Column("Tickets", String(1024), nullable=False)
@@ -186,7 +186,7 @@ class JobCache(rmsBase):
186
186
  """JobCache table"""
187
187
 
188
188
  __tablename__ = "JobCache"
189
- __table_args__ = {"mysql_engine": "InnoDB", "mysql_charset": "utf8"}
189
+ __table_args__ = {"mysql_engine": "InnoDB", "mysql_charset": "utf8mb4"}
190
190
 
191
191
  site = Column("Site", String(64), nullable=False, primary_key=True)
192
192
  status = Column("Status", String(16), nullable=False)
@@ -219,7 +219,7 @@ class PilotCache(rmsBase):
219
219
  """PilotCache table"""
220
220
 
221
221
  __tablename__ = "PilotCache"
222
- __table_args__ = {"mysql_engine": "InnoDB", "mysql_charset": "utf8"}
222
+ __table_args__ = {"mysql_engine": "InnoDB", "mysql_charset": "utf8mb4"}
223
223
 
224
224
  site = Column("Site", String(64), nullable=False, primary_key=True)
225
225
  ce = Column("CE", String(64), nullable=False, primary_key=True)
@@ -261,7 +261,7 @@ class PolicyResult(rmsBase):
261
261
  """PolicyResult table"""
262
262
 
263
263
  __tablename__ = "PolicyResult"
264
- __table_args__ = {"mysql_engine": "InnoDB", "mysql_charset": "utf8"}
264
+ __table_args__ = {"mysql_engine": "InnoDB", "mysql_charset": "utf8mb4"}
265
265
 
266
266
  policyname = Column("PolicyName", String(64), nullable=False, primary_key=True)
267
267
  statustype = Column("StatusType", String(16), nullable=False, server_default="", primary_key=True)
@@ -320,7 +320,7 @@ class SpaceTokenOccupancyCache(rmsBase):
320
320
  """SpaceTokenOccupancyCache table"""
321
321
 
322
322
  __tablename__ = "SpaceTokenOccupancyCache"
323
- __table_args__ = {"mysql_engine": "InnoDB", "mysql_charset": "utf8"}
323
+ __table_args__ = {"mysql_engine": "InnoDB", "mysql_charset": "utf8mb4"}
324
324
 
325
325
  endpoint = Column("Endpoint", String(128), nullable=False, primary_key=True)
326
326
  token = Column("Token", String(64), nullable=False, primary_key=True)
@@ -358,7 +358,7 @@ class TransferCache(rmsBase):
358
358
  """TransferCache table"""
359
359
 
360
360
  __tablename__ = "TransferCache"
361
- __table_args__ = {"mysql_engine": "InnoDB", "mysql_charset": "utf8"}
361
+ __table_args__ = {"mysql_engine": "InnoDB", "mysql_charset": "utf8mb4"}
362
362
 
363
363
  sourcename = Column("SourceName", String(64), nullable=False, primary_key=True)
364
364
  destinationname = Column("DestinationName", String(64), nullable=False, primary_key=True)
@@ -50,7 +50,7 @@ class ResourceStatusCache(rssBase):
50
50
  """
51
51
 
52
52
  __tablename__ = "ResourceStatusCache"
53
- __table_args__ = {"mysql_engine": "InnoDB", "mysql_charset": "utf8"}
53
+ __table_args__ = {"mysql_engine": "InnoDB", "mysql_charset": "utf8mb4"}
54
54
 
55
55
  id = Column("ID", BigInteger, nullable=False, autoincrement=True, primary_key=True)
56
56
  sitename = Column("SiteName", String(64), nullable=False)
@@ -89,7 +89,7 @@ class ElementStatusBase:
89
89
  Prototype for tables.
90
90
  """
91
91
 
92
- __table_args__ = {"mysql_engine": "InnoDB", "mysql_charset": "utf8"}
92
+ __table_args__ = {"mysql_engine": "InnoDB", "mysql_charset": "utf8mb4"}
93
93
 
94
94
  name = Column("Name", String(64), nullable=False, primary_key=True)
95
95
  statustype = Column("StatusType", String(128), nullable=False, server_default="all", primary_key=True)
@@ -3,11 +3,10 @@ Module containing functions interacting with the CS and useful for the RSS
3
3
  modules.
4
4
  """
5
5
 
6
- from DIRAC import gConfig, gLogger, S_OK
6
+ from DIRAC import S_OK, gConfig, gLogger
7
+ from DIRAC.ConfigurationSystem.Client.Helpers.Resources import getQueues
7
8
  from DIRAC.Core.Utilities.SiteSEMapping import getSEParameters
8
- from DIRAC.ConfigurationSystem.Client.Helpers.Resources import getQueues, getCESiteMapping
9
9
  from DIRAC.DataManagementSystem.Utilities.DMSHelpers import DMSHelpers
10
- from DIRAC.ResourceStatusSystem.Utilities import Utils
11
10
 
12
11
 
13
12
  def warmUp():
@@ -19,28 +18,6 @@ def warmUp():
19
18
  gRefresher.refreshConfigurationIfNeeded()
20
19
 
21
20
 
22
- def getResources():
23
- """
24
- Gets all resources
25
- """
26
-
27
- resources = DMSHelpers().getStorageElements()
28
-
29
- fts = getFTS()
30
- if fts["OK"]:
31
- resources = resources + fts["Value"]
32
-
33
- fc = getFileCatalogs()
34
- if fc["OK"]:
35
- resources = resources + fc["Value"]
36
-
37
- res = getCESiteMapping()
38
- if res["OK"]:
39
- resources = resources + list(res["Value"])
40
-
41
- return S_OK(resources)
42
-
43
-
44
21
  def getStorageElementEndpoint(seName):
45
22
  """Get endpoints of a StorageElement
46
23
 
@@ -86,12 +63,6 @@ def getFTS():
86
63
  return S_OK([])
87
64
 
88
65
 
89
- def getSpaceTokenEndpoints():
90
- """Get Space Token Endpoints"""
91
-
92
- return Utils.getCSTree("Shares/Disk")
93
-
94
-
95
66
  def getFileCatalogs():
96
67
  """
97
68
  Gets all storage elements from /Resources/FileCatalogs