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,66 @@
1
+ #!/usr/bin/env python
2
+ """
3
+ Basic interface to HTTPS requests using ssl object managers, for python >= 2.7.9.
4
+ See usage example in:
5
+ src/python/WMCore/WMSpec/Steps/Executors/DQMUpload.py
6
+ """
7
+ from __future__ import print_function, division
8
+
9
+ import logging
10
+ import ssl
11
+ try:
12
+ # python2
13
+ import urllib2
14
+ import httplib
15
+ HTTPSHandler = urllib2.HTTPSHandler
16
+ HTTPSConnection = httplib.HTTPSConnection
17
+ except:
18
+ # python3
19
+ import urllib.request
20
+ import http.client
21
+ HTTPSHandler = urllib.request.HTTPSHandler
22
+ HTTPSConnection = http.client.HTTPSConnection
23
+
24
+
25
+ class HTTPSAuthHandler(HTTPSHandler):
26
+ """
27
+ HTTPS authentication class to provide a ssl context with the certificates.
28
+ """
29
+ def __init__(self, key=None, cert=None, capath='/etc/grid-security/certificates/', level=0):
30
+ self.logger = logging.getLogger(__name__)
31
+ if cert:
32
+ # then create a default ssl context manager to carry the credentials.
33
+ # It also loads the default CA certificates
34
+ self.ctx = ssl.create_default_context()
35
+ self.ctx.load_cert_chain(cert, keyfile=key)
36
+ self.ctx.load_verify_locations(None, capath)
37
+
38
+ self.logger.info("Found %d default trusted CA certificates.", len(self.ctx.get_ca_certs()))
39
+ ### DEBUG start ###
40
+ #for ca in self.ctx.get_ca_certs():
41
+ # if 'CERN' in str(ca['subject']):
42
+ # print(" %s" % str(ca['subject']))
43
+ ### DEBUG end ###
44
+ self.logger.info("SSL context manager created with the following settings:")
45
+ self.logger.info(" check_hostname : %s", self.ctx.check_hostname) # default to True
46
+ self.logger.info(" options : %s", self.ctx.options) # default to 2197947391
47
+ self.logger.info(" protocol : %s", self.ctx.protocol) # default to 2 (PROTOCOL_SSLv23)
48
+ self.logger.info(" verify_flags : %s", self.ctx.verify_flags) # default to 0 (VERIFY_DEFAULT)
49
+ self.logger.info(" verify_mode : %s", self.ctx.verify_mode) # default to 2 (CERT_REQUIRED)
50
+ HTTPSHandler.__init__(self, debuglevel=level, context=self.ctx)
51
+ else:
52
+ self.logger.info("Certificate not provided for HTTPSHandler")
53
+ HTTPSHandler.__init__(self, debuglevel=level)
54
+
55
+ def get_connection(self, host, **kwargs):
56
+ if self.ctx:
57
+ return HTTPSConnection(host, context=self.ctx, **kwargs)
58
+ return HTTPSConnection(host)
59
+
60
+ def https_open(self, req):
61
+ """
62
+ Overwrite the default https_open.
63
+ """
64
+ self.logger.debug("%s method to %s", req.get_method(), req.get_full_url())
65
+ self.logger.debug(" with the following headers: %s", req.headers)
66
+ return self.do_open(self.get_connection, req)
File without changes
@@ -0,0 +1,201 @@
1
+ #!/usr/bin/env python
2
+ """
3
+ LogDB provides functionality to post/search messages into LogDB.
4
+ https://github.com/dmwm/WMCore/issues/5705
5
+ """
6
+ # futures
7
+ from builtins import object
8
+ from future.utils import viewitems
9
+
10
+ from future import standard_library
11
+ standard_library.install_aliases()
12
+
13
+ # standard modules
14
+ import logging
15
+ import re
16
+ import threading
17
+ from collections import defaultdict
18
+ from http.client import HTTPException
19
+
20
+ # project modules
21
+ from WMCore.Lexicon import splitCouchServiceURL
22
+ from WMCore.Services.LogDB.LogDBBackend import LogDBBackend
23
+
24
+
25
+ def getLogDBInstanceFromThread():
26
+ """This function only gets to call when LogDB is instantiated before hand
27
+ All the WMComponentWorkers instatntiate LogDB automatically
28
+ """
29
+ myThread = threading.currentThread()
30
+ if not hasattr(myThread, "logdbClient") or not isinstance(myThread.logdbClient, LogDB):
31
+ # logdb is not set do anything
32
+ return None
33
+ return myThread.logdbClient
34
+
35
+
36
+ class LogDB(object):
37
+ """
38
+ _LogDB_
39
+
40
+ LogDB object - interface to LogDB functionality.
41
+ """
42
+
43
+ def __init__(self, url, identifier, logger=None, **kwds):
44
+ self.logger = logger if logger else logging.getLogger()
45
+ self.url = url if url else 'https://cmsweb.cern.ch/couchdb/wmstats_logdb'
46
+ self.identifier = identifier if identifier else 'unknown'
47
+ self.default_user = "HEARTBEAT"
48
+
49
+ try:
50
+ self.thread_name = kwds.pop('thread_name')
51
+ except KeyError:
52
+ self.thread_name = threading.currentThread().getName()
53
+
54
+ self.user_pat = re.compile(r'^/[a-zA-Z][a-zA-Z0-9/\=\s()\']*\=[a-zA-Z0-9/\=\.\-_/#:\s\']*$')
55
+ self.agent = 0 if self.user_pat.match(self.identifier) else 1
56
+ couch_url, db_name = splitCouchServiceURL(self.url)
57
+ self.backend = LogDBBackend(couch_url, db_name, identifier,
58
+ self.thread_name, agent=self.agent, **kwds)
59
+ self.logger.info(self)
60
+
61
+ def __repr__(self):
62
+ "Return representation for class"
63
+ return "<LogDB(url=%s, identifier=%s, agent=%d)>" \
64
+ % (self.url, self.identifier, self.agent)
65
+
66
+ def post(self, request=None, msg="", mtype="comment"):
67
+ """Post new entry into LogDB for given request"""
68
+ res = 'post-error'
69
+ try:
70
+ if request is None:
71
+ request = self.default_user
72
+ if self.user_pat.match(self.identifier):
73
+ res = self.backend.user_update(request, msg, mtype)
74
+ else:
75
+ res = self.backend.agent_update(request, msg, mtype)
76
+ except HTTPException as ex:
77
+ msg = "Failed to post doc to LogDB. Reason: %s, status: %s" % (ex.reason, ex.status)
78
+ self.logger.error(msg)
79
+ except Exception as exc:
80
+ self.logger.error("LogDBBackend post API failed, error=%s", str(exc))
81
+ self.logger.debug("LogDB post request, res=%s", res)
82
+ return res
83
+
84
+ def get(self, request=None, mtype=None):
85
+ """Retrieve all entries from LogDB for given request"""
86
+ res = []
87
+ try:
88
+ if request is None:
89
+ request = self.default_user
90
+ if self.user_pat.match(self.identifier):
91
+ agent = False
92
+ else:
93
+ agent = True
94
+ for row in self.backend.get(request, mtype, agent=agent).get('rows', []):
95
+ request = row['doc']['request']
96
+ identifier = row['doc']['identifier']
97
+ thr = row['doc']['thr']
98
+ mtype = row['doc']['type']
99
+ for rec in row['doc']['messages']:
100
+ rec.update({'request': request, 'identifier': identifier, 'thr': thr, 'type': mtype})
101
+ res.append(rec)
102
+ except HTTPException as ex:
103
+ msg = "Failed to get doc from LogDB. Reason: %s, status: %s" % (ex.reason, ex.status)
104
+ self.logger.error(msg)
105
+ res = 'get-error'
106
+ except Exception as exc:
107
+ self.logger.error("LogDBBackend get API failed, error=%s", str(exc))
108
+ res = 'get-error'
109
+ self.logger.debug("LogDB get request, res=%s", res)
110
+ return res
111
+
112
+ def get_all_requests(self):
113
+ """Retrieve all entries from LogDB for given request"""
114
+ try:
115
+ results = self.backend.get_all_requests()
116
+ res = []
117
+ for row in results['rows']:
118
+ res.append(row["key"])
119
+ except Exception as exc:
120
+ self.logger.error("LogDBBackend get_all_requests API failed, error=%s", str(exc))
121
+ res = 'get-error'
122
+ self.logger.debug("LogDB get_all_requests request, res=%s", res)
123
+ return res
124
+
125
+ def delete(self, request=None, mtype=None, this_thread=False, agent=True):
126
+ """
127
+ Delete entry in LogDB for given request
128
+ if mtype == None - delete all the log for that request
129
+ mtype != None - only delete specified mtype
130
+ """
131
+ res = 'delete-error'
132
+ try:
133
+ if request is None:
134
+ request = self.default_user
135
+ res = self.backend.delete(request, mtype, this_thread, agent)
136
+ except HTTPException as ex:
137
+ msg = "Failed to delete doc in LogDB. Reason: %s, status: %s" % (ex.reason, ex.status)
138
+ self.logger.error(msg)
139
+ except Exception as ex:
140
+ self.logger.error("LogDBBackend delete API failed, error=%s", str(ex))
141
+ self.logger.debug("LogDB delete request, res=%s", res)
142
+ return res
143
+
144
+ def cleanup(self, thr, backend='local'):
145
+ """Clean-up back-end LogDB"""
146
+ docs = []
147
+ try:
148
+ docs = self.backend.cleanup(thr)
149
+ except Exception as exc:
150
+ self.logger.error('LogDBBackend cleanup API failed, backend=%s, error=%s', backend, str(exc))
151
+ return docs
152
+
153
+ def heartbeat_report(self):
154
+ report = defaultdict(dict)
155
+ if self.user_pat.match(self.identifier):
156
+ self.logger.error("User %s: doesn't allow this function", self.identifier)
157
+ return report
158
+
159
+ for row in self.backend.get(self.default_user, None, agent=True).get('rows', []):
160
+ identifier = row['doc']['identifier']
161
+ # wmstats thread can run in multiple boxed.
162
+ if self.identifier == identifier or identifier.startswith(self.identifier):
163
+ # this will handle wmstats DataCacheUpdate thread with multiple machine
164
+ postfix = identifier.replace(self.identifier, "")
165
+ thr = "%s%s" % (row['doc']['thr'], postfix)
166
+ mtype = row['doc']['type']
167
+ ts = row['doc']['messages'][-1]['ts']
168
+ msg = row['doc']['messages'][-1]['msg']
169
+ if (thr in report) and ('ts' in report[thr]) and ts <= report[thr]['ts']:
170
+ continue
171
+ else:
172
+ report[thr]['type'] = mtype
173
+ report[thr]['msg'] = msg
174
+ report[thr]['ts'] = ts
175
+ return report
176
+
177
+ def _append_down_component_detail(self, report, thr, msg, ts=0, state="error"):
178
+ report['down_components'].append(thr)
179
+ detail = {'name': thr, 'worker_name': thr, 'state': state,
180
+ 'last_error': ts, 'error_message': msg,
181
+ 'pid': 'N/A'}
182
+ report['down_component_detail'].append(detail)
183
+ return
184
+
185
+ def wmstats_down_components_report(self, thread_list):
186
+ report = {}
187
+ report['down_components'] = []
188
+ report['down_component_detail'] = []
189
+
190
+ hbinfo = self.heartbeat_report()
191
+ for thr in thread_list:
192
+ # skip DataCacheUpdate thread. It will have multiple with post fix.
193
+ # i.e. DataCacheUpdate-vocms111
194
+ # TODO, need a better way to check
195
+ if thr != "DataCacheUpdate" and thr not in hbinfo:
196
+ self._append_down_component_detail(report, thr, "Thread not running")
197
+
198
+ for thr, info in viewitems(hbinfo):
199
+ if info['type'] == 'agent-error':
200
+ self._append_down_component_detail(report, thr, info['msg'], info['ts'])
201
+ return report
@@ -0,0 +1,191 @@
1
+ #!/usr/bin/env python
2
+ """
3
+ LogDBBackend
4
+
5
+ Interface to LogDB persistent storage
6
+ """
7
+
8
+ from builtins import object, bytes
9
+
10
+ from Utils.PythonVersion import PY3
11
+ from Utils.Utilities import encodeUnicodeToBytes, encodeUnicodeToBytesConditional
12
+
13
+ # system modules
14
+ import datetime
15
+ import hashlib
16
+ import time
17
+
18
+ # WMCore modules
19
+ from WMCore.Database.CMSCouch import CouchServer, CouchNotFoundError
20
+ from WMCore.Services.LogDB.LogDBExceptions import LogDBError
21
+
22
+ # define full list of supported LogDB types
23
+ LOGDB_MSG_TYPES = ['info', 'error', 'warning', 'comment']
24
+
25
+ def gen_hash(key):
26
+ "Generate hash for given key"
27
+ key = encodeUnicodeToBytes(key) # if key is not unicode, then it is not changed
28
+ if not isinstance(key, bytes):
29
+ raise NotImplementedError
30
+ keyhash = hashlib.md5()
31
+ keyhash.update(encodeUnicodeToBytesConditional(key, condition=PY3))
32
+ return keyhash.hexdigest()
33
+
34
+ def tstamp():
35
+ "Return timestamp with microseconds"
36
+ now = datetime.datetime.now()
37
+ base = str(time.mktime(now.timetuple())).split('.')[0]
38
+ ctime = '%s.%s' % (base, now.microsecond)
39
+ return float(ctime)
40
+
41
+ def clean_entry(doc):
42
+ """Clean document from CouchDB attributes"""
43
+ for attr in ['_rev', '_id']:
44
+ if attr in doc:
45
+ del doc[attr]
46
+ return doc
47
+
48
+ class LogDBBackend(object):
49
+ """
50
+ Represents persistent storage for LogDB
51
+ """
52
+ def __init__(self, db_url, db_name, identifier, thread_name, **kwds):
53
+ self.db_url = db_url
54
+ self.server = CouchServer(db_url)
55
+ self.db_name = db_name
56
+ self.dbid = identifier
57
+ self.thread_name = thread_name
58
+ self.agent = kwds.get('agent', 0)
59
+ self.db = self.server.connectDatabase(db_name, create=False)
60
+ self.design = 'LogDB' # name of design document
61
+ self.view = 'requests' # name of view to look-up requests
62
+ self.tsview = 'tstamp' # name of tsview to look-up requests
63
+ self.threadview = 'logByRequestAndThread'
64
+ self.requestview = 'logByRequest'
65
+
66
+ def deleteDatabase(self):
67
+ """Delete back-end database"""
68
+ if self.db_name in self.server.listDatabases():
69
+ self.server.deleteDatabase(self.db_name)
70
+
71
+ def check(self, request, mtype=None):
72
+ """Check that given request name is valid"""
73
+ # TODO: we may add some logic to check request name, etc.
74
+ if not request:
75
+ raise LogDBError("Request name is empty")
76
+ if mtype and mtype not in LOGDB_MSG_TYPES:
77
+ raise LogDBError("Unsupported message type: '%s', supported types %s" \
78
+ % (mtype, LOGDB_MSG_TYPES))
79
+
80
+ def docid(self, request, mtype):
81
+ """Generate doc id, we use double dash to avoid dashes from thread names"""
82
+ return gen_hash('--'.join((request, self.dbid, self.thread_name, mtype)))
83
+
84
+ def prefix(self, mtype):
85
+ """Generate agent specific prefix for given message type"""
86
+ if self.agent:
87
+ # we add prefix for agent messages, all others will not have this index
88
+ mtype = 'agent-%s' % mtype
89
+ return mtype
90
+
91
+ def agent_update(self, request, msg='', mtype="info"):
92
+ """Update agent info in LogDB for given request"""
93
+ self.check(request, mtype)
94
+ mtype = self.prefix(mtype)
95
+ rec = {"ts":tstamp(), "msg":msg}
96
+ doc = {"_id": self.docid(request, mtype), "messages": [rec],
97
+ "request":request, "identifier":self.dbid,
98
+ "thr":self.thread_name, "type":mtype}
99
+ try:
100
+ exist_doc = self.db.document(doc["_id"])
101
+ doc["_rev"] = exist_doc["_rev"]
102
+ except CouchNotFoundError:
103
+ # this means document is not exist so we will just insert
104
+ pass
105
+ finally:
106
+ res = self.db.commitOne(doc)
107
+ return res
108
+
109
+ def user_update(self, request, msg, mtype='comment'):
110
+ """Update user info in LogDB for given request"""
111
+ rec = {"ts":tstamp(), "msg":msg}
112
+ doc = {"_id": self.docid(request, mtype), "messages": [rec],
113
+ "request":request, "identifier":self.dbid,
114
+ "thr":self.thread_name, "type":mtype}
115
+ try:
116
+ exist_doc = self.db.document(doc["_id"])
117
+ doc["_rev"] = exist_doc["_rev"]
118
+ doc["messages"] += exist_doc["messages"]
119
+ except CouchNotFoundError:
120
+ # this means document is not exist so we will just insert
121
+ pass
122
+ finally:
123
+ res = self.db.commitOne(doc)
124
+ return res
125
+
126
+ def get(self, request, mtype=None, detail=True, agent=True):
127
+ """Retrieve all entries from LogDB for given request"""
128
+ self.check(request, mtype)
129
+ if agent and mtype:
130
+ mtype = self.prefix(mtype)
131
+ options = {'reduce':False}
132
+ if mtype:
133
+ keys = [[request, mtype]]
134
+ else:
135
+ keys=[]
136
+ options.update({'startkey': [request], 'endkey':[request, {}]})
137
+ if detail:
138
+ options.update({'include_docs': True})
139
+ docs = self.db.loadView(self.design, self.view, options, keys=keys)
140
+ return docs
141
+
142
+ def get_by_thread(self, request, mtype='error', detail=False, agent=True):
143
+ self.check(request, mtype)
144
+ if agent and mtype:
145
+ mtype = self.prefix(mtype)
146
+ keys = [[request, self.dbid, self.thread_name, mtype]]
147
+ options = {'reduce':False}
148
+ if detail:
149
+ options.update({'include_docs': True})
150
+ docs = self.db.loadView(self.design, self.threadview, options, keys)
151
+ return docs
152
+
153
+ def get_by_request(self, request):
154
+ keys = [request]
155
+ options = {'reduce':False}
156
+ docs = self.db.loadView(self.design, self.requestview, options, keys)
157
+ return docs
158
+
159
+ def get_all_requests(self):
160
+ """Retrieve all entries from LogDB"""
161
+ options = {'reduce':True, 'group_level':1}
162
+ docs = self.db.loadView(self.design, self.view, options)
163
+ return docs
164
+
165
+ def delete(self, request, mtype=None, this_thread=False, agent=True):
166
+ """Delete entry in LogDB for given request"""
167
+ if mtype:
168
+ self.check(request, mtype)
169
+ else:
170
+ self.check(request)
171
+ if this_thread:
172
+ docs = self.get_by_thread(request, mtype=mtype, detail=False, agent=agent)
173
+ else:
174
+ docs = self.get(request, mtype=mtype, detail=False, agent=agent)
175
+ ids = [r['id'] for r in docs.get('rows', [])]
176
+ res = self.db.bulkDeleteByIDs(ids)
177
+ return res
178
+
179
+ def cleanup(self, thr):
180
+ """
181
+ Clean-up docs older then given threshold (thr should be specified in seconds).
182
+ This is done via tstamp view end endkey, e.g.
183
+ curl "http://127.0.0.1:5984/logdb/_design/LogDB/_view/tstamp?endkey=1427912282"
184
+ """
185
+ cutoff = int(round(time.time()-thr))
186
+ #docs = self.db.allDocs() # may need another view to look-up old docs
187
+ spec = {'endkey':cutoff, 'reduce':False}
188
+ docs = self.db.loadView(self.design, self.tsview, spec)
189
+ ids = [d['id'] for d in docs.get('rows', [])]
190
+ self.db.bulkDeleteByIDs(ids)
191
+ return ids
@@ -0,0 +1,11 @@
1
+ """LogDB Exceptions"""
2
+
3
+ class LogDBError(Exception):
4
+ """Standard error baseclass"""
5
+ def __init__(self, error):
6
+ Exception.__init__(self, error)
7
+ self.msg = LogDBError.__class__.__name__
8
+ self.error = error
9
+
10
+ def __str__(self):
11
+ return "%s: %s" % (self.msg, self.error)
@@ -0,0 +1,85 @@
1
+ #!/usr/bin/env python
2
+ #-*- coding: utf-8 -*-
3
+ #pylint: disable=
4
+ """
5
+ File : LogDBReport.py
6
+ Author : Valentin Kuznetsov <vkuznet AT gmail dot com>
7
+ Description: LogDB report class to represent LogDB messages
8
+ """
9
+ from __future__ import print_function
10
+
11
+ from builtins import range
12
+ from builtins import object
13
+
14
+ class LogDBReport(object):
15
+ """LogDBReport class to represent LogDB messages"""
16
+ def __init__(self, logdb):
17
+ self.logdb = logdb
18
+
19
+ def docs(self, request):
20
+ """Fetch LogDB messages for given request"""
21
+ if request == 'all':
22
+ docs = self.logdb.get_all_requests()
23
+ else:
24
+ docs = self.logdb.get(request)
25
+ return docs
26
+
27
+ def orderby(self, docs, order):
28
+ """Order LogDB messages by given type"""
29
+ odict = {}
30
+ for item in docs:
31
+ odict[item['ts']] = item
32
+ keys = sorted(odict.keys())
33
+ keys.reverse()
34
+ out = []
35
+ for key in keys:
36
+ out.append(odict[key])
37
+ return out
38
+
39
+ def to_json(self, request, order='ts'):
40
+ """Represent given messages in JSON data-format for given set of requests"""
41
+ docs = self.orderby(self.docs(request), order)
42
+ return docs
43
+
44
+ def to_txt(self, request, order='ts', sep=' '):
45
+ """Represent given messages in ASCII text format for given set of requests"""
46
+ docs = self.orderby(self.docs(request), order)
47
+ keys = list(docs[0])
48
+ out = sep.join(keys) + '\n'
49
+ for doc in docs:
50
+ values = []
51
+ for key in keys:
52
+ values.append('%s' % doc[key])
53
+ out += sep.join(values) + '\n'
54
+ return out
55
+
56
+ def to_html(self, request, order='ts'):
57
+ """Represent given messages in ASCII text format for given set of requests"""
58
+ out = '<table id="logdb-report">\n'
59
+ for doc in self.to_txt(request, order, sep='</td><td>').split('\n'):
60
+ if doc:
61
+ out += '<tr><td>'+doc+'</td></tr>\n'
62
+ out += '</table>'
63
+ return out
64
+
65
+ def to_stdout(self, request, order='ts'):
66
+ """Yield to stdout LogDB messages for given request/type"""
67
+ msg = '\nReport for %s' % request
68
+ print(msg, '\n', '-'*len(msg))
69
+ docs = self.orderby(self.docs(request), order)
70
+ times = []
71
+ messages = []
72
+ mtypes = []
73
+ for doc in docs:
74
+ times.append(str(doc['ts']))
75
+ messages.append(doc['msg'])
76
+ mtypes.append(doc['type'])
77
+ tstpad = max([len(t) for t in times])
78
+ msgpad = max([len(m) for m in messages])
79
+ mtppad = max([len(m) for m in mtypes])
80
+ out = []
81
+ for idx in range(len(times)):
82
+ tcol = '%s%s' % (times[idx], ' '*(tstpad-len(times[idx])))
83
+ mcol = '%s%s' % (messages[idx], ' '*(msgpad-len(messages[idx])))
84
+ ecol = '%s%s' % (mtypes[idx], ' '*(mtppad-len(mtypes[idx])))
85
+ print("%s %s %s" % (tcol, mcol, ecol))
File without changes
File without changes
@@ -0,0 +1,54 @@
1
+ """
2
+ This module contains a few basic WMCore-related utilitarian functions
3
+ """
4
+
5
+ from Utils.CertTools import ckey, cert
6
+
7
+ from WMCore.Services.pycurl_manager import RequestHandler
8
+
9
+
10
+ def makeHttpRequest(srvUrl, payload=None, method='GET', headers=None, encode=True, decode=True, payloadSizeToDump=50):
11
+ """
12
+ Perform HTTP call to provided service URL. This can be any of supported methods like
13
+ GET, POST, PUT, DELETE. It will return HTTP response from upstream MicroService
14
+ and parse it accordingly (the WMCore MS service returns results as {'result': {'data':...}}
15
+ HTTP response.
16
+
17
+ :param srvUrl: string with the service url
18
+ :param payload: payload query or document, in case of GET HTTP request it is query dictionary,
19
+ in case of POST/PUT HTTP requests it is JSON payload to the service
20
+ :param method: string, defines which HTTP method to use
21
+ :param headers: HTTP headers (presented as dictionarY)
22
+ :param encode: boolean to reflect if data should be encoded, see pycurl_manager.py
23
+ :param decode: boolean to reflect if data should be decoded, see pycurl_manager.py
24
+ :param payloadSizeToDump: amount of characters to dump in a log from payload (to make log entries readable)
25
+ :return: returns a list with all objects, or raises
26
+ an exception in case of failure
27
+ """
28
+ payload = payload or {}
29
+ mgr = RequestHandler()
30
+ headers = headers or {'Content-Type': 'application/json'}
31
+ data = mgr.getdata(srvUrl, payload, headers, verb=method,
32
+ ckey=ckey(), cert=cert(), encode=encode, decode=decode)
33
+ if data and data.get("result", []):
34
+ if "error" in data["result"][0]:
35
+ # strip off part of payload to make readable log message
36
+ sdata = f"{payload}"
37
+ if len(sdata) > payloadSizeToDump:
38
+ sdata = sdata[:payloadSizeToDump] + "..."
39
+ msg = f"Failed to contact {srvUrl} via {method} request with {sdata}"
40
+ msg += f" and error message: {data}"
41
+ raise RuntimeError(msg)
42
+ return data["result"]
43
+
44
+ def getPileupDocs(mspileupUrl, queryDict=None, method='GET'):
45
+ """
46
+ Fetch documents from MSPileup according to the query passed in using POST.
47
+
48
+ :param mspileupUrl: string with the MSPileup url
49
+ :param queryDict: dictionary with the MongoDB query to run
50
+ :param method: string, defines which HTTP method to use
51
+ :return: returns a list with all the pileup objects, or raises
52
+ an exception in case of failure
53
+ """
54
+ return makeHttpRequest(mspileupUrl, payload=queryDict, method=method)
File without changes