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,274 @@
1
+ #!/usr/bin/env
2
+
3
+ """
4
+ _MathAlgos_
5
+
6
+ Simple mathematical tools and tricks that might prove to
7
+ be useful.
8
+ """
9
+ from __future__ import print_function, division
10
+ from builtins import str, range
11
+
12
+ import math
13
+ import decimal
14
+ import logging
15
+
16
+ from WMCore.WMException import WMException
17
+
18
+
19
+ class MathAlgoException(WMException):
20
+ """
21
+ Some simple math algo exceptions
22
+
23
+ """
24
+ pass
25
+
26
+
27
+ def getAverageStdDev(numList):
28
+ """
29
+ _getAverageStdDev_
30
+
31
+ Given a list, calculate both the average and the
32
+ standard deviation.
33
+ """
34
+
35
+ total = 0.0
36
+ average = 0.0
37
+ stdBase = 0.0
38
+
39
+ # Assemble the average
40
+ skipped = 0
41
+ for value in numList:
42
+ try:
43
+ if math.isnan(value) or math.isinf(value):
44
+ skipped += 1
45
+ continue
46
+ else:
47
+ total += value
48
+ except TypeError:
49
+ msg = "Attempted to take average of non-numerical values.\n"
50
+ msg += "Expected int or float, got %s: %s" % (value.__class__, value)
51
+ logging.error(msg)
52
+ logging.debug("FullList: %s", numList)
53
+ raise MathAlgoException(msg)
54
+
55
+ length = len(numList) - skipped
56
+ if length < 1:
57
+ return average, total
58
+
59
+ average = total / length
60
+
61
+ for value in numList:
62
+ tmpValue = value - average
63
+ stdBase += (tmpValue * tmpValue)
64
+
65
+ stdDev = math.sqrt(stdBase / length)
66
+
67
+ if math.isnan(average) or math.isinf(average):
68
+ average = 0.0
69
+ if math.isnan(stdDev) or math.isinf(average) or not decimal.Decimal(str(stdDev)).is_finite():
70
+ stdDev = 0.0
71
+ if not isinstance(stdDev, (int, float)):
72
+ stdDev = 0.0
73
+
74
+ return average, stdDev
75
+
76
+
77
+ def createHistogram(numList, nBins, limit):
78
+ """
79
+ _createHistogram_
80
+
81
+ Create a histogram proxy (a list of bins) for a
82
+ given list of numbers
83
+ """
84
+
85
+ average, stdDev = getAverageStdDev(numList = numList)
86
+
87
+ underflow = []
88
+ overflow = []
89
+ histEvents = []
90
+ histogram = []
91
+ for value in numList:
92
+ if math.fabs(average - value) <= limit * stdDev:
93
+ # Then we counted this event
94
+ histEvents.append(value)
95
+ elif average < value:
96
+ overflow.append(value)
97
+ elif average > value:
98
+ underflow.append(value)
99
+
100
+ if len(underflow) > 0:
101
+ binAvg, binStdDev = getAverageStdDev(numList=underflow)
102
+ histogram.append({'type': 'underflow',
103
+ 'average': binAvg,
104
+ 'stdDev': binStdDev,
105
+ 'nEvents': len(underflow)})
106
+ if len(overflow) > 0:
107
+ binAvg, binStdDev = getAverageStdDev(numList=overflow)
108
+ histogram.append({'type': 'overflow',
109
+ 'average': binAvg,
110
+ 'stdDev': binStdDev,
111
+ 'nEvents': len(overflow)})
112
+ if len(histEvents) < 1:
113
+ # Nothing to do?
114
+ return histogram
115
+
116
+ histEvents.sort()
117
+ upperBound = max(histEvents)
118
+ lowerBound = min(histEvents)
119
+ if lowerBound == upperBound:
120
+ # This is a problem
121
+ logging.debug("Only one value in the histogram!")
122
+ nBins = 1
123
+ upperBound = upperBound + 1
124
+ lowerBound = lowerBound - 1
125
+ binSize = (upperBound - lowerBound)/nBins
126
+ binSize = floorTruncate(binSize)
127
+
128
+ for x in range(nBins):
129
+ lowerEdge = floorTruncate(lowerBound + (x * binSize))
130
+ histogram.append({'type': 'standard',
131
+ 'lowerEdge': lowerEdge,
132
+ 'upperEdge': lowerEdge + binSize,
133
+ 'average': 0.0,
134
+ 'stdDev': 0.0,
135
+ 'nEvents': 0})
136
+
137
+ for bin_ in histogram:
138
+ if bin_['type'] != 'standard':
139
+ continue
140
+ binList = []
141
+ for value in histEvents:
142
+ if value >= bin_['lowerEdge'] and value <= bin_['upperEdge']:
143
+ # Then we're in the bin
144
+ binList.append(value)
145
+ elif value > bin_['upperEdge']:
146
+ # Because this is a sorted list we are now out of the bin range
147
+ # Calculate our values and break
148
+ break
149
+ else:
150
+ continue
151
+
152
+ # If we get here, it's because we're out of values in the bin
153
+ # Time to do some math
154
+ if len(binList) < 1:
155
+ # Nothing to do here, leave defaults
156
+ continue
157
+
158
+ binAvg, binStdDev = getAverageStdDev(numList=binList)
159
+ bin_['average'] = binAvg
160
+ bin_['stdDev'] = binStdDev
161
+ bin_['nEvents'] = len(binList)
162
+
163
+ return histogram
164
+
165
+
166
+ def floorTruncate(value, precision=3):
167
+ """
168
+ _floorTruncate_
169
+
170
+ Truncate a value to a set number of decimal points
171
+
172
+ Always truncates to a LOWER value, this is so that using it for
173
+ histogram binning creates values beneath the histogram lower edge.
174
+ """
175
+ prec = math.pow(10, precision)
176
+
177
+ return math.floor(value * prec)/prec
178
+
179
+
180
+ def sortDictionaryListByKey(dictList, key, reverse=False):
181
+ """
182
+ _sortDictionaryListByKey_
183
+
184
+ Given a list of dictionaries and a key with a numerical
185
+ value, sort that dictionary in order of that key's value.
186
+
187
+ NOTE: If the key does not exist, this will not raise an exception
188
+ This is because this is used for sorting of performance histograms
189
+ And not all histograms have the same value
190
+ """
191
+
192
+ return sorted(dictList, key=lambda k: float(k.get(key, 0.0)), reverse=reverse)
193
+
194
+
195
+ def getLargestValues(dictList, key, n=1):
196
+ """
197
+ _getLargestValues_
198
+
199
+ Take a list of dictionaries, sort them by the value of a
200
+ particular key, and return the n largest entries.
201
+
202
+ Key must be a numerical key.
203
+ """
204
+
205
+ sortedList = sortDictionaryListByKey(dictList=dictList, key=key, reverse=True)
206
+
207
+ return sortedList[:n]
208
+
209
+
210
+ def validateNumericInput(value):
211
+ """
212
+ _validateNumericInput_
213
+
214
+ Check that the value is actually an usable number
215
+ """
216
+ value = float(value)
217
+ try:
218
+ if math.isnan(value) or math.isinf(value):
219
+ return False
220
+ except TypeError:
221
+ return False
222
+
223
+ return True
224
+
225
+
226
+ def calculateRunningAverageAndQValue(newPoint, n, oldM, oldQ):
227
+ """
228
+ _calculateRunningAverageAndQValue_
229
+
230
+ Use the algorithm described in:
231
+ Donald E. Knuth (1998). The Art of Computer Programming, volume 2: Seminumerical Algorithms, 3rd ed.., p. 232. Boston: Addison-Wesley.
232
+
233
+ To calculate an average and standard deviation while getting data, the standard deviation
234
+ can be obtained from the so-called Q value with the following equation:
235
+
236
+ sigma = sqrt(Q/n)
237
+
238
+ This is also contained in the function calculateStdDevFromQ in this module. The average is equal to M.
239
+ """
240
+
241
+ if not validateNumericInput(newPoint): raise MathAlgoException("Provided a non-valid newPoint")
242
+ if not validateNumericInput(n): raise MathAlgoException("Provided a non-valid n")
243
+
244
+ if n == 1:
245
+ M = newPoint
246
+ Q = 0.0
247
+ else:
248
+ if not validateNumericInput(oldM): raise MathAlgoException("Provided a non-valid oldM")
249
+ if not validateNumericInput(oldQ): raise MathAlgoException("Provided a non-valid oldQ")
250
+ M = oldM + (newPoint - oldM) / n
251
+ Q = oldQ + ((n - 1) * (newPoint - oldM) * (newPoint - oldM) / n)
252
+
253
+ return M, Q
254
+
255
+
256
+ def calculateStdDevFromQ(Q, n):
257
+ """
258
+ _calculateStdDevFromQ_
259
+
260
+ If Q is the sum of the squared differences of some points to their average,
261
+ then the standard deviation is given by:
262
+
263
+ sigma = sqrt(Q/n)
264
+
265
+ This function calculates that formula
266
+ """
267
+ if not validateNumericInput(Q): raise MathAlgoException("Provided a non-valid Q")
268
+ if not validateNumericInput(n): raise MathAlgoException("Provided a non-valid n")
269
+
270
+ sigma = math.sqrt(Q / n)
271
+
272
+ if not validateNumericInput(sigma): return 0.0
273
+
274
+ return sigma
@@ -0,0 +1,67 @@
1
+ #! /usr/bin/env python
2
+
3
+ """
4
+ _MiscAlgos_
5
+
6
+ Useful little tools that can be handy anywhere.
7
+ """
8
+ import logging
9
+
10
+ def sortListByKey(data, key):
11
+ """
12
+ Return list of dictionaries as a
13
+ dictionary of lists of dictionaries
14
+ keyed by one original key
15
+
16
+ """
17
+ final = {}
18
+
19
+ for entry in data:
20
+ value = entry.get(key, None)
21
+ if value == None:
22
+ # Empty dict value?
23
+ # This is an error, but we can't handle it here
24
+ logging.error("Found entry with no key in sortListByKey: %s", entry)
25
+ logging.error("Skipping")
26
+ continue
27
+ if isinstance(value, set):
28
+ try:
29
+ v = value
30
+ value = v.pop()
31
+ v.add(value)
32
+ except KeyError:
33
+ # Set was empty?
34
+ # This is peculiar, we can't handle this.
35
+ logging.error("Found list entry with empty key set in sortListByKey: %s", entry)
36
+ logging.error("Skipping")
37
+ continue
38
+ if value not in final:
39
+ final[value] = []
40
+ final[value].append(entry)
41
+
42
+ return final
43
+
44
+
45
+
46
+ ## {{{ http://code.activestate.com/recipes/576644/ (r1)
47
+ def dict_diff(first, second):
48
+ """ Return a dict of keys that differ with another config object. If a value is
49
+ not found in one fo the configs, it will be represented by KEYNOTFOUND.
50
+ @param first: Fist dictionary to diff.
51
+ @param second: Second dicationary to diff.
52
+ @return diff: Dict of Key => (first.val, second.val)
53
+ """
54
+ KEYNOTFOUND = '<KEYNOTFOUND>'
55
+ diff = {}
56
+ # Check all keys in first dict
57
+ for key in first:
58
+ if (key not in second):
59
+ diff[key] = (first[key], KEYNOTFOUND)
60
+ elif (first[key] != second[key]):
61
+ diff[key] = (first[key], second[key])
62
+ # Check all keys in second dict to find missing
63
+ for key in second:
64
+ if (key not in first):
65
+ diff[key] = (KEYNOTFOUND, second[key])
66
+ return diff
67
+ ## end of http://code.activestate.com/recipes/576644/ }}}
@@ -0,0 +1,115 @@
1
+ #!/bin/env python
2
+
3
+ """
4
+ _ParseXMLFile_
5
+
6
+ This holds the methods used to take an xmlFilename and return a tree structure.
7
+ Used for the expat xml parsers
8
+
9
+ """
10
+
11
+ from builtins import next, str, object
12
+ from future.utils import viewitems
13
+
14
+ import xml.parsers.expat
15
+
16
+ class Node(object):
17
+ """
18
+ _Node_
19
+
20
+ Really simple DOM like container to simplify parsing the XML file
21
+ and formatting the character data without all the whitespace guff
22
+
23
+ """
24
+ def __init__(self, name, attrs):
25
+ self.name = str(name)
26
+ self.attrs = {}
27
+ self.text = None
28
+ for k, v in viewitems(attrs):
29
+ self.attrs.__setitem__(str(k), str(v))
30
+ self.children = []
31
+
32
+ def __str__(self):
33
+
34
+ result = " %s %s \"%s\"\n" % (self.name, self.attrs, self.text)
35
+ for child in self.children:
36
+ result += str(child)
37
+ return result
38
+
39
+
40
+
41
+ def coroutine(func):
42
+ """
43
+ _coroutine_
44
+
45
+ Decorator method used to prime coroutines
46
+
47
+ """
48
+ def start(*args,**kwargs):
49
+ cr = func(*args,**kwargs)
50
+ next(cr)
51
+ return cr
52
+ return start
53
+
54
+
55
+ def xmlFileToNode(reportFile):
56
+ """
57
+ _xmlFileToNode_
58
+
59
+ Use expat and the build coroutine to parse the XML file and build
60
+ a node structure
61
+
62
+ """
63
+ node = Node("JobReports", {})
64
+ expat_parse(open(reportFile, 'rb'),
65
+ build(node))
66
+ return node
67
+
68
+
69
+ def expat_parse(f, target):
70
+ """
71
+ _expat_parse_
72
+
73
+ Expat based XML parsing that feeds a node building coroutine
74
+
75
+ """
76
+ parser = xml.parsers.expat.ParserCreate()
77
+ #parser.buffer_size = 65536
78
+ parser.buffer_text = True
79
+
80
+ # a leftover from the py2py3 migration - TO BE REMOVED
81
+ # parser.returns_unicode = False
82
+ parser.StartElementHandler = \
83
+ lambda name,attrs: target.send(('start',(name,attrs)))
84
+ parser.EndElementHandler = \
85
+ lambda name: target.send(('end',name))
86
+ parser.CharacterDataHandler = \
87
+ lambda data: target.send(('text',data))
88
+ parser.ParseFile(f)
89
+
90
+
91
+ @coroutine
92
+ def build(topNode):
93
+ """
94
+ _build_
95
+
96
+ Node structure builder that is fed from the expat_parse method
97
+
98
+ """
99
+ nodeStack = [topNode]
100
+ charCache = []
101
+ while True:
102
+ event, value = (yield)
103
+ if event == "start":
104
+ charCache = []
105
+ newnode = Node(value[0], value[1])
106
+ nodeStack[-1].children.append(newnode)
107
+ nodeStack.append(newnode)
108
+
109
+ elif event == "text":
110
+ charCache.append(value)
111
+
112
+ else: # end
113
+ nodeStack[-1].text = str(''.join(charCache)).strip()
114
+ nodeStack.pop()
115
+ charCache = []
@@ -0,0 +1,27 @@
1
+ '''
2
+ A bunch of functions that check the permissions on a file are what they should
3
+ be, or more restrictive.
4
+ '''
5
+
6
+
7
+
8
+ from builtins import oct
9
+ import os
10
+ import stat
11
+
12
+ def check_permissions(filehandle, permission, pass_stronger = False):
13
+ info = os.stat(filehandle)
14
+ filepermission = oct(info[stat.ST_MODE] & 0o777)
15
+ if pass_stronger:
16
+ assert filepermission <= permission, "file's permissions are too weak"
17
+ else:
18
+ assert filepermission == permission, "file does not have the correct permissions"
19
+
20
+ def owner_readonly(file_):
21
+ check_permissions(file_, oct(0o400))
22
+
23
+ def owner_readwrite(file_):
24
+ check_permissions(file_, oct(0o600))
25
+
26
+ def owner_readwriteexec(file_):
27
+ check_permissions(file_, oct(0o700))
@@ -0,0 +1,58 @@
1
+ #! /usr/bin/env python
2
+
3
+ """
4
+ A singleton pattern implemented in python. Adapted from ActiveState Code
5
+ Recipe 52558: The Singleton Pattern implemented with Python
6
+ http://code.activestate.com/recipes/52558/
7
+ """
8
+
9
+
10
+
11
+
12
+ from builtins import object
13
+ class Singleton(object):
14
+ """
15
+ A python singleton
16
+ """
17
+
18
+
19
+ class SingletonImplementation(object):
20
+ """
21
+ Implementation of the singleton interface
22
+ """
23
+
24
+ def singletonId(self):
25
+ """
26
+ Test method, return singleton id
27
+ """
28
+ return id(self)
29
+
30
+
31
+ # Storage for the instance reference
32
+ __instance = None
33
+
34
+ def __init__(self):
35
+ """
36
+ Create singleton instance
37
+ """
38
+ # Check whether we already have an instance
39
+ if Singleton.__instance is None:
40
+ # Create and remember instance
41
+ Singleton.__instance = Singleton.SingletonImplementation()
42
+
43
+ # Store instance reference as the only member in the handle
44
+ self.__dict__['_Singleton__instance'] = Singleton.__instance
45
+
46
+
47
+ def __getattr__(self, attr):
48
+ """
49
+ Delegate access to implementation
50
+ """
51
+ return getattr(self.__instance, attr)
52
+
53
+
54
+ def __setattr__(self, attr, value):
55
+ """
56
+ Delegate access to implementation
57
+ """
58
+ return setattr(self.__instance, attr, value)
@@ -0,0 +1,129 @@
1
+ #!/bin/env python
2
+
3
+ """
4
+ _SubprocessAlgos_
5
+
6
+ Little tricks you can do on the command line with Subprocess
7
+ i.e., stand-ins for Linux command line functions
8
+
9
+ """
10
+
11
+ from builtins import str
12
+ import os
13
+ import re
14
+ import signal
15
+ import logging
16
+ import subprocess
17
+
18
+ from WMCore.Algorithms.Alarm import Alarm, alarmHandler
19
+ from WMCore.WMException import WMException
20
+ from Utils.Utilities import decodeBytesToUnicode
21
+ from Utils.PythonVersion import PY3
22
+
23
+ class SubprocessAlgoException(WMException):
24
+ """
25
+ _SubprocessAlgoException_
26
+
27
+ Clever exception that does nothing. Cleverly.
28
+ """
29
+ pass
30
+
31
+
32
+ def findPIDs(name, user = os.getpid()):
33
+ """
34
+ Finds the PIDs for a process with name name being used by a user with a certain uid
35
+
36
+ """
37
+
38
+ pids = []
39
+
40
+ ps = subprocess.Popen(['ps', '-u', user, 'w'], stdout=subprocess.PIPE).communicate()[0]
41
+ processes = ps.split('\n')
42
+
43
+ for line in processes:
44
+ if len(line.split()) < 5:
45
+ continue
46
+ if re.match(name, line.split()[4]):
47
+ #Then we have matching process
48
+ pids.append(line.split()[0])
49
+
50
+ return pids
51
+
52
+
53
+ def killProcessByName(name, user = os.getpid(), sig = None):
54
+ """
55
+ Kills all processes of a certain type (name)
56
+
57
+ """
58
+
59
+ pids = findPIDs(name = name, user = user)
60
+
61
+ if len(pids) == 0:
62
+ #We have no processes to kill of this type
63
+ return pids
64
+
65
+ command = ['kill']
66
+ if sig:
67
+ command.append('-%i' % sig)
68
+ for pid in pids:
69
+ command.append(pid)
70
+
71
+ subprocess.Popen(command, stdout=subprocess.PIPE).communicate()[0]
72
+
73
+
74
+ return pids
75
+
76
+
77
+ def tailNLinesFromFile(file_, n):
78
+ """
79
+ Loads the last N lines from a file
80
+
81
+ """
82
+
83
+ if not os.path.isfile(file_):
84
+ return None
85
+
86
+ command = ['tail', '-n', str(n), file_]
87
+
88
+ output = subprocess.Popen(command, stdout=subprocess.PIPE).communicate()[0]
89
+
90
+ return output.split('\n')
91
+
92
+
93
+
94
+ def runCommand(cmd, shell = True, timeout = None):
95
+ """
96
+ Run generic command
97
+
98
+ This is NOT secure and hence NOT recommended
99
+ It does however have the timeout functions built into it
100
+ timeout must be an int
101
+ Note, setting timeout = 0 does nothing!
102
+ """
103
+
104
+ if timeout:
105
+ if not isinstance(timeout, int):
106
+ timeout = None
107
+ logging.error("SubprocessAlgo.runCommand expected int timeout, got %s", timeout)
108
+ else:
109
+ signal.signal(signal.SIGALRM, alarmHandler)
110
+ signal.alarm(timeout)
111
+ try:
112
+ pipe = subprocess.Popen(cmd, stdout = subprocess.PIPE,
113
+ stderr = subprocess.PIPE, shell = shell)
114
+ stdout, stderr = pipe.communicate()
115
+ if PY3:
116
+ stdout = decodeBytesToUnicode(stdout)
117
+ stderr = decodeBytesToUnicode(stderr)
118
+ returnCode = pipe.returncode
119
+ except Alarm:
120
+ msg = "Alarm sounded while running command after %s seconds.\n" % timeout
121
+ msg += "Command: %s\n" % cmd
122
+ msg += "Raising exception"
123
+ logging.error(msg)
124
+ raise SubprocessAlgoException(msg)
125
+
126
+ if timeout:
127
+ signal.alarm(0)
128
+
129
+ return stdout, stderr, returnCode
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env python
2
+ """
3
+ __init__
4
+
5
+ """
6
+
7
+ __all__ = []