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.
- Utils/CPMetrics.py +270 -0
- Utils/CertTools.py +100 -0
- Utils/EmailAlert.py +50 -0
- Utils/ExtendedUnitTestCase.py +62 -0
- Utils/FileTools.py +182 -0
- Utils/IteratorTools.py +80 -0
- Utils/MathUtils.py +31 -0
- Utils/MemoryCache.py +119 -0
- Utils/Patterns.py +24 -0
- Utils/Pipeline.py +137 -0
- Utils/PortForward.py +97 -0
- Utils/ProcFS.py +112 -0
- Utils/ProcessStats.py +194 -0
- Utils/PythonVersion.py +17 -0
- Utils/Signals.py +36 -0
- Utils/TemporaryEnvironment.py +27 -0
- Utils/Throttled.py +227 -0
- Utils/Timers.py +130 -0
- Utils/Timestamps.py +86 -0
- Utils/TokenManager.py +143 -0
- Utils/Tracing.py +60 -0
- Utils/TwPrint.py +98 -0
- Utils/Utilities.py +318 -0
- Utils/__init__.py +11 -0
- Utils/wmcoreDTools.py +707 -0
- WMCore/ACDC/Collection.py +57 -0
- WMCore/ACDC/CollectionTypes.py +12 -0
- WMCore/ACDC/CouchCollection.py +67 -0
- WMCore/ACDC/CouchFileset.py +238 -0
- WMCore/ACDC/CouchService.py +73 -0
- WMCore/ACDC/DataCollectionService.py +485 -0
- WMCore/ACDC/Fileset.py +94 -0
- WMCore/ACDC/__init__.py +11 -0
- WMCore/Algorithms/Alarm.py +39 -0
- WMCore/Algorithms/MathAlgos.py +274 -0
- WMCore/Algorithms/MiscAlgos.py +67 -0
- WMCore/Algorithms/ParseXMLFile.py +115 -0
- WMCore/Algorithms/Permissions.py +27 -0
- WMCore/Algorithms/Singleton.py +58 -0
- WMCore/Algorithms/SubprocessAlgos.py +129 -0
- WMCore/Algorithms/__init__.py +7 -0
- WMCore/Cache/GenericDataCache.py +98 -0
- WMCore/Cache/WMConfigCache.py +572 -0
- WMCore/Cache/__init__.py +0 -0
- WMCore/Configuration.py +659 -0
- WMCore/DAOFactory.py +47 -0
- WMCore/DataStructs/File.py +177 -0
- WMCore/DataStructs/Fileset.py +140 -0
- WMCore/DataStructs/Job.py +182 -0
- WMCore/DataStructs/JobGroup.py +142 -0
- WMCore/DataStructs/JobPackage.py +49 -0
- WMCore/DataStructs/LumiList.py +734 -0
- WMCore/DataStructs/Mask.py +219 -0
- WMCore/DataStructs/MathStructs/ContinuousSummaryHistogram.py +197 -0
- WMCore/DataStructs/MathStructs/DiscreteSummaryHistogram.py +92 -0
- WMCore/DataStructs/MathStructs/SummaryHistogram.py +117 -0
- WMCore/DataStructs/MathStructs/__init__.py +0 -0
- WMCore/DataStructs/Pickleable.py +24 -0
- WMCore/DataStructs/Run.py +256 -0
- WMCore/DataStructs/Subscription.py +175 -0
- WMCore/DataStructs/WMObject.py +47 -0
- WMCore/DataStructs/WorkUnit.py +112 -0
- WMCore/DataStructs/Workflow.py +60 -0
- WMCore/DataStructs/__init__.py +8 -0
- WMCore/Database/CMSCouch.py +1430 -0
- WMCore/Database/ConfigDBMap.py +29 -0
- WMCore/Database/CouchMonitoring.py +450 -0
- WMCore/Database/CouchUtils.py +118 -0
- WMCore/Database/DBCore.py +198 -0
- WMCore/Database/DBCreator.py +113 -0
- WMCore/Database/DBExceptionHandler.py +59 -0
- WMCore/Database/DBFactory.py +117 -0
- WMCore/Database/DBFormatter.py +177 -0
- WMCore/Database/Dialects.py +13 -0
- WMCore/Database/ExecuteDAO.py +327 -0
- WMCore/Database/MongoDB.py +241 -0
- WMCore/Database/MySQL/Destroy.py +42 -0
- WMCore/Database/MySQL/ListUserContent.py +20 -0
- WMCore/Database/MySQL/__init__.py +9 -0
- WMCore/Database/MySQLCore.py +132 -0
- WMCore/Database/Oracle/Destroy.py +56 -0
- WMCore/Database/Oracle/ListUserContent.py +19 -0
- WMCore/Database/Oracle/__init__.py +9 -0
- WMCore/Database/ResultSet.py +44 -0
- WMCore/Database/Transaction.py +91 -0
- WMCore/Database/__init__.py +9 -0
- WMCore/Database/ipy_profile_couch.py +438 -0
- WMCore/GlobalWorkQueue/CherryPyThreads/CleanUpTask.py +29 -0
- WMCore/GlobalWorkQueue/CherryPyThreads/HeartbeatMonitor.py +105 -0
- WMCore/GlobalWorkQueue/CherryPyThreads/LocationUpdateTask.py +28 -0
- WMCore/GlobalWorkQueue/CherryPyThreads/ReqMgrInteractionTask.py +35 -0
- WMCore/GlobalWorkQueue/CherryPyThreads/__init__.py +0 -0
- WMCore/GlobalWorkQueue/__init__.py +0 -0
- WMCore/GroupUser/CouchObject.py +127 -0
- WMCore/GroupUser/Decorators.py +51 -0
- WMCore/GroupUser/Group.py +33 -0
- WMCore/GroupUser/Interface.py +73 -0
- WMCore/GroupUser/User.py +96 -0
- WMCore/GroupUser/__init__.py +11 -0
- WMCore/Lexicon.py +836 -0
- WMCore/REST/Auth.py +202 -0
- WMCore/REST/CherryPyPeriodicTask.py +166 -0
- WMCore/REST/Error.py +333 -0
- WMCore/REST/Format.py +642 -0
- WMCore/REST/HeartbeatMonitorBase.py +90 -0
- WMCore/REST/Main.py +636 -0
- WMCore/REST/Server.py +2435 -0
- WMCore/REST/Services.py +24 -0
- WMCore/REST/Test.py +120 -0
- WMCore/REST/Tools.py +38 -0
- WMCore/REST/Validation.py +250 -0
- WMCore/REST/__init__.py +1 -0
- WMCore/ReqMgr/DataStructs/RequestStatus.py +209 -0
- WMCore/ReqMgr/DataStructs/RequestType.py +13 -0
- WMCore/ReqMgr/DataStructs/__init__.py +0 -0
- WMCore/ReqMgr/__init__.py +1 -0
- WMCore/Services/AlertManager/AlertManagerAPI.py +111 -0
- WMCore/Services/AlertManager/__init__.py +0 -0
- WMCore/Services/CRIC/CRIC.py +238 -0
- WMCore/Services/CRIC/__init__.py +0 -0
- WMCore/Services/DBS/DBS3Reader.py +1044 -0
- WMCore/Services/DBS/DBSConcurrency.py +44 -0
- WMCore/Services/DBS/DBSErrors.py +112 -0
- WMCore/Services/DBS/DBSReader.py +23 -0
- WMCore/Services/DBS/DBSUtils.py +166 -0
- WMCore/Services/DBS/DBSWriterObjects.py +381 -0
- WMCore/Services/DBS/ProdException.py +133 -0
- WMCore/Services/DBS/__init__.py +8 -0
- WMCore/Services/FWJRDB/FWJRDBAPI.py +118 -0
- WMCore/Services/FWJRDB/__init__.py +0 -0
- WMCore/Services/HTTPS/HTTPSAuthHandler.py +66 -0
- WMCore/Services/HTTPS/__init__.py +0 -0
- WMCore/Services/LogDB/LogDB.py +201 -0
- WMCore/Services/LogDB/LogDBBackend.py +191 -0
- WMCore/Services/LogDB/LogDBExceptions.py +11 -0
- WMCore/Services/LogDB/LogDBReport.py +85 -0
- WMCore/Services/LogDB/__init__.py +0 -0
- WMCore/Services/MSPileup/__init__.py +0 -0
- WMCore/Services/MSUtils/MSUtils.py +54 -0
- WMCore/Services/MSUtils/__init__.py +0 -0
- WMCore/Services/McM/McM.py +173 -0
- WMCore/Services/McM/__init__.py +8 -0
- WMCore/Services/MonIT/Grafana.py +133 -0
- WMCore/Services/MonIT/__init__.py +0 -0
- WMCore/Services/PyCondor/PyCondorAPI.py +154 -0
- WMCore/Services/PyCondor/__init__.py +0 -0
- WMCore/Services/ReqMgr/ReqMgr.py +261 -0
- WMCore/Services/ReqMgr/__init__.py +0 -0
- WMCore/Services/ReqMgrAux/ReqMgrAux.py +419 -0
- WMCore/Services/ReqMgrAux/__init__.py +0 -0
- WMCore/Services/RequestDB/RequestDBReader.py +267 -0
- WMCore/Services/RequestDB/RequestDBWriter.py +39 -0
- WMCore/Services/RequestDB/__init__.py +0 -0
- WMCore/Services/Requests.py +624 -0
- WMCore/Services/Rucio/Rucio.py +1290 -0
- WMCore/Services/Rucio/RucioUtils.py +74 -0
- WMCore/Services/Rucio/__init__.py +0 -0
- WMCore/Services/RucioConMon/RucioConMon.py +121 -0
- WMCore/Services/RucioConMon/__init__.py +0 -0
- WMCore/Services/Service.py +400 -0
- WMCore/Services/StompAMQ/__init__.py +0 -0
- WMCore/Services/TagCollector/TagCollector.py +155 -0
- WMCore/Services/TagCollector/XMLUtils.py +98 -0
- WMCore/Services/TagCollector/__init__.py +0 -0
- WMCore/Services/UUIDLib.py +13 -0
- WMCore/Services/UserFileCache/UserFileCache.py +160 -0
- WMCore/Services/UserFileCache/__init__.py +8 -0
- WMCore/Services/WMAgent/WMAgent.py +63 -0
- WMCore/Services/WMAgent/__init__.py +0 -0
- WMCore/Services/WMArchive/CMSSWMetrics.py +526 -0
- WMCore/Services/WMArchive/DataMap.py +463 -0
- WMCore/Services/WMArchive/WMArchive.py +33 -0
- WMCore/Services/WMArchive/__init__.py +0 -0
- WMCore/Services/WMBS/WMBS.py +97 -0
- WMCore/Services/WMBS/__init__.py +0 -0
- WMCore/Services/WMStats/DataStruct/RequestInfoCollection.py +300 -0
- WMCore/Services/WMStats/DataStruct/__init__.py +0 -0
- WMCore/Services/WMStats/WMStatsPycurl.py +145 -0
- WMCore/Services/WMStats/WMStatsReader.py +445 -0
- WMCore/Services/WMStats/WMStatsWriter.py +273 -0
- WMCore/Services/WMStats/__init__.py +0 -0
- WMCore/Services/WMStatsServer/WMStatsServer.py +134 -0
- WMCore/Services/WMStatsServer/__init__.py +0 -0
- WMCore/Services/WorkQueue/WorkQueue.py +492 -0
- WMCore/Services/WorkQueue/__init__.py +0 -0
- WMCore/Services/__init__.py +8 -0
- WMCore/Services/pycurl_manager.py +574 -0
- WMCore/WMBase.py +50 -0
- WMCore/WMConnectionBase.py +164 -0
- WMCore/WMException.py +183 -0
- WMCore/WMExceptions.py +269 -0
- WMCore/WMFactory.py +76 -0
- WMCore/WMInit.py +377 -0
- WMCore/WMLogging.py +104 -0
- WMCore/WMSpec/ConfigSectionTree.py +442 -0
- WMCore/WMSpec/Persistency.py +135 -0
- WMCore/WMSpec/Steps/BuildMaster.py +87 -0
- WMCore/WMSpec/Steps/BuildTools.py +201 -0
- WMCore/WMSpec/Steps/Builder.py +97 -0
- WMCore/WMSpec/Steps/Diagnostic.py +89 -0
- WMCore/WMSpec/Steps/Emulator.py +62 -0
- WMCore/WMSpec/Steps/ExecuteMaster.py +208 -0
- WMCore/WMSpec/Steps/Executor.py +210 -0
- WMCore/WMSpec/Steps/StepFactory.py +213 -0
- WMCore/WMSpec/Steps/TaskEmulator.py +75 -0
- WMCore/WMSpec/Steps/Template.py +204 -0
- WMCore/WMSpec/Steps/Templates/AlcaHarvest.py +76 -0
- WMCore/WMSpec/Steps/Templates/CMSSW.py +613 -0
- WMCore/WMSpec/Steps/Templates/DQMUpload.py +59 -0
- WMCore/WMSpec/Steps/Templates/DeleteFiles.py +70 -0
- WMCore/WMSpec/Steps/Templates/LogArchive.py +84 -0
- WMCore/WMSpec/Steps/Templates/LogCollect.py +105 -0
- WMCore/WMSpec/Steps/Templates/StageOut.py +105 -0
- WMCore/WMSpec/Steps/Templates/__init__.py +10 -0
- WMCore/WMSpec/Steps/WMExecutionFailure.py +21 -0
- WMCore/WMSpec/Steps/__init__.py +8 -0
- WMCore/WMSpec/Utilities.py +63 -0
- WMCore/WMSpec/WMSpecErrors.py +12 -0
- WMCore/WMSpec/WMStep.py +347 -0
- WMCore/WMSpec/WMTask.py +1997 -0
- WMCore/WMSpec/WMWorkload.py +2288 -0
- WMCore/WMSpec/WMWorkloadTools.py +382 -0
- WMCore/WMSpec/__init__.py +9 -0
- WMCore/WorkQueue/DataLocationMapper.py +273 -0
- WMCore/WorkQueue/DataStructs/ACDCBlock.py +47 -0
- WMCore/WorkQueue/DataStructs/Block.py +48 -0
- WMCore/WorkQueue/DataStructs/CouchWorkQueueElement.py +148 -0
- WMCore/WorkQueue/DataStructs/WorkQueueElement.py +274 -0
- WMCore/WorkQueue/DataStructs/WorkQueueElementResult.py +152 -0
- WMCore/WorkQueue/DataStructs/WorkQueueElementsSummary.py +185 -0
- WMCore/WorkQueue/DataStructs/__init__.py +0 -0
- WMCore/WorkQueue/Policy/End/EndPolicyInterface.py +44 -0
- WMCore/WorkQueue/Policy/End/SingleShot.py +22 -0
- WMCore/WorkQueue/Policy/End/__init__.py +32 -0
- WMCore/WorkQueue/Policy/PolicyInterface.py +17 -0
- WMCore/WorkQueue/Policy/Start/Block.py +258 -0
- WMCore/WorkQueue/Policy/Start/Dataset.py +180 -0
- WMCore/WorkQueue/Policy/Start/MonteCarlo.py +131 -0
- WMCore/WorkQueue/Policy/Start/ResubmitBlock.py +171 -0
- WMCore/WorkQueue/Policy/Start/StartPolicyInterface.py +316 -0
- WMCore/WorkQueue/Policy/Start/__init__.py +34 -0
- WMCore/WorkQueue/Policy/__init__.py +57 -0
- WMCore/WorkQueue/WMBSHelper.py +772 -0
- WMCore/WorkQueue/WorkQueue.py +1237 -0
- WMCore/WorkQueue/WorkQueueBackend.py +750 -0
- WMCore/WorkQueue/WorkQueueBase.py +39 -0
- WMCore/WorkQueue/WorkQueueExceptions.py +44 -0
- WMCore/WorkQueue/WorkQueueReqMgrInterface.py +278 -0
- WMCore/WorkQueue/WorkQueueUtils.py +130 -0
- WMCore/WorkQueue/__init__.py +13 -0
- WMCore/Wrappers/JsonWrapper/JSONThunker.py +342 -0
- WMCore/Wrappers/JsonWrapper/__init__.py +7 -0
- WMCore/Wrappers/__init__.py +6 -0
- WMCore/__init__.py +10 -0
- wmglobalqueue-2.4.5.1.data/data/bin/wmc-dist-patch +15 -0
- wmglobalqueue-2.4.5.1.data/data/bin/wmc-dist-unpatch +8 -0
- wmglobalqueue-2.4.5.1.data/data/bin/wmc-httpd +3 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/.couchapprc +1 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/README.md +40 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/index.html +264 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/js/ElementInfoByWorkflow.js +96 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/js/StuckElementInfo.js +57 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/js/WorkloadInfoTable.js +80 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/js/dataTable.js +70 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/js/namespace.js +23 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/style/main.css +75 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/couchapp.json +4 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/filters/childQueueFilter.js +13 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/filters/filterDeletedDocs.js +3 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/filters/queueFilter.js +11 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/language +1 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lib/mustache.js +333 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lib/validate.js +27 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lib/workqueue_utils.js +61 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lists/elementsDetail.js +28 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lists/filter.js +86 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lists/stuckElements.js +38 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lists/workRestrictions.js +153 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lists/workflowSummary.js +28 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/rewrites.json +73 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/shows/redirect.js +23 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/shows/status.js +40 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/ElementSummaryByWorkflow.html +27 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/StuckElementSummary.html +26 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/TaskStatus.html +23 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/WorkflowSummary.html +27 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/partials/workqueue-common-lib.html +2 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/partials/yui-lib-remote.html +16 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/partials/yui-lib.html +18 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/updates/in-place.js +50 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/validate_doc_update.js +8 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/vendor/couchapp/_attachments/jquery.couch.app.js +235 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/vendor/couchapp/_attachments/jquery.pathbinder.js +173 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/activeData/map.js +8 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/activeData/reduce.js +2 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/activeParentData/map.js +8 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/activeParentData/reduce.js +2 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/activePileupData/map.js +8 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/activePileupData/reduce.js +2 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/analyticsData/map.js +11 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/analyticsData/reduce.js +1 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/availableByPriority/map.js +6 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/conflicts/map.js +5 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elements/map.js +5 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByData/map.js +8 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByParent/map.js +8 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByParentData/map.js +8 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByPileupData/map.js +8 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByStatus/map.js +8 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsBySubscription/map.js +6 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByWorkflow/map.js +8 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByWorkflow/reduce.js +3 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsDetailByWorkflowAndStatus/map.js +26 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobInjectStatusByRequest/map.js +10 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobInjectStatusByRequest/reduce.js +1 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobStatusByRequest/map.js +6 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobStatusByRequest/reduce.js +1 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByChildQueueAndPriority/map.js +6 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByChildQueueAndPriority/reduce.js +1 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByChildQueueAndStatus/map.js +6 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByChildQueueAndStatus/reduce.js +1 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByRequest/map.js +6 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByRequest/reduce.js +1 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByStatus/map.js +6 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByStatus/reduce.js +1 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByStatusAndPriority/map.js +6 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByStatusAndPriority/reduce.js +1 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/openRequests/map.js +6 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/recent-items/map.js +5 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/siteWhitelistByRequest/map.js +6 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/siteWhitelistByRequest/reduce.js +1 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/specsByWorkflow/map.js +5 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/stuckElements/map.js +38 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/wmbsInjectStatusByRequest/map.js +12 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/wmbsInjectStatusByRequest/reduce.js +3 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/wmbsUrl/map.js +6 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/wmbsUrl/reduce.js +2 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/wmbsUrlByRequest/map.js +6 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/wmbsUrlByRequest/reduce.js +2 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/workflowSummary/map.js +9 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/workflowSummary/reduce.js +10 -0
- wmglobalqueue-2.4.5.1.dist-info/METADATA +26 -0
- wmglobalqueue-2.4.5.1.dist-info/RECORD +347 -0
- wmglobalqueue-2.4.5.1.dist-info/WHEEL +5 -0
- wmglobalqueue-2.4.5.1.dist-info/licenses/LICENSE +202 -0
- wmglobalqueue-2.4.5.1.dist-info/licenses/NOTICE +16 -0
- 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
|