wmglobalqueue 2.3.10rc10__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.

Potentially problematic release.


This version of wmglobalqueue might be problematic. Click here for more details.

Files changed (345) hide show
  1. Utils/CPMetrics.py +270 -0
  2. Utils/CertTools.py +62 -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/ProcessStats.py +103 -0
  13. Utils/PythonVersion.py +17 -0
  14. Utils/Signals.py +36 -0
  15. Utils/TemporaryEnvironment.py +27 -0
  16. Utils/Throttled.py +227 -0
  17. Utils/Timers.py +130 -0
  18. Utils/Timestamps.py +86 -0
  19. Utils/TokenManager.py +143 -0
  20. Utils/Tracing.py +60 -0
  21. Utils/TwPrint.py +98 -0
  22. Utils/Utilities.py +308 -0
  23. Utils/__init__.py +11 -0
  24. WMCore/ACDC/Collection.py +57 -0
  25. WMCore/ACDC/CollectionTypes.py +12 -0
  26. WMCore/ACDC/CouchCollection.py +67 -0
  27. WMCore/ACDC/CouchFileset.py +238 -0
  28. WMCore/ACDC/CouchService.py +73 -0
  29. WMCore/ACDC/DataCollectionService.py +485 -0
  30. WMCore/ACDC/Fileset.py +94 -0
  31. WMCore/ACDC/__init__.py +11 -0
  32. WMCore/Algorithms/Alarm.py +39 -0
  33. WMCore/Algorithms/MathAlgos.py +274 -0
  34. WMCore/Algorithms/MiscAlgos.py +67 -0
  35. WMCore/Algorithms/ParseXMLFile.py +115 -0
  36. WMCore/Algorithms/Permissions.py +27 -0
  37. WMCore/Algorithms/Singleton.py +58 -0
  38. WMCore/Algorithms/SubprocessAlgos.py +129 -0
  39. WMCore/Algorithms/__init__.py +7 -0
  40. WMCore/Cache/GenericDataCache.py +98 -0
  41. WMCore/Cache/WMConfigCache.py +572 -0
  42. WMCore/Cache/__init__.py +0 -0
  43. WMCore/Configuration.py +651 -0
  44. WMCore/DAOFactory.py +47 -0
  45. WMCore/DataStructs/File.py +177 -0
  46. WMCore/DataStructs/Fileset.py +140 -0
  47. WMCore/DataStructs/Job.py +182 -0
  48. WMCore/DataStructs/JobGroup.py +142 -0
  49. WMCore/DataStructs/JobPackage.py +49 -0
  50. WMCore/DataStructs/LumiList.py +734 -0
  51. WMCore/DataStructs/Mask.py +219 -0
  52. WMCore/DataStructs/MathStructs/ContinuousSummaryHistogram.py +197 -0
  53. WMCore/DataStructs/MathStructs/DiscreteSummaryHistogram.py +92 -0
  54. WMCore/DataStructs/MathStructs/SummaryHistogram.py +117 -0
  55. WMCore/DataStructs/MathStructs/__init__.py +0 -0
  56. WMCore/DataStructs/Pickleable.py +24 -0
  57. WMCore/DataStructs/Run.py +256 -0
  58. WMCore/DataStructs/Subscription.py +175 -0
  59. WMCore/DataStructs/WMObject.py +47 -0
  60. WMCore/DataStructs/WorkUnit.py +112 -0
  61. WMCore/DataStructs/Workflow.py +60 -0
  62. WMCore/DataStructs/__init__.py +8 -0
  63. WMCore/Database/CMSCouch.py +1349 -0
  64. WMCore/Database/ConfigDBMap.py +29 -0
  65. WMCore/Database/CouchUtils.py +118 -0
  66. WMCore/Database/DBCore.py +198 -0
  67. WMCore/Database/DBCreator.py +113 -0
  68. WMCore/Database/DBExceptionHandler.py +57 -0
  69. WMCore/Database/DBFactory.py +110 -0
  70. WMCore/Database/DBFormatter.py +177 -0
  71. WMCore/Database/Dialects.py +13 -0
  72. WMCore/Database/ExecuteDAO.py +327 -0
  73. WMCore/Database/MongoDB.py +241 -0
  74. WMCore/Database/MySQL/Destroy.py +42 -0
  75. WMCore/Database/MySQL/ListUserContent.py +20 -0
  76. WMCore/Database/MySQL/__init__.py +9 -0
  77. WMCore/Database/MySQLCore.py +132 -0
  78. WMCore/Database/Oracle/Destroy.py +56 -0
  79. WMCore/Database/Oracle/ListUserContent.py +19 -0
  80. WMCore/Database/Oracle/__init__.py +9 -0
  81. WMCore/Database/ResultSet.py +44 -0
  82. WMCore/Database/Transaction.py +91 -0
  83. WMCore/Database/__init__.py +9 -0
  84. WMCore/Database/ipy_profile_couch.py +438 -0
  85. WMCore/GlobalWorkQueue/CherryPyThreads/CleanUpTask.py +29 -0
  86. WMCore/GlobalWorkQueue/CherryPyThreads/HeartbeatMonitor.py +105 -0
  87. WMCore/GlobalWorkQueue/CherryPyThreads/LocationUpdateTask.py +28 -0
  88. WMCore/GlobalWorkQueue/CherryPyThreads/ReqMgrInteractionTask.py +35 -0
  89. WMCore/GlobalWorkQueue/CherryPyThreads/__init__.py +0 -0
  90. WMCore/GlobalWorkQueue/__init__.py +0 -0
  91. WMCore/GroupUser/CouchObject.py +127 -0
  92. WMCore/GroupUser/Decorators.py +51 -0
  93. WMCore/GroupUser/Group.py +33 -0
  94. WMCore/GroupUser/Interface.py +73 -0
  95. WMCore/GroupUser/User.py +96 -0
  96. WMCore/GroupUser/__init__.py +11 -0
  97. WMCore/Lexicon.py +836 -0
  98. WMCore/REST/Auth.py +202 -0
  99. WMCore/REST/CherryPyPeriodicTask.py +166 -0
  100. WMCore/REST/Error.py +333 -0
  101. WMCore/REST/Format.py +642 -0
  102. WMCore/REST/HeartbeatMonitorBase.py +90 -0
  103. WMCore/REST/Main.py +623 -0
  104. WMCore/REST/Server.py +2435 -0
  105. WMCore/REST/Services.py +24 -0
  106. WMCore/REST/Test.py +120 -0
  107. WMCore/REST/Tools.py +38 -0
  108. WMCore/REST/Validation.py +250 -0
  109. WMCore/REST/__init__.py +1 -0
  110. WMCore/ReqMgr/DataStructs/RequestStatus.py +209 -0
  111. WMCore/ReqMgr/DataStructs/RequestType.py +13 -0
  112. WMCore/ReqMgr/DataStructs/__init__.py +0 -0
  113. WMCore/ReqMgr/__init__.py +1 -0
  114. WMCore/Services/AlertManager/AlertManagerAPI.py +111 -0
  115. WMCore/Services/AlertManager/__init__.py +0 -0
  116. WMCore/Services/CRIC/CRIC.py +238 -0
  117. WMCore/Services/CRIC/__init__.py +0 -0
  118. WMCore/Services/DBS/DBS3Reader.py +1044 -0
  119. WMCore/Services/DBS/DBSConcurrency.py +44 -0
  120. WMCore/Services/DBS/DBSErrors.py +113 -0
  121. WMCore/Services/DBS/DBSReader.py +23 -0
  122. WMCore/Services/DBS/DBSUtils.py +139 -0
  123. WMCore/Services/DBS/DBSWriterObjects.py +381 -0
  124. WMCore/Services/DBS/ProdException.py +133 -0
  125. WMCore/Services/DBS/__init__.py +8 -0
  126. WMCore/Services/FWJRDB/FWJRDBAPI.py +118 -0
  127. WMCore/Services/FWJRDB/__init__.py +0 -0
  128. WMCore/Services/HTTPS/HTTPSAuthHandler.py +66 -0
  129. WMCore/Services/HTTPS/__init__.py +0 -0
  130. WMCore/Services/LogDB/LogDB.py +201 -0
  131. WMCore/Services/LogDB/LogDBBackend.py +191 -0
  132. WMCore/Services/LogDB/LogDBExceptions.py +11 -0
  133. WMCore/Services/LogDB/LogDBReport.py +85 -0
  134. WMCore/Services/LogDB/__init__.py +0 -0
  135. WMCore/Services/MSPileup/__init__.py +0 -0
  136. WMCore/Services/MSUtils/MSUtils.py +54 -0
  137. WMCore/Services/MSUtils/__init__.py +0 -0
  138. WMCore/Services/McM/McM.py +173 -0
  139. WMCore/Services/McM/__init__.py +8 -0
  140. WMCore/Services/MonIT/Grafana.py +133 -0
  141. WMCore/Services/MonIT/__init__.py +0 -0
  142. WMCore/Services/PyCondor/PyCondorAPI.py +154 -0
  143. WMCore/Services/PyCondor/PyCondorUtils.py +105 -0
  144. WMCore/Services/PyCondor/__init__.py +0 -0
  145. WMCore/Services/ReqMgr/ReqMgr.py +261 -0
  146. WMCore/Services/ReqMgr/__init__.py +0 -0
  147. WMCore/Services/ReqMgrAux/ReqMgrAux.py +419 -0
  148. WMCore/Services/ReqMgrAux/__init__.py +0 -0
  149. WMCore/Services/RequestDB/RequestDBReader.py +267 -0
  150. WMCore/Services/RequestDB/RequestDBWriter.py +39 -0
  151. WMCore/Services/RequestDB/__init__.py +0 -0
  152. WMCore/Services/Requests.py +624 -0
  153. WMCore/Services/Rucio/Rucio.py +1287 -0
  154. WMCore/Services/Rucio/RucioUtils.py +74 -0
  155. WMCore/Services/Rucio/__init__.py +0 -0
  156. WMCore/Services/RucioConMon/RucioConMon.py +128 -0
  157. WMCore/Services/RucioConMon/__init__.py +0 -0
  158. WMCore/Services/Service.py +400 -0
  159. WMCore/Services/StompAMQ/__init__.py +0 -0
  160. WMCore/Services/TagCollector/TagCollector.py +155 -0
  161. WMCore/Services/TagCollector/XMLUtils.py +98 -0
  162. WMCore/Services/TagCollector/__init__.py +0 -0
  163. WMCore/Services/UUIDLib.py +13 -0
  164. WMCore/Services/UserFileCache/UserFileCache.py +160 -0
  165. WMCore/Services/UserFileCache/__init__.py +8 -0
  166. WMCore/Services/WMAgent/WMAgent.py +63 -0
  167. WMCore/Services/WMAgent/__init__.py +0 -0
  168. WMCore/Services/WMArchive/CMSSWMetrics.py +526 -0
  169. WMCore/Services/WMArchive/DataMap.py +463 -0
  170. WMCore/Services/WMArchive/WMArchive.py +33 -0
  171. WMCore/Services/WMArchive/__init__.py +0 -0
  172. WMCore/Services/WMBS/WMBS.py +97 -0
  173. WMCore/Services/WMBS/__init__.py +0 -0
  174. WMCore/Services/WMStats/DataStruct/RequestInfoCollection.py +300 -0
  175. WMCore/Services/WMStats/DataStruct/__init__.py +0 -0
  176. WMCore/Services/WMStats/WMStatsPycurl.py +145 -0
  177. WMCore/Services/WMStats/WMStatsReader.py +445 -0
  178. WMCore/Services/WMStats/WMStatsWriter.py +273 -0
  179. WMCore/Services/WMStats/__init__.py +0 -0
  180. WMCore/Services/WMStatsServer/WMStatsServer.py +134 -0
  181. WMCore/Services/WMStatsServer/__init__.py +0 -0
  182. WMCore/Services/WorkQueue/WorkQueue.py +492 -0
  183. WMCore/Services/WorkQueue/__init__.py +0 -0
  184. WMCore/Services/__init__.py +8 -0
  185. WMCore/Services/pycurl_manager.py +574 -0
  186. WMCore/WMBase.py +50 -0
  187. WMCore/WMConnectionBase.py +164 -0
  188. WMCore/WMException.py +183 -0
  189. WMCore/WMExceptions.py +269 -0
  190. WMCore/WMFactory.py +76 -0
  191. WMCore/WMInit.py +228 -0
  192. WMCore/WMLogging.py +108 -0
  193. WMCore/WMSpec/ConfigSectionTree.py +442 -0
  194. WMCore/WMSpec/Persistency.py +135 -0
  195. WMCore/WMSpec/Steps/BuildMaster.py +87 -0
  196. WMCore/WMSpec/Steps/BuildTools.py +201 -0
  197. WMCore/WMSpec/Steps/Builder.py +97 -0
  198. WMCore/WMSpec/Steps/Diagnostic.py +89 -0
  199. WMCore/WMSpec/Steps/Emulator.py +62 -0
  200. WMCore/WMSpec/Steps/ExecuteMaster.py +208 -0
  201. WMCore/WMSpec/Steps/Executor.py +210 -0
  202. WMCore/WMSpec/Steps/StepFactory.py +213 -0
  203. WMCore/WMSpec/Steps/TaskEmulator.py +75 -0
  204. WMCore/WMSpec/Steps/Template.py +204 -0
  205. WMCore/WMSpec/Steps/Templates/AlcaHarvest.py +76 -0
  206. WMCore/WMSpec/Steps/Templates/CMSSW.py +613 -0
  207. WMCore/WMSpec/Steps/Templates/DQMUpload.py +59 -0
  208. WMCore/WMSpec/Steps/Templates/DeleteFiles.py +70 -0
  209. WMCore/WMSpec/Steps/Templates/LogArchive.py +84 -0
  210. WMCore/WMSpec/Steps/Templates/LogCollect.py +105 -0
  211. WMCore/WMSpec/Steps/Templates/StageOut.py +105 -0
  212. WMCore/WMSpec/Steps/Templates/__init__.py +10 -0
  213. WMCore/WMSpec/Steps/WMExecutionFailure.py +21 -0
  214. WMCore/WMSpec/Steps/__init__.py +8 -0
  215. WMCore/WMSpec/Utilities.py +63 -0
  216. WMCore/WMSpec/WMSpecErrors.py +12 -0
  217. WMCore/WMSpec/WMStep.py +347 -0
  218. WMCore/WMSpec/WMTask.py +1980 -0
  219. WMCore/WMSpec/WMWorkload.py +2288 -0
  220. WMCore/WMSpec/WMWorkloadTools.py +370 -0
  221. WMCore/WMSpec/__init__.py +9 -0
  222. WMCore/WorkQueue/DataLocationMapper.py +269 -0
  223. WMCore/WorkQueue/DataStructs/ACDCBlock.py +47 -0
  224. WMCore/WorkQueue/DataStructs/Block.py +48 -0
  225. WMCore/WorkQueue/DataStructs/CouchWorkQueueElement.py +148 -0
  226. WMCore/WorkQueue/DataStructs/WorkQueueElement.py +274 -0
  227. WMCore/WorkQueue/DataStructs/WorkQueueElementResult.py +152 -0
  228. WMCore/WorkQueue/DataStructs/WorkQueueElementsSummary.py +185 -0
  229. WMCore/WorkQueue/DataStructs/__init__.py +0 -0
  230. WMCore/WorkQueue/Policy/End/EndPolicyInterface.py +44 -0
  231. WMCore/WorkQueue/Policy/End/SingleShot.py +22 -0
  232. WMCore/WorkQueue/Policy/End/__init__.py +32 -0
  233. WMCore/WorkQueue/Policy/PolicyInterface.py +17 -0
  234. WMCore/WorkQueue/Policy/Start/Block.py +258 -0
  235. WMCore/WorkQueue/Policy/Start/Dataset.py +180 -0
  236. WMCore/WorkQueue/Policy/Start/MonteCarlo.py +131 -0
  237. WMCore/WorkQueue/Policy/Start/ResubmitBlock.py +171 -0
  238. WMCore/WorkQueue/Policy/Start/StartPolicyInterface.py +316 -0
  239. WMCore/WorkQueue/Policy/Start/__init__.py +34 -0
  240. WMCore/WorkQueue/Policy/__init__.py +57 -0
  241. WMCore/WorkQueue/WMBSHelper.py +772 -0
  242. WMCore/WorkQueue/WorkQueue.py +1237 -0
  243. WMCore/WorkQueue/WorkQueueBackend.py +741 -0
  244. WMCore/WorkQueue/WorkQueueBase.py +39 -0
  245. WMCore/WorkQueue/WorkQueueExceptions.py +44 -0
  246. WMCore/WorkQueue/WorkQueueReqMgrInterface.py +278 -0
  247. WMCore/WorkQueue/WorkQueueUtils.py +130 -0
  248. WMCore/WorkQueue/__init__.py +13 -0
  249. WMCore/Wrappers/JsonWrapper/JSONThunker.py +342 -0
  250. WMCore/Wrappers/JsonWrapper/__init__.py +7 -0
  251. WMCore/Wrappers/__init__.py +6 -0
  252. WMCore/__init__.py +10 -0
  253. wmglobalqueue-2.3.10rc10.data/data/bin/wmc-dist-patch +15 -0
  254. wmglobalqueue-2.3.10rc10.data/data/bin/wmc-dist-unpatch +8 -0
  255. wmglobalqueue-2.3.10rc10.data/data/bin/wmc-httpd +3 -0
  256. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/.couchapprc +1 -0
  257. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/README.md +40 -0
  258. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/_attachments/index.html +264 -0
  259. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/_attachments/js/ElementInfoByWorkflow.js +96 -0
  260. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/_attachments/js/StuckElementInfo.js +57 -0
  261. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/_attachments/js/WorkloadInfoTable.js +80 -0
  262. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/_attachments/js/dataTable.js +70 -0
  263. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/_attachments/js/namespace.js +23 -0
  264. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/_attachments/style/main.css +75 -0
  265. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/couchapp.json +4 -0
  266. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/filters/childQueueFilter.js +13 -0
  267. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/filters/filterDeletedDocs.js +3 -0
  268. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/filters/queueFilter.js +11 -0
  269. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/language +1 -0
  270. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/lib/mustache.js +333 -0
  271. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/lib/validate.js +27 -0
  272. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/lib/workqueue_utils.js +61 -0
  273. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/lists/elementsDetail.js +28 -0
  274. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/lists/filter.js +86 -0
  275. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/lists/stuckElements.js +38 -0
  276. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/lists/workRestrictions.js +153 -0
  277. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/lists/workflowSummary.js +28 -0
  278. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/rewrites.json +73 -0
  279. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/shows/redirect.js +23 -0
  280. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/shows/status.js +40 -0
  281. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/templates/ElementSummaryByWorkflow.html +27 -0
  282. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/templates/StuckElementSummary.html +26 -0
  283. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/templates/TaskStatus.html +23 -0
  284. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/templates/WorkflowSummary.html +27 -0
  285. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/templates/partials/workqueue-common-lib.html +2 -0
  286. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/templates/partials/yui-lib-remote.html +16 -0
  287. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/templates/partials/yui-lib.html +18 -0
  288. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/updates/in-place.js +50 -0
  289. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/validate_doc_update.js +8 -0
  290. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/vendor/couchapp/_attachments/jquery.couch.app.js +235 -0
  291. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/vendor/couchapp/_attachments/jquery.pathbinder.js +173 -0
  292. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/activeData/map.js +8 -0
  293. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/activeData/reduce.js +2 -0
  294. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/activeParentData/map.js +8 -0
  295. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/activeParentData/reduce.js +2 -0
  296. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/activePileupData/map.js +8 -0
  297. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/activePileupData/reduce.js +2 -0
  298. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/analyticsData/map.js +11 -0
  299. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/analyticsData/reduce.js +1 -0
  300. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/availableByPriority/map.js +6 -0
  301. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/conflicts/map.js +5 -0
  302. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/elements/map.js +5 -0
  303. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/elementsByData/map.js +8 -0
  304. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/elementsByParent/map.js +8 -0
  305. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/elementsByParentData/map.js +8 -0
  306. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/elementsByPileupData/map.js +8 -0
  307. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/elementsByStatus/map.js +8 -0
  308. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/elementsBySubscription/map.js +6 -0
  309. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/elementsByWorkflow/map.js +8 -0
  310. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/elementsByWorkflow/reduce.js +3 -0
  311. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/elementsDetailByWorkflowAndStatus/map.js +26 -0
  312. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/jobInjectStatusByRequest/map.js +10 -0
  313. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/jobInjectStatusByRequest/reduce.js +1 -0
  314. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/jobStatusByRequest/map.js +6 -0
  315. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/jobStatusByRequest/reduce.js +1 -0
  316. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/jobsByChildQueueAndPriority/map.js +6 -0
  317. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/jobsByChildQueueAndPriority/reduce.js +1 -0
  318. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/jobsByChildQueueAndStatus/map.js +6 -0
  319. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/jobsByChildQueueAndStatus/reduce.js +1 -0
  320. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/jobsByRequest/map.js +6 -0
  321. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/jobsByRequest/reduce.js +1 -0
  322. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/jobsByStatus/map.js +6 -0
  323. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/jobsByStatus/reduce.js +1 -0
  324. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/jobsByStatusAndPriority/map.js +6 -0
  325. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/jobsByStatusAndPriority/reduce.js +1 -0
  326. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/openRequests/map.js +6 -0
  327. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/recent-items/map.js +5 -0
  328. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/siteWhitelistByRequest/map.js +6 -0
  329. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/siteWhitelistByRequest/reduce.js +1 -0
  330. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/specsByWorkflow/map.js +5 -0
  331. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/stuckElements/map.js +38 -0
  332. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/wmbsInjectStatusByRequest/map.js +12 -0
  333. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/wmbsInjectStatusByRequest/reduce.js +3 -0
  334. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/wmbsUrl/map.js +6 -0
  335. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/wmbsUrl/reduce.js +2 -0
  336. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/wmbsUrlByRequest/map.js +6 -0
  337. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/wmbsUrlByRequest/reduce.js +2 -0
  338. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/workflowSummary/map.js +9 -0
  339. wmglobalqueue-2.3.10rc10.data/data/data/couchapps/WorkQueue/views/workflowSummary/reduce.js +10 -0
  340. wmglobalqueue-2.3.10rc10.dist-info/METADATA +26 -0
  341. wmglobalqueue-2.3.10rc10.dist-info/RECORD +345 -0
  342. wmglobalqueue-2.3.10rc10.dist-info/WHEEL +5 -0
  343. wmglobalqueue-2.3.10rc10.dist-info/licenses/LICENSE +202 -0
  344. wmglobalqueue-2.3.10rc10.dist-info/licenses/NOTICE +16 -0
  345. wmglobalqueue-2.3.10rc10.dist-info/top_level.txt +2 -0
@@ -0,0 +1,772 @@
1
+ #!/usr/bin/env python
2
+ """
3
+ _WMBSHelper_
4
+
5
+ Use WMSpecParser to extract information for creating workflow, fileset, and subscription
6
+ """
7
+
8
+ from builtins import next, str as newstr, bytes, zip, range
9
+ from future.utils import viewitems
10
+
11
+ import logging
12
+ import threading
13
+ from collections import defaultdict
14
+
15
+ from Utils.PythonVersion import PY3
16
+ from Utils.Utilities import encodeUnicodeToBytesConditional
17
+ from WMComponent.DBS3Buffer.DBSBufferDataset import DBSBufferDataset
18
+ from WMComponent.DBS3Buffer.DBSBufferFile import DBSBufferFile
19
+ from WMCore.BossAir.BossAirAPI import BossAirAPI, BossAirException
20
+ from WMCore.DAOFactory import DAOFactory
21
+ from WMCore.DataStructs.File import File as DatastructFile
22
+ from WMCore.DataStructs.LumiList import LumiList
23
+ from WMCore.DataStructs.Run import Run
24
+ from WMCore.JobStateMachine.ChangeState import ChangeState
25
+ from WMCore.ResourceControl.ResourceControl import ResourceControl
26
+ from WMCore.WMBS.File import File
27
+ from WMCore.WMBS.Fileset import Fileset
28
+ from WMCore.WMBS.Job import Job
29
+ from WMCore.WMBS.Subscription import Subscription
30
+ from WMCore.WMBS.Workflow import Workflow
31
+ from WMCore.WMConnectionBase import WMConnectionBase
32
+ from WMCore.WMException import WMException
33
+ from WMCore.WMRuntime.SandboxCreator import SandboxCreator
34
+
35
+
36
+ def wmbsSubscriptionStatus(logger, dbi, conn, transaction):
37
+ """
38
+ Function to return status of wmbs subscriptions
39
+ """
40
+ daoFactory = DAOFactory(package='WMCore.WMBS', logger=logger, dbinterface=dbi)
41
+ action = daoFactory(classname='Monitoring.SubscriptionStatus')
42
+ return action.execute(conn=conn, transaction=transaction)
43
+
44
+
45
+ class WorkQueueWMBSException(WMException):
46
+ """
47
+ Dummy exception class for exceptions raised
48
+ in WMBS Helper.
49
+
50
+ TODO: Do something useful
51
+
52
+ """
53
+
54
+ pass
55
+
56
+
57
+ def killWorkflow(workflowName, jobCouchConfig, bossAirConfig=None):
58
+ """
59
+ _killWorkflow_
60
+
61
+ Kill a workflow that is already executing inside the agent. This will
62
+ mark all incomplete jobs as failed and files that belong to all
63
+ non-cleanup and non-logcollect subscriptions as failed. The name of the
64
+ JSM couch database and the URL to the database must be passed in as well
65
+ so the state transitions are logged.
66
+ """
67
+ myThread = threading.currentThread()
68
+ daoFactory = DAOFactory(package="WMCore.WMBS",
69
+ logger=myThread.logger,
70
+ dbinterface=myThread.dbi)
71
+ killFilesAction = daoFactory(classname="Subscriptions.KillWorkflow")
72
+ killJobsAction = daoFactory(classname="Jobs.KillWorkflow")
73
+
74
+ killFilesAction.execute(workflowName=workflowName,
75
+ conn=myThread.transaction.conn)
76
+
77
+ liveJobs = killJobsAction.execute(workflowName=workflowName,
78
+ conn=myThread.transaction.conn)
79
+
80
+ changeState = ChangeState(jobCouchConfig)
81
+
82
+ # Deal with any jobs that are running in the batch system
83
+ # only works if we can start the API
84
+ if bossAirConfig:
85
+ bossAir = BossAirAPI(config=bossAirConfig)
86
+ killableJobs = []
87
+ for liveJob in liveJobs:
88
+ if liveJob["state"].lower() == 'executing':
89
+ # Then we need to kill this on the batch system
90
+ liveWMBSJob = Job(id=liveJob["id"])
91
+ liveWMBSJob.update(liveJob)
92
+ killableJobs.append(liveJob)
93
+ # Now kill them
94
+ try:
95
+ logging.info("Killing %d jobs for workflow: %s", len(killableJobs), workflowName)
96
+ bossAir.kill(jobs=killableJobs, workflowName=workflowName)
97
+ except BossAirException as ex:
98
+ errMsg = "Error while trying to kill running jobs in workflow. Error: %s" % str(ex)
99
+ logging.exception(errMsg)
100
+ # But continue; we need to kill the jobs in the master
101
+ # the batch system will have to take care of itself.
102
+
103
+ liveWMBSJobs = defaultdict(list)
104
+ for liveJob in liveJobs:
105
+ if liveJob["state"] == "killed":
106
+ # Then we've killed it already
107
+ continue
108
+ liveWMBSJob = Job(id=liveJob["id"])
109
+ liveWMBSJob.update(liveJob)
110
+ liveWMBSJobs[liveJob["state"]].append(liveWMBSJob)
111
+
112
+ for state, jobsByState in viewitems(liveWMBSJobs):
113
+ if len(jobsByState) > 100 and state != "executing":
114
+ # if there are to many jobs skip the couch and dashboard update
115
+ # TODO: couch and dashboard need to be updated or parallel.
116
+ changeState.check("killed", state)
117
+ changeState.persist(jobsByState, "killed", state)
118
+ else:
119
+ changeState.propagate(jobsByState, "killed", state)
120
+ return
121
+
122
+
123
+ def freeSlots(multiplier=1.0, minusRunning=False, allowedStates=None, knownCmsSites=None):
124
+ """
125
+ Get free resources from wmbs.
126
+
127
+ Specify multiplier to apply a ratio to the actual numbers.
128
+ minusRunning control if running jobs should be counted
129
+ """
130
+ allowedStates = allowedStates or ['Normal']
131
+ rc_sites = ResourceControl().listThresholdsForCreate()
132
+ thresholds = defaultdict(lambda: 0)
133
+ jobCounts = defaultdict(dict)
134
+ for name, site in viewitems(rc_sites):
135
+ if not site.get('cms_name'):
136
+ logging.warning("Not fetching work for %s, cms_name not defined", name)
137
+ continue
138
+ if knownCmsSites and site['cms_name'] not in knownCmsSites:
139
+ logging.warning(
140
+ "%s doesn't appear to be a known cms site, work may fail to be acquired for it", site['cms_name'])
141
+ if site['state'] not in allowedStates:
142
+ continue
143
+ slots = site['total_slots']
144
+ thresholds[site['cms_name']] += (slots * multiplier)
145
+ if minusRunning:
146
+ jobCounts[site['cms_name']] = dict(
147
+ (k, jobCounts[site['cms_name']].get(k, 0) + site['pending_jobs'].get(k, 0))
148
+ for k in site['pending_jobs'])
149
+
150
+ return dict(thresholds), dict(jobCounts)
151
+
152
+
153
+ class WMBSHelper(WMConnectionBase):
154
+ """
155
+ _WMBSHelper_
156
+
157
+ Interface between the WorkQueue and WMBS.
158
+ """
159
+
160
+ def __init__(self, wmSpec, taskName, blockName=None, mask=None,
161
+ cachepath='.', commonLocation=None):
162
+ """
163
+ _init_
164
+
165
+ Initialize DAOs and other things needed.
166
+ """
167
+ self.block = blockName
168
+ self.mask = mask
169
+ self.wmSpec = wmSpec
170
+ self.topLevelTask = wmSpec.getTask(taskName)
171
+ self.cachepath = cachepath
172
+ self.isDBS = True
173
+
174
+ self.topLevelFileset = None
175
+ self.topLevelSubscription = None
176
+ self.topLevelTaskDBSBufferId = None
177
+ self.commonLocation = commonLocation or []
178
+
179
+ self.mergeOutputMapping = {}
180
+
181
+ # Initiate the pieces you need to run your own DAOs
182
+ WMConnectionBase.__init__(self, "WMCore.WMBS")
183
+ myThread = threading.currentThread()
184
+ self.dbsDaoFactory = DAOFactory(package="WMComponent.DBS3Buffer",
185
+ logger=myThread.logger,
186
+ dbinterface=myThread.dbi)
187
+
188
+ # DAOs from WMBS for file commit
189
+ self.setParentage = self.daofactory(classname="Files.SetParentage")
190
+ self.setFileLocation = self.daofactory(classname="Files.SetLocationForWorkQueue")
191
+ self.setFileAddChecksum = self.daofactory(classname="Files.AddChecksumByLFN")
192
+ self.addFileAction = self.daofactory(classname="Files.Add")
193
+ self.addToFileset = self.daofactory(classname="Files.AddDupsToFileset")
194
+ self.getLocationInfo = self.daofactory(classname="Locations.GetSiteInfo")
195
+
196
+ # DAOs from DBSBuffer
197
+ self.dbsCreateFiles = self.dbsDaoFactory(classname="DBSBufferFiles.Add")
198
+ self.dbsSetLocation = self.dbsDaoFactory(classname="DBSBufferFiles.SetLocationByLFN")
199
+ self.dbsInsertLocation = self.dbsDaoFactory(classname="DBSBufferFiles.AddLocation")
200
+ self.dbsSetChecksum = self.dbsDaoFactory(classname="DBSBufferFiles.AddChecksumByLFN")
201
+ self.dbsInsertWorkflow = self.dbsDaoFactory(classname="InsertWorkflow")
202
+
203
+ # Added for file creation bookkeeping
204
+ self.dbsFilesToCreate = set()
205
+ self.wmbsFilesToCreate = set()
206
+ self.insertedBogusDataset = -1
207
+
208
+ return
209
+
210
+ def createSandbox(self):
211
+ """Create the runtime sandbox"""
212
+ sandboxCreator = SandboxCreator()
213
+ sandboxCreator.makeSandbox(self.cachepath, self.wmSpec)
214
+
215
+ def createTopLevelFileset(self, topLevelFilesetName=None):
216
+ """
217
+ _createTopLevelFileset_
218
+
219
+ Create the top level fileset for the workflow. If the name of the top
220
+ level fileset is not given create one.
221
+ """
222
+ if topLevelFilesetName is None:
223
+ filesetName = ("%s-%s" % (self.wmSpec.name(),
224
+ self.wmSpec.getTopLevelTask()[0].name()))
225
+ if self.block:
226
+ filesetName += "-%s" % self.block
227
+ if self.mask:
228
+ from hashlib import md5
229
+ mask_string = ",".join(["%s=%s" % (x, self.mask[x]) for x in sorted(self.mask)])
230
+ mask_string = encodeUnicodeToBytesConditional(mask_string, condition=PY3)
231
+ filesetName += "-%s" % md5(mask_string).hexdigest()
232
+ else:
233
+ filesetName = topLevelFilesetName
234
+
235
+ self.topLevelFileset = Fileset(filesetName)
236
+ self.topLevelFileset.create()
237
+ return
238
+
239
+ def outputFilesetName(self, task, outputModuleName, dataTier=''):
240
+ """
241
+ _outputFilesetName_
242
+
243
+ Generate an output fileset name for the given task, output module and data tier.
244
+ """
245
+ if task.taskType() == "Merge":
246
+ outputFilesetName = "%s/merged-%s%s" % (task.getPathName(),
247
+ outputModuleName, dataTier)
248
+ else:
249
+ outputFilesetName = "%s/unmerged-%s%s" % (task.getPathName(),
250
+ outputModuleName, dataTier)
251
+
252
+ return outputFilesetName
253
+
254
+ def createSubscription(self, task, fileset, alternativeFilesetClose=False):
255
+ """
256
+ _createSubscription_
257
+
258
+ Create subscriptions in the database.
259
+ This includes workflows in WMBS and DBSBuffer, output maps, datasets
260
+ and phedex subscriptions, and filesets for each task below and including
261
+ the given task.
262
+ """
263
+ self._createSubscriptionsInWMBS(task, fileset, alternativeFilesetClose)
264
+
265
+ self._createWorkflowsInDBSBuffer()
266
+ self._createDatasetSubscriptionsInDBSBuffer()
267
+
268
+ return
269
+
270
+ def _createSubscriptionsInWMBS(self, task, fileset, alternativeFilesetClose=False,
271
+ createSandbox=True):
272
+ """
273
+ __createSubscriptionsInWMBS_
274
+
275
+ Create subscriptions in WMBS for all the tasks in the spec. This
276
+ includes filesets, workflows and the output map for each task.
277
+ :param createSandbox: boolean flag to skip (re-)creation of the workload sandbox
278
+ """
279
+ # create runtime sandbox for workflow
280
+ if createSandbox:
281
+ self.createSandbox()
282
+
283
+ # FIXME: Let workflow put in values if spec is missing them
284
+ workflow = Workflow(spec=self.wmSpec.specUrl(), owner=self.wmSpec.getOwner()["name"],
285
+ dn=self.wmSpec.getOwner().get("dn", "unknown"),
286
+ group=self.wmSpec.getOwner().get("group", "unknown"),
287
+ owner_vogroup=self.wmSpec.getOwner().get("vogroup", "DEFAULT"),
288
+ owner_vorole=self.wmSpec.getOwner().get("vorole", "DEFAULT"),
289
+ name=self.wmSpec.name(), task=task.getPathName(),
290
+ wfType=self.wmSpec.getDashboardActivity(),
291
+ alternativeFilesetClose=alternativeFilesetClose,
292
+ priority=self.wmSpec.priority())
293
+ workflow.create()
294
+
295
+ subscription = Subscription(fileset=fileset, workflow=workflow,
296
+ split_algo=task.jobSplittingAlgorithm(),
297
+ type=task.getPrimarySubType())
298
+ subscription.create()
299
+
300
+ ### FIXME: I'm pretty sure we can improve how we handle this site white/black list
301
+ for site in task.siteWhitelist():
302
+ subscription.addWhiteBlackList([{"site_name": site, "valid": True}])
303
+
304
+ for site in task.siteBlacklist():
305
+ subscription.addWhiteBlackList([{"site_name": site, "valid": False}])
306
+
307
+ if self.topLevelSubscription is None:
308
+ self.topLevelSubscription = subscription
309
+ logging.info("Top level subscription %s created for %s", subscription["id"], self.wmSpec.name())
310
+ else:
311
+ logging.info("Child subscription %s created for %s", subscription["id"], self.wmSpec.name())
312
+
313
+ outputModules = task.getOutputModulesForTask()
314
+ ignoredOutputModules = task.getIgnoredOutputModulesForTask()
315
+ for outputModule in outputModules:
316
+ for outputModuleName in sorted(outputModule.listSections_()):
317
+ if outputModuleName in ignoredOutputModules:
318
+ msg = "%s has %s as IgnoredOutputModule, skipping fileset creation."
319
+ logging.info(msg, task.getPathName(), outputModuleName)
320
+ continue
321
+ dataTier = getattr(getattr(outputModule, outputModuleName), "dataTier", '')
322
+ filesetName = self.outputFilesetName(task, outputModuleName, dataTier)
323
+ outputFileset = Fileset(filesetName)
324
+ outputFileset.create()
325
+ outputFileset.markOpen(True)
326
+ mergedOutputFileset = None
327
+
328
+ for childTask in task.childTaskIterator():
329
+ if childTask.data.input.outputModule == outputModuleName:
330
+ childDatatier = getattr(childTask.data.input, 'dataTier', '')
331
+ if childTask.taskType() in ["Cleanup", "Merge"] and childDatatier != dataTier:
332
+ continue
333
+ elif childTask.taskType() == "Merge" and childDatatier == dataTier:
334
+ filesetName = self.outputFilesetName(childTask, "Merged", dataTier)
335
+ mergedOutputFileset = Fileset(filesetName)
336
+ mergedOutputFileset.create()
337
+ mergedOutputFileset.markOpen(True)
338
+
339
+ primaryDataset = getattr(getattr(outputModule, outputModuleName), "primaryDataset", None)
340
+ if primaryDataset is not None:
341
+ self.mergeOutputMapping[mergedOutputFileset.id] = primaryDataset
342
+
343
+ self._createSubscriptionsInWMBS(childTask, outputFileset,
344
+ alternativeFilesetClose, createSandbox=False)
345
+
346
+ if mergedOutputFileset is None:
347
+ workflow.addOutput(outputModuleName + dataTier, outputFileset,
348
+ outputFileset)
349
+ else:
350
+ workflow.addOutput(outputModuleName + dataTier, outputFileset,
351
+ mergedOutputFileset)
352
+
353
+ return
354
+
355
+ def addMCFakeFile(self):
356
+ """Add a fake file for wmbs to run production over"""
357
+ needed = ['FirstEvent', 'FirstLumi', 'FirstRun', 'LastEvent', 'LastLumi', 'LastRun']
358
+ for key in needed:
359
+ if self.mask and self.mask.get(key) is None:
360
+ msg = 'Invalid value "%s" for %s' % (self.mask.get(key), key)
361
+ raise WorkQueueWMBSException(msg)
362
+
363
+ locations = set()
364
+ siteInfo = self.getLocationInfo.execute(conn=self.getDBConn(),
365
+ transaction=self.existingTransaction())
366
+ for site in siteInfo:
367
+ locations.update(set(site['pnn']) & set(self.commonLocation))
368
+
369
+ if not locations:
370
+ msg = 'No locations to inject Monte Carlo work to, unable to proceed'
371
+ raise WorkQueueWMBSException(msg)
372
+ mcFakeFileName = "MCFakeFile-%s" % self.topLevelFileset.name
373
+ wmbsFile = File(lfn=mcFakeFileName,
374
+ first_event=self.mask['FirstEvent'],
375
+ last_event=self.mask['LastEvent'],
376
+ events=self.mask['LastEvent'] - self.mask['FirstEvent'] + 1, # inclusive range
377
+ locations=locations,
378
+ merged=False, # merged causes dbs parentage relation
379
+ )
380
+
381
+ if self.mask:
382
+ lumis = list(range(self.mask['FirstLumi'], self.mask['LastLumi'] + 1)) # inclusive range
383
+ wmbsFile.addRun(Run(self.mask['FirstRun'], *lumis)) # assume run number static
384
+ else:
385
+ wmbsFile.addRun(Run(1, 1))
386
+
387
+ wmbsFile['inFileset'] = True # file is not a parent
388
+
389
+ logging.debug("WMBS MC Fake File: %s on Location: %s", wmbsFile['lfn'], wmbsFile['newlocations'])
390
+
391
+ self.wmbsFilesToCreate.add(wmbsFile)
392
+
393
+ totalFiles = self.topLevelFileset.addFilesToWMBSInBulk(self.wmbsFilesToCreate,
394
+ self.wmSpec.name(),
395
+ isDBS=self.isDBS)
396
+
397
+ self.topLevelFileset.markOpen(False)
398
+ return totalFiles
399
+
400
+ def createSubscriptionAndAddFiles(self, block):
401
+ """
402
+ _createSubscriptionAndAddFiles_
403
+
404
+ Create the subscription and add files at one time to
405
+ put everything in one transaction.
406
+
407
+ """
408
+ existingTransaction = self.beginTransaction()
409
+
410
+ self.createTopLevelFileset()
411
+ try:
412
+ self.createSubscription(self.topLevelTask, self.topLevelFileset)
413
+ except Exception as ex:
414
+ myThread = threading.currentThread()
415
+ myThread.transaction.rollback()
416
+ logging.exception("Failed to create subscription. Error: %s", str(ex))
417
+ raise ex
418
+
419
+ if block:
420
+ logging.info('"%s" Injecting block %s (%d files) into wmbs.',
421
+ self.wmSpec.name(), self.block, len(block['Files']))
422
+ addedFiles = self.addFiles(block)
423
+ else:
424
+ # For MC case
425
+ logging.info('"%s" Injecting production %s:%s:%s - %s:%s:%s (run:lumi:event) into wmbs',
426
+ self.wmSpec.name(),
427
+ self.mask['FirstRun'], self.mask['FirstLumi'], self.mask['FirstEvent'],
428
+ self.mask['LastRun'], self.mask['LastLumi'], self.mask['LastEvent'])
429
+ addedFiles = self.addMCFakeFile()
430
+
431
+ self.commitTransaction(existingTransaction)
432
+ logging.info("Transaction committed: %s, for %s", not existingTransaction, self.wmSpec.name())
433
+
434
+ # Now that we've created those files, clear the list
435
+ self.dbsFilesToCreate = set()
436
+ self.wmbsFilesToCreate = set()
437
+
438
+ return self.topLevelSubscription, addedFiles
439
+
440
+ def addFiles(self, block):
441
+ """
442
+ _addFiles_
443
+
444
+ create wmbs files from given dbs block.
445
+ as well as run lumi update
446
+ """
447
+ if self.topLevelTask.getInputACDC():
448
+ self.isDBS = False
449
+ logging.info('Adding ACDC files into WMBS for %s', self.wmSpec.name())
450
+ for acdcFile in self.validFiles(block['Files']):
451
+ self._addACDCFileToWMBSFile(acdcFile)
452
+ else:
453
+ self.isDBS = True
454
+ blockPNNs = block['PhEDExNodeNames']
455
+ logging.info('Adding files into WMBS for %s with PNNs: %s', self.wmSpec.name(), blockPNNs)
456
+ for dbsFile in self.validFiles(block['Files']):
457
+ self._addDBSFileToWMBSFile(dbsFile, blockPNNs)
458
+
459
+ # Add files to WMBS
460
+ logging.info('Inserting %d files in bulk into WMBS for %s', len(self.wmbsFilesToCreate),
461
+ self.wmSpec.name())
462
+ totalFiles = self.topLevelFileset.addFilesToWMBSInBulk(self.wmbsFilesToCreate,
463
+ self.wmSpec.name(),
464
+ isDBS=self.isDBS)
465
+ # Add files to DBSBuffer
466
+ logging.info('Inserting %d files in bulk into DBSBuffer for %s', len(self.dbsFilesToCreate),
467
+ self.wmSpec.name())
468
+ self._createFilesInDBSBuffer()
469
+
470
+ # DBS blocks are always closed, so mark fileset as closed as well
471
+ self.topLevelFileset.markOpen(False)
472
+ return totalFiles
473
+
474
+ def getMergeOutputMapping(self):
475
+ """
476
+ _getMergeOutputMapping_
477
+
478
+ retrieves the relationship between primary
479
+ dataset and merge output fileset ids for
480
+ all merge tasks created
481
+ """
482
+ return self.mergeOutputMapping
483
+
484
+ def _createWorkflowsInDBSBuffer(self):
485
+ """
486
+ _createWorkflowsInDBSBuffer_
487
+
488
+ Register workflow information and settings in dbsbuffer for all
489
+ tasks that will potentially produce any output in this spec.
490
+ """
491
+ existingTransaction = self.beginTransaction()
492
+
493
+ for task in self.wmSpec.listOutputProducingTasks():
494
+ workflow_id = self.dbsInsertWorkflow.execute(self.wmSpec.name(), task,
495
+ self.wmSpec.getBlockCloseMaxWaitTime(),
496
+ self.wmSpec.getBlockCloseMaxFiles(),
497
+ self.wmSpec.getBlockCloseMaxEvents(),
498
+ self.wmSpec.getBlockCloseMaxSize(),
499
+ conn=self.getDBConn(), transaction=self.existingTransaction())
500
+ if task == self.topLevelTask.getPathName():
501
+ self.topLevelTaskDBSBufferId = workflow_id
502
+
503
+ self.commitTransaction(existingTransaction)
504
+
505
+ def _createDatasetSubscriptionsInDBSBuffer(self):
506
+ """
507
+ _createDatasetSubscriptionsInDBSBuffer_
508
+
509
+ Insert the subscriptions defined in the workload for the output
510
+ datasets with the different options.
511
+ """
512
+ existingTransaction = self.beginTransaction()
513
+
514
+ subInfo = self.wmSpec.getSubscriptionInformation()
515
+ for dataset in subInfo:
516
+ dbsDataset = DBSBufferDataset(path=dataset)
517
+ dbsDataset.create()
518
+ dbsDataset.addSubscription(subInfo[dataset])
519
+ self.commitTransaction(existingTransaction)
520
+ return
521
+
522
+ def _createFilesInDBSBuffer(self):
523
+ """
524
+ _createFilesInDBSBuffer_
525
+
526
+ It does the actual job of creating things in DBSBuffer
527
+
528
+ """
529
+ if not self.dbsFilesToCreate:
530
+ # Whoops, nothing to do!
531
+ return
532
+
533
+ dbsFileTuples = set()
534
+ dbsFileLoc = []
535
+ dbsCksumBinds = []
536
+ locationsToAdd = set()
537
+
538
+ # The first thing we need to do is add the datasetAlgo
539
+ # Assume all files in a pass come from one datasetAlgo?
540
+ if self.insertedBogusDataset == -1:
541
+ self.insertedBogusDataset = next(iter(self.dbsFilesToCreate)).insertDatasetAlgo()
542
+
543
+ for dbsFile in self.dbsFilesToCreate:
544
+ # Append a tuple in the format specified by DBSBufferFiles.Add
545
+ # Also run insertDatasetAlgo
546
+
547
+ lfn = dbsFile['lfn']
548
+ selfChecksums = dbsFile['checksums']
549
+
550
+ newTuple = (lfn, dbsFile['size'], dbsFile['events'],
551
+ self.insertedBogusDataset, dbsFile['status'],
552
+ self.topLevelTaskDBSBufferId, dbsFile['in_phedex'])
553
+
554
+ dbsFileTuples.add(newTuple)
555
+
556
+ if len(dbsFile['newlocations']) < 1:
557
+ msg = ''
558
+ msg += "File created without any locations!\n"
559
+ msg += "File lfn: %s\n" % (lfn)
560
+ msg += "Rejecting this group of files in DBS!\n"
561
+ logging.error(msg)
562
+ raise WorkQueueWMBSException(msg)
563
+
564
+ for jobLocation in dbsFile['newlocations']:
565
+ locationsToAdd.add(jobLocation)
566
+ dbsFileLoc.append({'lfn': lfn, 'pnn': jobLocation})
567
+
568
+ if selfChecksums:
569
+ # If we have checksums we have to create a bind
570
+ # For each different checksum
571
+ for entry in selfChecksums:
572
+ dbsCksumBinds.append({'lfn': lfn, 'cksum': selfChecksums[entry],
573
+ 'cktype': entry})
574
+
575
+ self.dbsInsertLocation.execute(siteName=locationsToAdd,
576
+ conn=self.getDBConn(),
577
+ transaction=self.existingTransaction())
578
+
579
+ self.dbsCreateFiles.execute(files=dbsFileTuples,
580
+ conn=self.getDBConn(),
581
+ transaction=self.existingTransaction())
582
+
583
+ self.dbsSetLocation.execute(binds=dbsFileLoc,
584
+ conn=self.getDBConn(),
585
+ transaction=self.existingTransaction())
586
+
587
+ if len(dbsCksumBinds) > 0:
588
+ self.dbsSetChecksum.execute(bulkList=dbsCksumBinds,
589
+ conn=self.getDBConn(),
590
+ transaction=self.existingTransaction())
591
+
592
+ return
593
+
594
+ def _addToDBSBuffer(self, dbsFile, checksums, locations):
595
+ """
596
+ This step is just for increase the performance for
597
+ Accountant doesn't neccessary to check the parentage
598
+ """
599
+ dbsBuffer = DBSBufferFile(lfn=dbsFile["LogicalFileName"],
600
+ size=dbsFile["FileSize"],
601
+ events=dbsFile["NumberOfEvents"],
602
+ checksums=checksums,
603
+ locations=locations,
604
+ status="GLOBAL",
605
+ inPhedex=1)
606
+ dbsBuffer.setDatasetPath('bogus')
607
+ dbsBuffer.setAlgorithm(appName="cmsRun", appVer="Unknown",
608
+ appFam="Unknown", psetHash="Unknown",
609
+ configContent="Unknown")
610
+
611
+ self.dbsFilesToCreate.add(dbsBuffer)
612
+ return
613
+
614
+ def _addDBSFileToWMBSFile(self, dbsFile, storageElements, inFileset=True):
615
+ """
616
+ There are two assumptions made to make this method behave properly,
617
+ 1. DBS returns only one level of ParentList.
618
+ If DBS returns multiple level of parentage, it will be still get handled.
619
+ However that might not be what we wanted. In that case, restrict to one level.
620
+ 2. Assumes parents files are in the same location as child files.
621
+ This is not True in general case, but workquue should only select work only
622
+ where child and parent files are in the same location
623
+ """
624
+ # TODO get dbsFile with lumi event information
625
+ wmbsParents = []
626
+ dbsFile.setdefault("ParentList", [])
627
+ for parent in dbsFile["ParentList"]:
628
+ wmbsParents.append(self._addDBSFileToWMBSFile(parent,
629
+ storageElements, inFileset=False))
630
+
631
+ checksums = {}
632
+ if dbsFile.get('Checksum'):
633
+ checksums['cksum'] = dbsFile['Checksum']
634
+ if dbsFile.get('Adler32'):
635
+ checksums['adler32'] = dbsFile['Adler32']
636
+
637
+ wmbsFile = File(lfn=dbsFile["LogicalFileName"],
638
+ size=dbsFile["FileSize"],
639
+ events=dbsFile["NumberOfEvents"],
640
+ checksums=checksums,
641
+ # TODO: need to get list of parent lfn
642
+ parents=wmbsParents,
643
+ locations=set(storageElements))
644
+
645
+ for lumi in dbsFile['LumiList']:
646
+ if isinstance(lumi['LumiSectionNumber'], list):
647
+ lumiSecList = (list(zip(lumi['LumiSectionNumber'], lumi['EventCount']))
648
+ if 'EventCount' in lumi else lumi['LumiSectionNumber'])
649
+ run = Run(lumi['RunNumber'], lumiSecList)
650
+ else:
651
+ lumiSecTuple = ((lumi['LumiSectionNumber'], lumi['EventCount'])
652
+ if 'EventCount' in lumi else lumi['LumiSectionNumber'])
653
+ run = Run(lumi['RunNumber'], lumiSecTuple)
654
+ wmbsFile.addRun(run)
655
+
656
+ self._addToDBSBuffer(dbsFile, checksums, storageElements)
657
+
658
+ logging.debug("WMBS File: %s on Location: %s", wmbsFile['lfn'], wmbsFile['newlocations'])
659
+
660
+ wmbsFile['inFileset'] = bool(inFileset)
661
+ self.wmbsFilesToCreate.add(wmbsFile)
662
+
663
+ return wmbsFile
664
+
665
+ def _convertACDCFileToDBSFile(self, acdcFile):
666
+ """
667
+ convert ACDCFiles to dbs file format
668
+ """
669
+ dbsFile = {}
670
+ dbsFile["LogicalFileName"] = acdcFile["lfn"]
671
+ dbsFile["FileSize"] = acdcFile["size"]
672
+ dbsFile["NumberOfEvents"] = acdcFile["events"]
673
+ return dbsFile
674
+
675
+ def _addACDCFileToWMBSFile(self, acdcFile, inFileset=True):
676
+ """
677
+ adds the ACDC files into WMBS database
678
+ """
679
+ wmbsParents = []
680
+ # If file is merged, then it will be the parent of whatever output that
681
+ # process this job (it twists my mind!). Meaning, block below can be skipped
682
+ if int(acdcFile.get("merged", 0)) == 0 and acdcFile["parents"]:
683
+ # set the parentage for all the unmerged parents
684
+ for parent in acdcFile["parents"]:
685
+ if parent.startswith("/store/unmerged/") or parent.startswith("MCFakeFile"):
686
+ logging.warning("WMBS ACDC skipped parent invalid file: %s", parent)
687
+ continue
688
+ logging.debug("WMBS ACDC Parent File: %s", parent)
689
+ parent = self._addACDCFileToWMBSFile(DatastructFile(lfn=parent,
690
+ locations=acdcFile["locations"],
691
+ merged=True),
692
+ inFileset=False)
693
+ wmbsParents.append(parent)
694
+
695
+ # pass empty check sum since it won't be updated to dbs anyway
696
+ checksums = {}
697
+ wmbsFile = File(lfn=str(acdcFile["lfn"]),
698
+ size=acdcFile["size"],
699
+ events=acdcFile["events"],
700
+ first_event=acdcFile.get('first_event', 0),
701
+ last_event=acdcFile.get('last_event', 0),
702
+ checksums=checksums,
703
+ parents=wmbsParents,
704
+ locations=acdcFile["locations"],
705
+ merged=acdcFile.get('merged', True))
706
+
707
+ ## TODO need to get the lumi lists
708
+ for run in acdcFile['runs']:
709
+ wmbsFile.addRun(run)
710
+
711
+ if not acdcFile["lfn"].startswith("/store/unmerged") or wmbsParents:
712
+ # only add to DBSBuffer if is not unmerged file or it has parents.
713
+ dbsFile = self._convertACDCFileToDBSFile(acdcFile)
714
+ self._addToDBSBuffer(dbsFile, checksums, acdcFile["locations"])
715
+
716
+ logging.debug("WMBS ACDC File: %s on Location: %s", wmbsFile['lfn'], wmbsFile['newlocations'])
717
+
718
+ wmbsFile['inFileset'] = bool(inFileset)
719
+
720
+ self.wmbsFilesToCreate.add(wmbsFile)
721
+
722
+ return wmbsFile
723
+
724
+ def validFiles(self, files):
725
+ """
726
+ Apply lumi mask and or run white/black list and return files which have
727
+ one or more of the requested lumis
728
+ """
729
+ runWhiteList = self.topLevelTask.inputRunWhitelist()
730
+ runBlackList = self.topLevelTask.inputRunBlacklist()
731
+ lumiMask = self.topLevelTask.getLumiMask()
732
+
733
+ blackMask = None
734
+ if lumiMask: # We have a lumiMask, so use it and modify with run white/black list
735
+ if runWhiteList:
736
+ lumiMask.selectRuns(runWhiteList)
737
+ if runBlackList:
738
+ lumiMask.removeRuns(runBlackList)
739
+ elif runWhiteList: # We have a run whitelist, subtract off blacklist
740
+ lumiMask = LumiList(runs=runWhiteList)
741
+ if runBlackList: # We only have a blacklist, so make a black mask out of it instead
742
+ lumiMask.removeRuns(runBlackList)
743
+ else:
744
+ lumiMask = None
745
+ if runBlackList:
746
+ blackMask = LumiList(runs=runBlackList)
747
+
748
+ results = []
749
+ for f in files:
750
+ if isinstance(f, (newstr, bytes)) or "LumiList" not in f:
751
+ results.append(f)
752
+ continue
753
+
754
+ # Create a LumiList from the WMBS info
755
+ runLumis = {}
756
+ for x in f['LumiList']:
757
+ if x['RunNumber'] in runLumis:
758
+ runLumis[x['RunNumber']].extend(x['LumiSectionNumber'])
759
+ else:
760
+ runLumis[x['RunNumber']] = x['LumiSectionNumber']
761
+ fileLumiList = LumiList(runsAndLumis=runLumis)
762
+
763
+ if lumiMask:
764
+ if fileLumiList & lumiMask: # At least one lumi from file is in lumiMask
765
+ results.append(f)
766
+ elif blackMask:
767
+ if fileLumiList - blackMask: # At least one lumi from file is not in blackMask
768
+ results.append(f)
769
+ else: # There is effectively no mask
770
+ results.append(f)
771
+
772
+ return results