wmglobalqueue 2.4.5.1__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 (347) hide show
  1. Utils/CPMetrics.py +270 -0
  2. Utils/CertTools.py +100 -0
  3. Utils/EmailAlert.py +50 -0
  4. Utils/ExtendedUnitTestCase.py +62 -0
  5. Utils/FileTools.py +182 -0
  6. Utils/IteratorTools.py +80 -0
  7. Utils/MathUtils.py +31 -0
  8. Utils/MemoryCache.py +119 -0
  9. Utils/Patterns.py +24 -0
  10. Utils/Pipeline.py +137 -0
  11. Utils/PortForward.py +97 -0
  12. Utils/ProcFS.py +112 -0
  13. Utils/ProcessStats.py +194 -0
  14. Utils/PythonVersion.py +17 -0
  15. Utils/Signals.py +36 -0
  16. Utils/TemporaryEnvironment.py +27 -0
  17. Utils/Throttled.py +227 -0
  18. Utils/Timers.py +130 -0
  19. Utils/Timestamps.py +86 -0
  20. Utils/TokenManager.py +143 -0
  21. Utils/Tracing.py +60 -0
  22. Utils/TwPrint.py +98 -0
  23. Utils/Utilities.py +318 -0
  24. Utils/__init__.py +11 -0
  25. Utils/wmcoreDTools.py +707 -0
  26. WMCore/ACDC/Collection.py +57 -0
  27. WMCore/ACDC/CollectionTypes.py +12 -0
  28. WMCore/ACDC/CouchCollection.py +67 -0
  29. WMCore/ACDC/CouchFileset.py +238 -0
  30. WMCore/ACDC/CouchService.py +73 -0
  31. WMCore/ACDC/DataCollectionService.py +485 -0
  32. WMCore/ACDC/Fileset.py +94 -0
  33. WMCore/ACDC/__init__.py +11 -0
  34. WMCore/Algorithms/Alarm.py +39 -0
  35. WMCore/Algorithms/MathAlgos.py +274 -0
  36. WMCore/Algorithms/MiscAlgos.py +67 -0
  37. WMCore/Algorithms/ParseXMLFile.py +115 -0
  38. WMCore/Algorithms/Permissions.py +27 -0
  39. WMCore/Algorithms/Singleton.py +58 -0
  40. WMCore/Algorithms/SubprocessAlgos.py +129 -0
  41. WMCore/Algorithms/__init__.py +7 -0
  42. WMCore/Cache/GenericDataCache.py +98 -0
  43. WMCore/Cache/WMConfigCache.py +572 -0
  44. WMCore/Cache/__init__.py +0 -0
  45. WMCore/Configuration.py +659 -0
  46. WMCore/DAOFactory.py +47 -0
  47. WMCore/DataStructs/File.py +177 -0
  48. WMCore/DataStructs/Fileset.py +140 -0
  49. WMCore/DataStructs/Job.py +182 -0
  50. WMCore/DataStructs/JobGroup.py +142 -0
  51. WMCore/DataStructs/JobPackage.py +49 -0
  52. WMCore/DataStructs/LumiList.py +734 -0
  53. WMCore/DataStructs/Mask.py +219 -0
  54. WMCore/DataStructs/MathStructs/ContinuousSummaryHistogram.py +197 -0
  55. WMCore/DataStructs/MathStructs/DiscreteSummaryHistogram.py +92 -0
  56. WMCore/DataStructs/MathStructs/SummaryHistogram.py +117 -0
  57. WMCore/DataStructs/MathStructs/__init__.py +0 -0
  58. WMCore/DataStructs/Pickleable.py +24 -0
  59. WMCore/DataStructs/Run.py +256 -0
  60. WMCore/DataStructs/Subscription.py +175 -0
  61. WMCore/DataStructs/WMObject.py +47 -0
  62. WMCore/DataStructs/WorkUnit.py +112 -0
  63. WMCore/DataStructs/Workflow.py +60 -0
  64. WMCore/DataStructs/__init__.py +8 -0
  65. WMCore/Database/CMSCouch.py +1430 -0
  66. WMCore/Database/ConfigDBMap.py +29 -0
  67. WMCore/Database/CouchMonitoring.py +450 -0
  68. WMCore/Database/CouchUtils.py +118 -0
  69. WMCore/Database/DBCore.py +198 -0
  70. WMCore/Database/DBCreator.py +113 -0
  71. WMCore/Database/DBExceptionHandler.py +59 -0
  72. WMCore/Database/DBFactory.py +117 -0
  73. WMCore/Database/DBFormatter.py +177 -0
  74. WMCore/Database/Dialects.py +13 -0
  75. WMCore/Database/ExecuteDAO.py +327 -0
  76. WMCore/Database/MongoDB.py +241 -0
  77. WMCore/Database/MySQL/Destroy.py +42 -0
  78. WMCore/Database/MySQL/ListUserContent.py +20 -0
  79. WMCore/Database/MySQL/__init__.py +9 -0
  80. WMCore/Database/MySQLCore.py +132 -0
  81. WMCore/Database/Oracle/Destroy.py +56 -0
  82. WMCore/Database/Oracle/ListUserContent.py +19 -0
  83. WMCore/Database/Oracle/__init__.py +9 -0
  84. WMCore/Database/ResultSet.py +44 -0
  85. WMCore/Database/Transaction.py +91 -0
  86. WMCore/Database/__init__.py +9 -0
  87. WMCore/Database/ipy_profile_couch.py +438 -0
  88. WMCore/GlobalWorkQueue/CherryPyThreads/CleanUpTask.py +29 -0
  89. WMCore/GlobalWorkQueue/CherryPyThreads/HeartbeatMonitor.py +105 -0
  90. WMCore/GlobalWorkQueue/CherryPyThreads/LocationUpdateTask.py +28 -0
  91. WMCore/GlobalWorkQueue/CherryPyThreads/ReqMgrInteractionTask.py +35 -0
  92. WMCore/GlobalWorkQueue/CherryPyThreads/__init__.py +0 -0
  93. WMCore/GlobalWorkQueue/__init__.py +0 -0
  94. WMCore/GroupUser/CouchObject.py +127 -0
  95. WMCore/GroupUser/Decorators.py +51 -0
  96. WMCore/GroupUser/Group.py +33 -0
  97. WMCore/GroupUser/Interface.py +73 -0
  98. WMCore/GroupUser/User.py +96 -0
  99. WMCore/GroupUser/__init__.py +11 -0
  100. WMCore/Lexicon.py +836 -0
  101. WMCore/REST/Auth.py +202 -0
  102. WMCore/REST/CherryPyPeriodicTask.py +166 -0
  103. WMCore/REST/Error.py +333 -0
  104. WMCore/REST/Format.py +642 -0
  105. WMCore/REST/HeartbeatMonitorBase.py +90 -0
  106. WMCore/REST/Main.py +636 -0
  107. WMCore/REST/Server.py +2435 -0
  108. WMCore/REST/Services.py +24 -0
  109. WMCore/REST/Test.py +120 -0
  110. WMCore/REST/Tools.py +38 -0
  111. WMCore/REST/Validation.py +250 -0
  112. WMCore/REST/__init__.py +1 -0
  113. WMCore/ReqMgr/DataStructs/RequestStatus.py +209 -0
  114. WMCore/ReqMgr/DataStructs/RequestType.py +13 -0
  115. WMCore/ReqMgr/DataStructs/__init__.py +0 -0
  116. WMCore/ReqMgr/__init__.py +1 -0
  117. WMCore/Services/AlertManager/AlertManagerAPI.py +111 -0
  118. WMCore/Services/AlertManager/__init__.py +0 -0
  119. WMCore/Services/CRIC/CRIC.py +238 -0
  120. WMCore/Services/CRIC/__init__.py +0 -0
  121. WMCore/Services/DBS/DBS3Reader.py +1044 -0
  122. WMCore/Services/DBS/DBSConcurrency.py +44 -0
  123. WMCore/Services/DBS/DBSErrors.py +112 -0
  124. WMCore/Services/DBS/DBSReader.py +23 -0
  125. WMCore/Services/DBS/DBSUtils.py +166 -0
  126. WMCore/Services/DBS/DBSWriterObjects.py +381 -0
  127. WMCore/Services/DBS/ProdException.py +133 -0
  128. WMCore/Services/DBS/__init__.py +8 -0
  129. WMCore/Services/FWJRDB/FWJRDBAPI.py +118 -0
  130. WMCore/Services/FWJRDB/__init__.py +0 -0
  131. WMCore/Services/HTTPS/HTTPSAuthHandler.py +66 -0
  132. WMCore/Services/HTTPS/__init__.py +0 -0
  133. WMCore/Services/LogDB/LogDB.py +201 -0
  134. WMCore/Services/LogDB/LogDBBackend.py +191 -0
  135. WMCore/Services/LogDB/LogDBExceptions.py +11 -0
  136. WMCore/Services/LogDB/LogDBReport.py +85 -0
  137. WMCore/Services/LogDB/__init__.py +0 -0
  138. WMCore/Services/MSPileup/__init__.py +0 -0
  139. WMCore/Services/MSUtils/MSUtils.py +54 -0
  140. WMCore/Services/MSUtils/__init__.py +0 -0
  141. WMCore/Services/McM/McM.py +173 -0
  142. WMCore/Services/McM/__init__.py +8 -0
  143. WMCore/Services/MonIT/Grafana.py +133 -0
  144. WMCore/Services/MonIT/__init__.py +0 -0
  145. WMCore/Services/PyCondor/PyCondorAPI.py +154 -0
  146. WMCore/Services/PyCondor/__init__.py +0 -0
  147. WMCore/Services/ReqMgr/ReqMgr.py +261 -0
  148. WMCore/Services/ReqMgr/__init__.py +0 -0
  149. WMCore/Services/ReqMgrAux/ReqMgrAux.py +419 -0
  150. WMCore/Services/ReqMgrAux/__init__.py +0 -0
  151. WMCore/Services/RequestDB/RequestDBReader.py +267 -0
  152. WMCore/Services/RequestDB/RequestDBWriter.py +39 -0
  153. WMCore/Services/RequestDB/__init__.py +0 -0
  154. WMCore/Services/Requests.py +624 -0
  155. WMCore/Services/Rucio/Rucio.py +1290 -0
  156. WMCore/Services/Rucio/RucioUtils.py +74 -0
  157. WMCore/Services/Rucio/__init__.py +0 -0
  158. WMCore/Services/RucioConMon/RucioConMon.py +121 -0
  159. WMCore/Services/RucioConMon/__init__.py +0 -0
  160. WMCore/Services/Service.py +400 -0
  161. WMCore/Services/StompAMQ/__init__.py +0 -0
  162. WMCore/Services/TagCollector/TagCollector.py +155 -0
  163. WMCore/Services/TagCollector/XMLUtils.py +98 -0
  164. WMCore/Services/TagCollector/__init__.py +0 -0
  165. WMCore/Services/UUIDLib.py +13 -0
  166. WMCore/Services/UserFileCache/UserFileCache.py +160 -0
  167. WMCore/Services/UserFileCache/__init__.py +8 -0
  168. WMCore/Services/WMAgent/WMAgent.py +63 -0
  169. WMCore/Services/WMAgent/__init__.py +0 -0
  170. WMCore/Services/WMArchive/CMSSWMetrics.py +526 -0
  171. WMCore/Services/WMArchive/DataMap.py +463 -0
  172. WMCore/Services/WMArchive/WMArchive.py +33 -0
  173. WMCore/Services/WMArchive/__init__.py +0 -0
  174. WMCore/Services/WMBS/WMBS.py +97 -0
  175. WMCore/Services/WMBS/__init__.py +0 -0
  176. WMCore/Services/WMStats/DataStruct/RequestInfoCollection.py +300 -0
  177. WMCore/Services/WMStats/DataStruct/__init__.py +0 -0
  178. WMCore/Services/WMStats/WMStatsPycurl.py +145 -0
  179. WMCore/Services/WMStats/WMStatsReader.py +445 -0
  180. WMCore/Services/WMStats/WMStatsWriter.py +273 -0
  181. WMCore/Services/WMStats/__init__.py +0 -0
  182. WMCore/Services/WMStatsServer/WMStatsServer.py +134 -0
  183. WMCore/Services/WMStatsServer/__init__.py +0 -0
  184. WMCore/Services/WorkQueue/WorkQueue.py +492 -0
  185. WMCore/Services/WorkQueue/__init__.py +0 -0
  186. WMCore/Services/__init__.py +8 -0
  187. WMCore/Services/pycurl_manager.py +574 -0
  188. WMCore/WMBase.py +50 -0
  189. WMCore/WMConnectionBase.py +164 -0
  190. WMCore/WMException.py +183 -0
  191. WMCore/WMExceptions.py +269 -0
  192. WMCore/WMFactory.py +76 -0
  193. WMCore/WMInit.py +377 -0
  194. WMCore/WMLogging.py +104 -0
  195. WMCore/WMSpec/ConfigSectionTree.py +442 -0
  196. WMCore/WMSpec/Persistency.py +135 -0
  197. WMCore/WMSpec/Steps/BuildMaster.py +87 -0
  198. WMCore/WMSpec/Steps/BuildTools.py +201 -0
  199. WMCore/WMSpec/Steps/Builder.py +97 -0
  200. WMCore/WMSpec/Steps/Diagnostic.py +89 -0
  201. WMCore/WMSpec/Steps/Emulator.py +62 -0
  202. WMCore/WMSpec/Steps/ExecuteMaster.py +208 -0
  203. WMCore/WMSpec/Steps/Executor.py +210 -0
  204. WMCore/WMSpec/Steps/StepFactory.py +213 -0
  205. WMCore/WMSpec/Steps/TaskEmulator.py +75 -0
  206. WMCore/WMSpec/Steps/Template.py +204 -0
  207. WMCore/WMSpec/Steps/Templates/AlcaHarvest.py +76 -0
  208. WMCore/WMSpec/Steps/Templates/CMSSW.py +613 -0
  209. WMCore/WMSpec/Steps/Templates/DQMUpload.py +59 -0
  210. WMCore/WMSpec/Steps/Templates/DeleteFiles.py +70 -0
  211. WMCore/WMSpec/Steps/Templates/LogArchive.py +84 -0
  212. WMCore/WMSpec/Steps/Templates/LogCollect.py +105 -0
  213. WMCore/WMSpec/Steps/Templates/StageOut.py +105 -0
  214. WMCore/WMSpec/Steps/Templates/__init__.py +10 -0
  215. WMCore/WMSpec/Steps/WMExecutionFailure.py +21 -0
  216. WMCore/WMSpec/Steps/__init__.py +8 -0
  217. WMCore/WMSpec/Utilities.py +63 -0
  218. WMCore/WMSpec/WMSpecErrors.py +12 -0
  219. WMCore/WMSpec/WMStep.py +347 -0
  220. WMCore/WMSpec/WMTask.py +1997 -0
  221. WMCore/WMSpec/WMWorkload.py +2288 -0
  222. WMCore/WMSpec/WMWorkloadTools.py +382 -0
  223. WMCore/WMSpec/__init__.py +9 -0
  224. WMCore/WorkQueue/DataLocationMapper.py +273 -0
  225. WMCore/WorkQueue/DataStructs/ACDCBlock.py +47 -0
  226. WMCore/WorkQueue/DataStructs/Block.py +48 -0
  227. WMCore/WorkQueue/DataStructs/CouchWorkQueueElement.py +148 -0
  228. WMCore/WorkQueue/DataStructs/WorkQueueElement.py +274 -0
  229. WMCore/WorkQueue/DataStructs/WorkQueueElementResult.py +152 -0
  230. WMCore/WorkQueue/DataStructs/WorkQueueElementsSummary.py +185 -0
  231. WMCore/WorkQueue/DataStructs/__init__.py +0 -0
  232. WMCore/WorkQueue/Policy/End/EndPolicyInterface.py +44 -0
  233. WMCore/WorkQueue/Policy/End/SingleShot.py +22 -0
  234. WMCore/WorkQueue/Policy/End/__init__.py +32 -0
  235. WMCore/WorkQueue/Policy/PolicyInterface.py +17 -0
  236. WMCore/WorkQueue/Policy/Start/Block.py +258 -0
  237. WMCore/WorkQueue/Policy/Start/Dataset.py +180 -0
  238. WMCore/WorkQueue/Policy/Start/MonteCarlo.py +131 -0
  239. WMCore/WorkQueue/Policy/Start/ResubmitBlock.py +171 -0
  240. WMCore/WorkQueue/Policy/Start/StartPolicyInterface.py +316 -0
  241. WMCore/WorkQueue/Policy/Start/__init__.py +34 -0
  242. WMCore/WorkQueue/Policy/__init__.py +57 -0
  243. WMCore/WorkQueue/WMBSHelper.py +772 -0
  244. WMCore/WorkQueue/WorkQueue.py +1237 -0
  245. WMCore/WorkQueue/WorkQueueBackend.py +750 -0
  246. WMCore/WorkQueue/WorkQueueBase.py +39 -0
  247. WMCore/WorkQueue/WorkQueueExceptions.py +44 -0
  248. WMCore/WorkQueue/WorkQueueReqMgrInterface.py +278 -0
  249. WMCore/WorkQueue/WorkQueueUtils.py +130 -0
  250. WMCore/WorkQueue/__init__.py +13 -0
  251. WMCore/Wrappers/JsonWrapper/JSONThunker.py +342 -0
  252. WMCore/Wrappers/JsonWrapper/__init__.py +7 -0
  253. WMCore/Wrappers/__init__.py +6 -0
  254. WMCore/__init__.py +10 -0
  255. wmglobalqueue-2.4.5.1.data/data/bin/wmc-dist-patch +15 -0
  256. wmglobalqueue-2.4.5.1.data/data/bin/wmc-dist-unpatch +8 -0
  257. wmglobalqueue-2.4.5.1.data/data/bin/wmc-httpd +3 -0
  258. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/.couchapprc +1 -0
  259. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/README.md +40 -0
  260. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/index.html +264 -0
  261. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/js/ElementInfoByWorkflow.js +96 -0
  262. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/js/StuckElementInfo.js +57 -0
  263. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/js/WorkloadInfoTable.js +80 -0
  264. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/js/dataTable.js +70 -0
  265. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/js/namespace.js +23 -0
  266. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/style/main.css +75 -0
  267. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/couchapp.json +4 -0
  268. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/filters/childQueueFilter.js +13 -0
  269. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/filters/filterDeletedDocs.js +3 -0
  270. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/filters/queueFilter.js +11 -0
  271. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/language +1 -0
  272. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lib/mustache.js +333 -0
  273. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lib/validate.js +27 -0
  274. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lib/workqueue_utils.js +61 -0
  275. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lists/elementsDetail.js +28 -0
  276. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lists/filter.js +86 -0
  277. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lists/stuckElements.js +38 -0
  278. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lists/workRestrictions.js +153 -0
  279. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lists/workflowSummary.js +28 -0
  280. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/rewrites.json +73 -0
  281. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/shows/redirect.js +23 -0
  282. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/shows/status.js +40 -0
  283. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/ElementSummaryByWorkflow.html +27 -0
  284. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/StuckElementSummary.html +26 -0
  285. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/TaskStatus.html +23 -0
  286. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/WorkflowSummary.html +27 -0
  287. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/partials/workqueue-common-lib.html +2 -0
  288. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/partials/yui-lib-remote.html +16 -0
  289. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/partials/yui-lib.html +18 -0
  290. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/updates/in-place.js +50 -0
  291. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/validate_doc_update.js +8 -0
  292. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/vendor/couchapp/_attachments/jquery.couch.app.js +235 -0
  293. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/vendor/couchapp/_attachments/jquery.pathbinder.js +173 -0
  294. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/activeData/map.js +8 -0
  295. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/activeData/reduce.js +2 -0
  296. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/activeParentData/map.js +8 -0
  297. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/activeParentData/reduce.js +2 -0
  298. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/activePileupData/map.js +8 -0
  299. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/activePileupData/reduce.js +2 -0
  300. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/analyticsData/map.js +11 -0
  301. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/analyticsData/reduce.js +1 -0
  302. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/availableByPriority/map.js +6 -0
  303. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/conflicts/map.js +5 -0
  304. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elements/map.js +5 -0
  305. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByData/map.js +8 -0
  306. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByParent/map.js +8 -0
  307. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByParentData/map.js +8 -0
  308. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByPileupData/map.js +8 -0
  309. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByStatus/map.js +8 -0
  310. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsBySubscription/map.js +6 -0
  311. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByWorkflow/map.js +8 -0
  312. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByWorkflow/reduce.js +3 -0
  313. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsDetailByWorkflowAndStatus/map.js +26 -0
  314. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobInjectStatusByRequest/map.js +10 -0
  315. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobInjectStatusByRequest/reduce.js +1 -0
  316. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobStatusByRequest/map.js +6 -0
  317. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobStatusByRequest/reduce.js +1 -0
  318. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByChildQueueAndPriority/map.js +6 -0
  319. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByChildQueueAndPriority/reduce.js +1 -0
  320. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByChildQueueAndStatus/map.js +6 -0
  321. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByChildQueueAndStatus/reduce.js +1 -0
  322. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByRequest/map.js +6 -0
  323. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByRequest/reduce.js +1 -0
  324. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByStatus/map.js +6 -0
  325. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByStatus/reduce.js +1 -0
  326. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByStatusAndPriority/map.js +6 -0
  327. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByStatusAndPriority/reduce.js +1 -0
  328. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/openRequests/map.js +6 -0
  329. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/recent-items/map.js +5 -0
  330. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/siteWhitelistByRequest/map.js +6 -0
  331. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/siteWhitelistByRequest/reduce.js +1 -0
  332. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/specsByWorkflow/map.js +5 -0
  333. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/stuckElements/map.js +38 -0
  334. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/wmbsInjectStatusByRequest/map.js +12 -0
  335. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/wmbsInjectStatusByRequest/reduce.js +3 -0
  336. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/wmbsUrl/map.js +6 -0
  337. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/wmbsUrl/reduce.js +2 -0
  338. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/wmbsUrlByRequest/map.js +6 -0
  339. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/wmbsUrlByRequest/reduce.js +2 -0
  340. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/workflowSummary/map.js +9 -0
  341. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/workflowSummary/reduce.js +10 -0
  342. wmglobalqueue-2.4.5.1.dist-info/METADATA +26 -0
  343. wmglobalqueue-2.4.5.1.dist-info/RECORD +347 -0
  344. wmglobalqueue-2.4.5.1.dist-info/WHEEL +5 -0
  345. wmglobalqueue-2.4.5.1.dist-info/licenses/LICENSE +202 -0
  346. wmglobalqueue-2.4.5.1.dist-info/licenses/NOTICE +16 -0
  347. wmglobalqueue-2.4.5.1.dist-info/top_level.txt +2 -0
@@ -0,0 +1,316 @@
1
+ #!/usr/bin/env python
2
+ """
3
+ WorkQueue SplitPolicyInterface
4
+
5
+ """
6
+ from builtins import str as newstr, bytes
7
+ from future.utils import viewitems
8
+
9
+
10
+ __all__ = []
11
+ from WMCore.WorkQueue.Policy.PolicyInterface import PolicyInterface
12
+ from WMCore.WorkQueue.DataStructs.WorkQueueElement import WorkQueueElement
13
+ from WMCore.DataStructs.LumiList import LumiList
14
+ from WMCore.WorkQueue.WorkQueueExceptions import WorkQueueWMSpecError, WorkQueueNoWorkError
15
+ from WMCore.Services.MSUtils.MSUtils import getPileupDocs
16
+ from dbs.exceptions.dbsClientException import dbsClientException
17
+ from WMCore.Services.CRIC.CRIC import CRIC
18
+ from WMCore.Services.Rucio.Rucio import Rucio
19
+ from WMCore.Services.DBS.DBSErrors import DBSReaderError
20
+ from WMCore import Lexicon
21
+
22
+
23
+ class StartPolicyInterface(PolicyInterface):
24
+ """Interface for start policies"""
25
+
26
+ def __init__(self, **args):
27
+ # We need to pop this object instance from args because otherwise
28
+ # the super class blows up when doing a deepcopy(args)
29
+ self.rucio = args.pop("rucioObject", None)
30
+ PolicyInterface.__init__(self, **args)
31
+ self.workQueueElements = []
32
+ self.wmspec = None
33
+ self.team = None
34
+ self.initialTask = None
35
+ self.splitParams = None
36
+ self.dbs_pool = {}
37
+ self.data = {}
38
+ self.lumi = None
39
+ self.couchdb = None
40
+ self.rejectedWork = [] # List of inputs that were rejected
41
+ self.badWork = [] # list of bad work unit (e.g. without any valid files)
42
+ self.pileupData = {}
43
+ self.cric = CRIC()
44
+ # FIXME: for the moment, it will always use the default value
45
+ self.rucioAcct = self.args.get("rucioAcct", "wmcore_transferor")
46
+ self.rucioAcctPU = self.args.get("rucioAcctPU", "wmcore_pileup")
47
+ if not self.rucio:
48
+ self.rucio = Rucio(self.rucioAcct, configDict={'logger': self.logger})
49
+
50
+ def split(self):
51
+ """Apply policy to spec"""
52
+ raise NotImplementedError
53
+
54
+ def validate(self):
55
+ """Check params and spec are appropriate for the policy"""
56
+ raise NotImplementedError
57
+
58
+ def validateCommon(self):
59
+ """Common validation stuff"""
60
+ try:
61
+ Lexicon.requestName(self.wmspec.name())
62
+ except Exception as ex: # can throw many errors e.g. AttributeError, AssertionError etc.
63
+ error = WorkQueueWMSpecError(self.wmspec, "Workflow name validation error: %s" % str(ex))
64
+ raise error
65
+
66
+ if self.initialTask.siteWhitelist():
67
+ if isinstance(self.initialTask.siteWhitelist(), (newstr, bytes)):
68
+ error = WorkQueueWMSpecError(self.wmspec, 'Invalid site whitelist: Must be tuple/list but is %s' % type(
69
+ self.initialTask.siteWhitelist()))
70
+ raise error
71
+ try:
72
+ [Lexicon.cmsname(site) for site in self.initialTask.siteWhitelist()]
73
+ except Exception as ex: # can throw many errors e.g. AttributeError, AssertionError etc.
74
+ error = WorkQueueWMSpecError(self.wmspec, "Site whitelist validation error: %s" % str(ex))
75
+ raise error
76
+ else:
77
+ error = WorkQueueWMSpecError(self.wmspec, "Site whitelist validation error: Empty site whitelist")
78
+ raise error
79
+
80
+ if self.initialTask.siteBlacklist():
81
+ if isinstance(self.initialTask.siteBlacklist(), (newstr, bytes)):
82
+ error = WorkQueueWMSpecError(self.wmspec, 'Invalid site blacklist: Must be tuple/list but is %s' % type(
83
+ self.initialTask.siteBlacklist()))
84
+ raise error
85
+ try:
86
+ [Lexicon.cmsname(site) for site in self.initialTask.siteBlacklist()]
87
+ except Exception as ex: # can throw many errors e.g. AttributeError, AssertionError etc.
88
+ error = WorkQueueWMSpecError(self.wmspec, "Site blacklist validation error: %s" % str(ex))
89
+ raise error
90
+
91
+ # splitter settings
92
+ if self.args.get('SliceSize', 1) <= 0:
93
+ error = WorkQueueWMSpecError(self.wmspec, 'Zero or negative SliceSize parameter')
94
+ raise error
95
+ if self.args.get('SubSliceSize', 1) <= 0:
96
+ error = WorkQueueWMSpecError(self.wmspec, 'Zero or negative SubSliceSize parameter')
97
+ raise error
98
+
99
+ # check input dataset is valid
100
+ try:
101
+ if self.initialTask.getInputDatasetPath():
102
+ Lexicon.dataset(self.initialTask.getInputDatasetPath())
103
+ except Exception as ex: # can throw many errors e.g. AttributeError, AssertionError etc.
104
+ error = WorkQueueWMSpecError(self.wmspec, "Dataset validation error: %s" % str(ex))
105
+ raise error
106
+
107
+ # if pileup is found, check that they are valid datasets
108
+ try:
109
+ pileupDatasets = self.wmspec.listPileupDatasets()
110
+ for dbsUrl in pileupDatasets:
111
+ for dataset in pileupDatasets[dbsUrl]:
112
+ Lexicon.dataset(dataset)
113
+ except Exception as ex: # can throw many errors e.g. AttributeError, AssertionError etc.
114
+ error = WorkQueueWMSpecError(self.wmspec, "Pileup dataset validation error: %s" % str(ex))
115
+ raise error
116
+
117
+ def newQueueElement(self, **args):
118
+ # DBS Url may not be available in the initial task
119
+ # but in the pileup data (MC pileup)
120
+ dbsUrl = self.initialTask.dbsUrl()
121
+ if dbsUrl is None and self.pileupData:
122
+ # Get the first DBS found
123
+ dbsUrl = next(iter(self.wmspec.listPileupDatasets()))
124
+
125
+ args.setdefault('Status', 'Available')
126
+ args.setdefault('WMSpec', self.wmspec)
127
+ args.setdefault('Task', self.initialTask)
128
+ args.setdefault('RequestName', self.wmspec.name())
129
+ args.setdefault('TaskName', self.initialTask.name())
130
+ args.setdefault('Dbs', dbsUrl)
131
+ args.setdefault('SiteWhitelist', self.initialTask.siteWhitelist())
132
+ args.setdefault('SiteBlacklist', self.initialTask.siteBlacklist())
133
+ args.setdefault('StartPolicy', self.wmspec.startPolicy())
134
+ args.setdefault('EndPolicy', self.wmspec.endPolicyParameters())
135
+ args.setdefault('Priority', self.wmspec.priority())
136
+ args.setdefault('PileupData', self.pileupData)
137
+ if not args['Priority']:
138
+ args['Priority'] = 0
139
+ ele = WorkQueueElement(**args)
140
+ for data, sites in viewitems(ele['Inputs']):
141
+ if not sites:
142
+ # we comment out raising exception due to issue-11784 and allow WQ element creation
143
+ # but we would like to monitor when and how often it happens
144
+ self.logger.warning('Input data has no location, spec=%s, data=%s', self.wmspec, data)
145
+ # raise WorkQueueWMSpecError(self.wmspec, 'Input data has no locations "%s"' % data)
146
+
147
+ # catch infinite splitting loops
148
+ if len(self.workQueueElements) > self.args.get('maxRequestSize', 1e8):
149
+ raise WorkQueueWMSpecError(self.wmspec, 'Too many elements (%d)' % self.args.get('MaxRequestElements', 1e8))
150
+ self.workQueueElements.append(ele)
151
+
152
+ def __call__(self, wmspec, task, data=None, mask=None, team=None, continuous=False, rucioObj=None):
153
+ self.wmspec = wmspec
154
+ # bring in spec specific settings
155
+ self.args.update(self.wmspec.startPolicyParameters())
156
+ self.initialTask = task
157
+ if data:
158
+ self.data = data
159
+ self.mask = mask
160
+ self.validate()
161
+ try:
162
+ pileupDatasets = self.wmspec.listPileupDatasets()
163
+ self.logger.debug(f'pileupDatasets: {pileupDatasets}')
164
+ if pileupDatasets:
165
+ # unwrap {"url":[datasets]} structure into list of datasets
166
+ self.pileupData = self.getDatasetLocationsFromMSPileup(pileupDatasets)
167
+ self.split()
168
+ # For known exceptions raise custom error that will fail the workflow.
169
+ except dbsClientException as ex:
170
+ # A dbs configuration error implies the spec is invalid
171
+ error = WorkQueueWMSpecError(self.wmspec, "DBS config error: %s" % str(ex))
172
+ raise error
173
+ except AssertionError as ex:
174
+ # Assertion generally means validation of an input field failed
175
+ error = WorkQueueWMSpecError(self.wmspec, "Assertion error: %s" % str(ex))
176
+ raise error
177
+ except DBSReaderError as ex:
178
+ # Hacky way of identifying non-existant data, DbsBadRequest chomped by DBSReader
179
+ if 'Invalid parameters' in str(ex):
180
+ data = task.data.input.pythonise_() if task.data.input else 'None'
181
+ msg = """data: %s, mask: %s, pileup: %s. %s""" % (str(data), str(mask), str(pileupDatasets), str(ex))
182
+ error = WorkQueueNoWorkError(self.wmspec, msg)
183
+ raise error
184
+ raise # propagate other dbs errors
185
+
186
+ # if we have no new elements and we are not adding work to request
187
+ # already running, then raise exception
188
+ if not self.workQueueElements and not continuous:
189
+ data = task.data.input.pythonise_() if task.data.input else 'None'
190
+ msg = "Failed to add work. Input data: %s, mask: %s." % (str(data), str(mask))
191
+ error = WorkQueueNoWorkError(self.wmspec, msg)
192
+ raise error
193
+
194
+ return self.workQueueElements, self.rejectedWork, self.badWork
195
+
196
+ def dbs(self, dbs_url=None):
197
+ """Get DBSReader"""
198
+ from WMCore.WorkQueue.WorkQueueUtils import get_dbs
199
+ if dbs_url is None:
200
+ dbs_url = self.initialTask.dbsUrl()
201
+ return get_dbs(dbs_url)
202
+
203
+ @staticmethod
204
+ def supportsWorkAddition():
205
+ """Indicates if a given policy supports addition of new work"""
206
+ return False
207
+
208
+ def getMaskedBlocks(self, task, dbs, datasetPath):
209
+ """
210
+ Get the blocks which pass the lumi mask restrictions. For each block
211
+ return the list of lumis which were ok (given the lumi mask). The data
212
+ structure returned is the following:
213
+ {
214
+ "block1" : {"file1" : LumiList(), "file5" : LumiList(), ...}
215
+ "block2" : {"file2" : LumiList(), "file7" : LumiList(), ...}
216
+ }
217
+ """
218
+ # Get the task mask as a LumiList object to make operations easier
219
+ maskedBlocks = {}
220
+ taskMask = task.getLumiMask()
221
+
222
+ # for performance reasons, we first get all the blocknames
223
+ blocks = [x['block_name'] for x in dbs.dbs.listBlocks(dataset=datasetPath)]
224
+
225
+ for block in blocks:
226
+ fileLumis = dbs.dbs.listFileLumis(block_name=block, validFileOnly=1)
227
+ for fileLumi in fileLumis:
228
+ lfn = fileLumi['logical_file_name']
229
+ runNumber = str(fileLumi['run_num'])
230
+ lumis = fileLumi['lumi_section_num']
231
+ fileMask = LumiList(runsAndLumis={runNumber: lumis})
232
+ commonMask = taskMask & fileMask
233
+ if commonMask:
234
+ maskedBlocks.setdefault(block, {})
235
+ maskedBlocks[block].setdefault(lfn, LumiList())
236
+ maskedBlocks[block][lfn] += commonMask
237
+
238
+ return maskedBlocks
239
+
240
+ def modifyPolicyForWorkAddition(self, inboxElement):
241
+ """Set modifiers to the policy based on the inboxElement information so that after a splitting pass
242
+ with this policy strictly new work is returned, the inbox element must have information
243
+ about already existing work"""
244
+ raise NotImplementedError("This can't be called on a base StartPolicyInterface object")
245
+
246
+ def newDataAvailable(self, task, inbound):
247
+ """
248
+ Returns True if there is data in the future could be included as an element
249
+ for the inbound parent. However it doesn't guarantee that the new data
250
+ will be included if the inbound element is split (i.e. the new data could be open blocks for the Block policy).
251
+ """
252
+ raise NotImplementedError("This can't be called on a base StartPolicyInterface object")
253
+
254
+ def getDatasetLocations(self, datasets, account=None):
255
+ """
256
+ Returns a dictionary with the location of the datasets according to Rucio
257
+ The definition of "location" here is a union of all sites holding at least
258
+ part of the dataset (defined by the DATASET grouping).
259
+ :param datasets: list of datasets
260
+ :param account: rucio account to use, if it is not provided we fallback to
261
+ pileup account for backward compatibility
262
+ :return: a dictionary of dataset locations, key'ed by the dataset name
263
+ """
264
+ if not account:
265
+ account = self.rucioAcctPU
266
+ if isinstance(datasets, str):
267
+ datasets = [datasets]
268
+ result = {}
269
+ for datasetPath in datasets:
270
+ msg = f"Fetching Rucio locks for account: {account} and dataset: {datasetPath}"
271
+ self.logger.info(msg)
272
+ locations = self.rucio.getDataLockedAndAvailable(name=datasetPath,
273
+ account=account)
274
+ result[datasetPath] = self.cric.PNNstoPSNs(locations)
275
+ return result
276
+
277
+ def getDatasetLocationsFromMSPileup(self, datasetsWithDbsURL):
278
+ """
279
+ Returns a dictionary with the location of the datasets according to MSPileup
280
+ :param datasetsWithDbsURL: a dict with the DBS URL as the key, and the associated list of datasets as the value
281
+ """
282
+
283
+ result = {}
284
+ for dbsUrl, datasets in datasetsWithDbsURL.items():
285
+ pileUpinstance = '-testbed' if 'cmsweb-testbed' in dbsUrl else '-prod'
286
+ msPileupUrl = f'https://cmsweb{pileUpinstance}.cern.ch/ms-pileup/data/pileup'
287
+ self.logger.info(f'Will fetch {len(datasets)} from MSPileup url: {msPileupUrl}')
288
+ for dataset in datasets:
289
+ queryDict = {'query': {'pileupName': dataset},
290
+ 'filters': ['expectedRSEs', 'currentRSEs', 'pileupName', 'containerFraction', 'ruleIds']}
291
+ try:
292
+ doc = getPileupDocs(msPileupUrl, queryDict, method='POST')[0]
293
+ currentRSEs = self.cric.PNNstoPSNs(doc['currentRSEs'])
294
+ self.logger.debug(f'Retrieved MSPileup document: {doc}')
295
+ if len(currentRSEs) == 0:
296
+ self.logger.warning(f'No RSE has a copy of the desired pileup dataset. Expected RSEs: {doc["expectedRSEs"]}')
297
+ result[dataset] = currentRSEs
298
+ except IndexError:
299
+ self.logger.warning('Did not find any pileup document for query: %s', queryDict['query'])
300
+ result[dataset] = []
301
+ except Exception as ex:
302
+ self.logger.exception('Error getting block location from MSPileup for %s: %s', dataset, str(ex))
303
+
304
+ return result
305
+
306
+ def blockLocationRucioPhedex(self, blockName):
307
+ """
308
+ Wrapper around Rucio and PhEDEx systems.
309
+ Fetch the current location of the block name (if Rucio,
310
+ also consider the locks made on that block)
311
+ :param blockName: string with the block name
312
+ :return: a list of RSEs
313
+ """
314
+ location = self.rucio.getDataLockedAndAvailable(name=blockName,
315
+ account=self.rucioAcct)
316
+ return location
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env python
2
+ """
3
+ WorkQueue Start Policy
4
+
5
+ """
6
+ from copy import deepcopy
7
+ from WMCore.WMFactory import WMFactory
8
+
9
+ startFac = WMFactory(__name__, __name__)
10
+
11
+
12
+ def startPolicy(name, startMap, rucioObj, logger=None):
13
+ """Load a start policy"""
14
+ # Take splitting policy from workload & load specific policy for this queue
15
+ # Workload may also directly specify specific splitter implementation
16
+ if name in startMap:
17
+ # take mapping from queue
18
+ policyName = startMap[name]['name']
19
+ else:
20
+ # workload directly specifies splitting algo
21
+ policyName = name
22
+ try:
23
+ args = deepcopy(startMap[name]['args'])
24
+ except IndexError:
25
+ args = {}
26
+ args['rucioObject'] = rucioObj
27
+ args['logger'] = logger
28
+ return startFac.loadObject(policyName,
29
+ args,
30
+ storeInCache=False,
31
+ )
32
+
33
+
34
+ __all__ = []
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env python
2
+ """
3
+ WorkQueue Policy
4
+
5
+ https://twiki.cern.ch/twiki/bin/view/CMS/WMCoreWorkQueuePolicy
6
+ """
7
+
8
+
9
+ #
10
+ #from WMCore.WMFactory import WMFactory
11
+ #from WMCore.WMSpec.WMWorkload import WMWorkloadHelper
12
+ #
13
+ #startFac = WMFactory("WorkQueueStartPolicy", __name__ + '.Start')
14
+ #endFac = WMFactory("WorkQueueEndPolicy", __name__ + '.End')
15
+ #startMap = {}
16
+ #
17
+ ##TODO: Argument handling need to give params from workqueue as well as from spec
18
+ #
19
+ #def setStartPolicy(policyDirective, policyName, policyArgs):
20
+ # """Set the Start policy for a queue"""
21
+ # global startMap
22
+ # startMap[policyDirective] = (policyName, policyArgs)
23
+ #
24
+ #def startPolicy(name, startMap):
25
+ # """Load a start policy"""
26
+ # # Do we have a defined policy for this policy - if not load null policy
27
+ # if not startMap.has_key(name):
28
+ # name = 'passthrough'
29
+ # policyName, args = startMap[name]
30
+ # #policyName, args = startMap.get(name, ('passthrough', {}))
31
+ # return startFac.loadObject(policyName,
32
+ # args,
33
+ # storeInCache = False,
34
+ # )
35
+ ## return startFac.loadObject(startMap.get(name, name),
36
+ ## args,
37
+ ## storeInCache = False)
38
+ #
39
+ #def endPolicy(elements, args):
40
+ # """Load an end policy"""
41
+ #
42
+ # for ele in elements:
43
+ # # if still working return simple aggregate state
44
+ # if not ele.inEndState():
45
+ # return endFac.loadObject('SingleShot',
46
+ # {'SuccessThreshold' : 1.0},
47
+ # storeInCache = False)(*elements)
48
+ #
49
+ # # all elements finished processing load policy and apply
50
+ # spec = WMWorkloadHelper()
51
+ # spec.load(elements[0]['WMSpecUrl'])
52
+ # args.update(spec.data.policies.end.dictionary_())
53
+ # return endFac.loadObject(spec.data.policies.end.policyName,
54
+ # args,
55
+ # storeInCache = False)(*elements)
56
+ #
57
+ #__all__ = [setStartPolicy, startPolicy, endPolicy]