wmglobalqueue 2.3.10__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of wmglobalqueue might be problematic. Click here for more details.
- Utils/CPMetrics.py +270 -0
- Utils/CertTools.py +62 -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/ProcessStats.py +103 -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 +308 -0
- Utils/__init__.py +11 -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 +651 -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 +1349 -0
- WMCore/Database/ConfigDBMap.py +29 -0
- WMCore/Database/CouchUtils.py +118 -0
- WMCore/Database/DBCore.py +198 -0
- WMCore/Database/DBCreator.py +113 -0
- WMCore/Database/DBExceptionHandler.py +57 -0
- WMCore/Database/DBFactory.py +110 -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 +623 -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 +113 -0
- WMCore/Services/DBS/DBSReader.py +23 -0
- WMCore/Services/DBS/DBSUtils.py +139 -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/PyCondorUtils.py +105 -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 +1287 -0
- WMCore/Services/Rucio/RucioUtils.py +74 -0
- WMCore/Services/Rucio/__init__.py +0 -0
- WMCore/Services/RucioConMon/RucioConMon.py +128 -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 +228 -0
- WMCore/WMLogging.py +108 -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 +1980 -0
- WMCore/WMSpec/WMWorkload.py +2288 -0
- WMCore/WMSpec/WMWorkloadTools.py +370 -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.3.10.data/data/bin/wmc-dist-patch +15 -0
- wmglobalqueue-2.3.10.data/data/bin/wmc-dist-unpatch +8 -0
- wmglobalqueue-2.3.10.data/data/bin/wmc-httpd +3 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/.couchapprc +1 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/README.md +40 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/_attachments/index.html +264 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/_attachments/js/ElementInfoByWorkflow.js +96 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/_attachments/js/StuckElementInfo.js +57 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/_attachments/js/WorkloadInfoTable.js +80 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/_attachments/js/dataTable.js +70 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/_attachments/js/namespace.js +23 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/_attachments/style/main.css +75 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/couchapp.json +4 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/filters/childQueueFilter.js +13 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/filters/filterDeletedDocs.js +3 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/filters/queueFilter.js +11 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/language +1 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/lib/mustache.js +333 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/lib/validate.js +27 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/lib/workqueue_utils.js +61 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/lists/elementsDetail.js +28 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/lists/filter.js +86 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/lists/stuckElements.js +38 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/lists/workRestrictions.js +153 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/lists/workflowSummary.js +28 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/rewrites.json +73 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/shows/redirect.js +23 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/shows/status.js +40 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/templates/ElementSummaryByWorkflow.html +27 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/templates/StuckElementSummary.html +26 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/templates/TaskStatus.html +23 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/templates/WorkflowSummary.html +27 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/templates/partials/workqueue-common-lib.html +2 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/templates/partials/yui-lib-remote.html +16 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/templates/partials/yui-lib.html +18 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/updates/in-place.js +50 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/validate_doc_update.js +8 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/vendor/couchapp/_attachments/jquery.couch.app.js +235 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/vendor/couchapp/_attachments/jquery.pathbinder.js +173 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/activeData/map.js +8 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/activeData/reduce.js +2 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/activeParentData/map.js +8 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/activeParentData/reduce.js +2 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/activePileupData/map.js +8 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/activePileupData/reduce.js +2 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/analyticsData/map.js +11 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/analyticsData/reduce.js +1 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/availableByPriority/map.js +6 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/conflicts/map.js +5 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/elements/map.js +5 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/elementsByData/map.js +8 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/elementsByParent/map.js +8 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/elementsByParentData/map.js +8 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/elementsByPileupData/map.js +8 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/elementsByStatus/map.js +8 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/elementsBySubscription/map.js +6 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/elementsByWorkflow/map.js +8 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/elementsByWorkflow/reduce.js +3 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/elementsDetailByWorkflowAndStatus/map.js +26 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/jobInjectStatusByRequest/map.js +10 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/jobInjectStatusByRequest/reduce.js +1 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/jobStatusByRequest/map.js +6 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/jobStatusByRequest/reduce.js +1 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/jobsByChildQueueAndPriority/map.js +6 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/jobsByChildQueueAndPriority/reduce.js +1 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/jobsByChildQueueAndStatus/map.js +6 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/jobsByChildQueueAndStatus/reduce.js +1 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/jobsByRequest/map.js +6 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/jobsByRequest/reduce.js +1 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/jobsByStatus/map.js +6 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/jobsByStatus/reduce.js +1 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/jobsByStatusAndPriority/map.js +6 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/jobsByStatusAndPriority/reduce.js +1 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/openRequests/map.js +6 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/recent-items/map.js +5 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/siteWhitelistByRequest/map.js +6 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/siteWhitelistByRequest/reduce.js +1 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/specsByWorkflow/map.js +5 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/stuckElements/map.js +38 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/wmbsInjectStatusByRequest/map.js +12 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/wmbsInjectStatusByRequest/reduce.js +3 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/wmbsUrl/map.js +6 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/wmbsUrl/reduce.js +2 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/wmbsUrlByRequest/map.js +6 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/wmbsUrlByRequest/reduce.js +2 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/workflowSummary/map.js +9 -0
- wmglobalqueue-2.3.10.data/data/data/couchapps/WorkQueue/views/workflowSummary/reduce.js +10 -0
- wmglobalqueue-2.3.10.dist-info/LICENSE +202 -0
- wmglobalqueue-2.3.10.dist-info/METADATA +24 -0
- wmglobalqueue-2.3.10.dist-info/NOTICE +16 -0
- wmglobalqueue-2.3.10.dist-info/RECORD +345 -0
- wmglobalqueue-2.3.10.dist-info/WHEEL +5 -0
- wmglobalqueue-2.3.10.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
from __future__ import print_function, division
|
|
2
|
+
from builtins import str
|
|
3
|
+
from builtins import object
|
|
4
|
+
import time
|
|
5
|
+
import logging
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class MemoryCacheStruct(object):
|
|
9
|
+
"""
|
|
10
|
+
WARNING: This can be used in multi thread by registering on GenericDataCache
|
|
11
|
+
But this cache is not thread safe.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
def __init__(self, expire, func, initCacheValue=None, logger=None, kwargs=None):
|
|
15
|
+
"""
|
|
16
|
+
expire is the seconds which cache will be refreshed when cache is older than the expire.
|
|
17
|
+
func is the fuction which cache data is retrieved
|
|
18
|
+
kwargs are func arguments for cache data
|
|
19
|
+
"""
|
|
20
|
+
kwargs = kwargs or {}
|
|
21
|
+
self.data = initCacheValue
|
|
22
|
+
self.expire = expire
|
|
23
|
+
self.func = func
|
|
24
|
+
|
|
25
|
+
self.kwargs = kwargs
|
|
26
|
+
self.lastUpdated = -1
|
|
27
|
+
self.logger = logger if logger else logging.getLogger()
|
|
28
|
+
|
|
29
|
+
def isDataExpired(self):
|
|
30
|
+
if self.lastUpdated == -1:
|
|
31
|
+
return True
|
|
32
|
+
if (int(time.time()) - self.lastUpdated) > self.expire:
|
|
33
|
+
return True
|
|
34
|
+
return False
|
|
35
|
+
|
|
36
|
+
def getData(self, noFail=True):
|
|
37
|
+
if self.isDataExpired():
|
|
38
|
+
try:
|
|
39
|
+
self.data = self.func(**self.kwargs)
|
|
40
|
+
self.lastUpdated = int(time.time())
|
|
41
|
+
except Exception as exc:
|
|
42
|
+
if noFail:
|
|
43
|
+
msg = "Passive failure while looking data up in the memory cache. Error: %s" % str(exc)
|
|
44
|
+
self.logger.warning(msg)
|
|
45
|
+
else:
|
|
46
|
+
raise
|
|
47
|
+
return self.data
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class CacheExistException(Exception):
|
|
51
|
+
def __init__(self, cacheName):
|
|
52
|
+
Exception.__init__(self, cacheName)
|
|
53
|
+
self.msg = CacheExistException.__class__.__name__
|
|
54
|
+
self.error = "Cache already registered %s" % cacheName
|
|
55
|
+
|
|
56
|
+
def __str__(self):
|
|
57
|
+
return "%s: %s" % (self.msg, self.error)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class CacheWithWrongStructException(Exception):
|
|
61
|
+
def __init__(self, cacheName):
|
|
62
|
+
Exception.__init__(self, cacheName)
|
|
63
|
+
self.msg = CacheWithWrongStructException.__class__.__name__
|
|
64
|
+
self.error = "Cache should be instance of MemoryCacheStruct %s" % cacheName
|
|
65
|
+
|
|
66
|
+
def __str__(self):
|
|
67
|
+
return "%s: %s" % (self.msg, self.error)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class GenericDataCache(object):
|
|
71
|
+
_dataCache = {}
|
|
72
|
+
|
|
73
|
+
@staticmethod
|
|
74
|
+
def getCacheData(cacheName):
|
|
75
|
+
return GenericDataCache._dataCache[cacheName]
|
|
76
|
+
|
|
77
|
+
@staticmethod
|
|
78
|
+
def registerCache(cacheName, memoryCache):
|
|
79
|
+
"""
|
|
80
|
+
cacheName, unique name for the cache
|
|
81
|
+
memoryCache MemoryCacheStruct instance.
|
|
82
|
+
"""
|
|
83
|
+
if cacheName in GenericDataCache._dataCache:
|
|
84
|
+
raise CacheExistException(cacheName)
|
|
85
|
+
elif not isinstance(memoryCache, MemoryCacheStruct):
|
|
86
|
+
raise CacheWithWrongStructException(cacheName)
|
|
87
|
+
else:
|
|
88
|
+
logging.info("Creating generic cache named: %s", cacheName)
|
|
89
|
+
GenericDataCache._dataCache[cacheName] = memoryCache
|
|
90
|
+
|
|
91
|
+
@staticmethod
|
|
92
|
+
def cacheExists(cacheName):
|
|
93
|
+
"""
|
|
94
|
+
Return True if provided cache name is already cached, else False.
|
|
95
|
+
:param cacheName: cache name string
|
|
96
|
+
:return: boolean
|
|
97
|
+
"""
|
|
98
|
+
return cacheName in GenericDataCache._dataCache
|
|
@@ -0,0 +1,572 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""
|
|
3
|
+
_WMConfigCache_
|
|
4
|
+
|
|
5
|
+
Being in itself a wrapped class around a config cache
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from future import standard_library
|
|
9
|
+
standard_library.install_aliases()
|
|
10
|
+
import urllib.request, urllib.parse, urllib.error
|
|
11
|
+
from builtins import str
|
|
12
|
+
from future.utils import with_metaclass
|
|
13
|
+
from future.utils import viewkeys, viewvalues
|
|
14
|
+
|
|
15
|
+
import hashlib
|
|
16
|
+
import logging
|
|
17
|
+
import traceback
|
|
18
|
+
from contextlib import closing
|
|
19
|
+
|
|
20
|
+
import WMCore.GroupUser.Decorators as Decorators
|
|
21
|
+
from Utils.Patterns import Singleton
|
|
22
|
+
from Utils.Utilities import decodeBytesToUnicode
|
|
23
|
+
from Utils.PythonVersion import PY3
|
|
24
|
+
from WMCore.DataStructs.WMObject import WMObject
|
|
25
|
+
from WMCore.Database.CMSCouch import CouchNotFoundError
|
|
26
|
+
from WMCore.Database.CMSCouch import CouchServer, Document
|
|
27
|
+
from WMCore.GroupUser.Group import Group
|
|
28
|
+
from WMCore.GroupUser.User import makeUser
|
|
29
|
+
from WMCore.WMException import WMException
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class ConfigCacheException(WMException):
|
|
33
|
+
"""
|
|
34
|
+
Placeholder for a smarter exception class
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class DocumentCache(with_metaclass(Singleton, object)):
|
|
41
|
+
"""DocumentCache holds config ids. Use this class as singleton"""
|
|
42
|
+
|
|
43
|
+
def __init__(self, database, detail=True):
|
|
44
|
+
super(DocumentCache, self).__init__()
|
|
45
|
+
self.cache = {}
|
|
46
|
+
self.database = database
|
|
47
|
+
# flag to decide whether update detail or not when it is prefetched
|
|
48
|
+
self.detail = detail
|
|
49
|
+
|
|
50
|
+
def __getitem__(self, configID):
|
|
51
|
+
"""
|
|
52
|
+
Internal get method to fetch document based on provided ID
|
|
53
|
+
"""
|
|
54
|
+
if configID not in self.cache:
|
|
55
|
+
self.prefetch([configID])
|
|
56
|
+
return self.cache[configID]
|
|
57
|
+
|
|
58
|
+
def cleanup(self, ids):
|
|
59
|
+
"""
|
|
60
|
+
_cleanup_
|
|
61
|
+
|
|
62
|
+
Clean-up given ids from local cache
|
|
63
|
+
"""
|
|
64
|
+
for rid in ids:
|
|
65
|
+
if rid in self.cache:
|
|
66
|
+
del self.cache[rid]
|
|
67
|
+
|
|
68
|
+
def prefetch(self, keys):
|
|
69
|
+
"""
|
|
70
|
+
_fetch_
|
|
71
|
+
|
|
72
|
+
Pre-fetch given list of documents from CouchDB
|
|
73
|
+
"""
|
|
74
|
+
if self.detail:
|
|
75
|
+
options = {'include_docs': True}
|
|
76
|
+
else:
|
|
77
|
+
options = {}
|
|
78
|
+
result = self.database.allDocs(options=options, keys=keys)
|
|
79
|
+
for row in result['rows']:
|
|
80
|
+
if self.detail:
|
|
81
|
+
self.cache[row['id']] = row['doc']
|
|
82
|
+
else:
|
|
83
|
+
self.cache[row['id']] = True
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class ConfigCache(WMObject):
|
|
87
|
+
"""
|
|
88
|
+
_ConfigCache_
|
|
89
|
+
|
|
90
|
+
The class that handles the upload and download of configCache
|
|
91
|
+
artifacts from Couch
|
|
92
|
+
"""
|
|
93
|
+
|
|
94
|
+
def __init__(self, dbURL, couchDBName=None, id=None, rev=None, usePYCurl=True,
|
|
95
|
+
ckey=None, cert=None, capath=None, detail=True):
|
|
96
|
+
super(ConfigCache, self).__init__()
|
|
97
|
+
self.dbname = couchDBName
|
|
98
|
+
self.dburl = dbURL
|
|
99
|
+
self.detail = detail
|
|
100
|
+
try:
|
|
101
|
+
self.couchdb = CouchServer(self.dburl, usePYCurl=usePYCurl, ckey=ckey, cert=cert, capath=capath)
|
|
102
|
+
if self.dbname not in self.couchdb.listDatabases():
|
|
103
|
+
self.createDatabase()
|
|
104
|
+
|
|
105
|
+
self.database = self.couchdb.connectDatabase(self.dbname)
|
|
106
|
+
except Exception as ex:
|
|
107
|
+
msg = "Error connecting to couch: %s\n" % str(ex)
|
|
108
|
+
msg += str(traceback.format_exc())
|
|
109
|
+
logging.error(msg)
|
|
110
|
+
raise ConfigCacheException(message=msg)
|
|
111
|
+
|
|
112
|
+
# local cache
|
|
113
|
+
self.docs_cache = DocumentCache(self.database, self.detail)
|
|
114
|
+
|
|
115
|
+
# UserGroup variables
|
|
116
|
+
self.group = None
|
|
117
|
+
self.owner = None
|
|
118
|
+
|
|
119
|
+
# Internal data structure
|
|
120
|
+
self.document = Document()
|
|
121
|
+
self.attachments = {}
|
|
122
|
+
self.document['type'] = "config"
|
|
123
|
+
self.document['description'] = {}
|
|
124
|
+
self.document['description']['config_label'] = None
|
|
125
|
+
self.document['description']['config_desc'] = None
|
|
126
|
+
|
|
127
|
+
if id != None:
|
|
128
|
+
self.document['_id'] = id
|
|
129
|
+
self.document['pset_tweak_details'] = None
|
|
130
|
+
self.document['info'] = None
|
|
131
|
+
self.document['config'] = None
|
|
132
|
+
return
|
|
133
|
+
|
|
134
|
+
def createDatabase(self):
|
|
135
|
+
"""
|
|
136
|
+
_createDatabase_
|
|
137
|
+
|
|
138
|
+
"""
|
|
139
|
+
database = self.couchdb.createDatabase(self.dbname)
|
|
140
|
+
database.commit()
|
|
141
|
+
return database
|
|
142
|
+
|
|
143
|
+
def connectUserGroup(self, groupname, username):
|
|
144
|
+
"""
|
|
145
|
+
_connectUserGroup_
|
|
146
|
+
|
|
147
|
+
"""
|
|
148
|
+
self.group = Group(name=groupname)
|
|
149
|
+
self.group.setCouch(self.dburl, self.dbname)
|
|
150
|
+
self.group.connect()
|
|
151
|
+
self.owner = makeUser(groupname, username,
|
|
152
|
+
couchUrl=self.dburl,
|
|
153
|
+
couchDatabase=self.dbname)
|
|
154
|
+
return
|
|
155
|
+
|
|
156
|
+
def createUserGroup(self, groupname, username):
|
|
157
|
+
"""
|
|
158
|
+
_createUserGroup_
|
|
159
|
+
|
|
160
|
+
Create all the userGroup information
|
|
161
|
+
"""
|
|
162
|
+
self.createGroup(name=groupname)
|
|
163
|
+
self.createUser(username=username)
|
|
164
|
+
return
|
|
165
|
+
|
|
166
|
+
def createGroup(self, name):
|
|
167
|
+
"""
|
|
168
|
+
_createGroup_
|
|
169
|
+
|
|
170
|
+
Create Group for GroupUser
|
|
171
|
+
"""
|
|
172
|
+
self.group = Group(name=name)
|
|
173
|
+
self.group.setCouch(self.dburl, self.dbname)
|
|
174
|
+
self.group.connect()
|
|
175
|
+
self.group.create()
|
|
176
|
+
return
|
|
177
|
+
|
|
178
|
+
def setLabel(self, label):
|
|
179
|
+
"""
|
|
180
|
+
_setLabel_
|
|
181
|
+
|
|
182
|
+
Util to add a descriptive label to the configuration doc
|
|
183
|
+
"""
|
|
184
|
+
self.document['description']['config_label'] = label
|
|
185
|
+
|
|
186
|
+
def setDescription(self, desc):
|
|
187
|
+
"""
|
|
188
|
+
_setDescription_
|
|
189
|
+
|
|
190
|
+
Util to add a verbose description string to a configuration doc
|
|
191
|
+
"""
|
|
192
|
+
self.document['description']['config_desc'] = desc
|
|
193
|
+
|
|
194
|
+
@Decorators.requireGroup
|
|
195
|
+
def createUser(self, username):
|
|
196
|
+
self.owner = makeUser(self.group['name'], username,
|
|
197
|
+
couchUrl=self.dburl,
|
|
198
|
+
couchDatabase=self.dbname)
|
|
199
|
+
self.owner.create()
|
|
200
|
+
self.owner.ownThis(self.document)
|
|
201
|
+
return
|
|
202
|
+
|
|
203
|
+
@Decorators.requireGroup
|
|
204
|
+
@Decorators.requireUser
|
|
205
|
+
def save(self):
|
|
206
|
+
"""
|
|
207
|
+
_save_
|
|
208
|
+
|
|
209
|
+
Save yourself! Save your internal document.
|
|
210
|
+
"""
|
|
211
|
+
rawResults = self.database.commit(doc=self.document)
|
|
212
|
+
|
|
213
|
+
# We should only be committing one document at a time
|
|
214
|
+
# if not, get the last one.
|
|
215
|
+
|
|
216
|
+
try:
|
|
217
|
+
commitResults = rawResults[-1]
|
|
218
|
+
self.document["_rev"] = commitResults.get('rev')
|
|
219
|
+
self.document["_id"] = commitResults.get('id')
|
|
220
|
+
except KeyError as ex:
|
|
221
|
+
msg = "Document returned from couch without ID or Revision\n"
|
|
222
|
+
msg += "Document probably bad\n"
|
|
223
|
+
msg += str(ex)
|
|
224
|
+
logging.error(msg)
|
|
225
|
+
raise ConfigCacheException(message=msg)
|
|
226
|
+
|
|
227
|
+
# Now do the attachments
|
|
228
|
+
for attachName in self.attachments:
|
|
229
|
+
self.saveAttachment(name=attachName,
|
|
230
|
+
attachment=self.attachments[attachName])
|
|
231
|
+
|
|
232
|
+
return
|
|
233
|
+
|
|
234
|
+
def saveAttachment(self, name, attachment):
|
|
235
|
+
"""
|
|
236
|
+
_saveAttachment_
|
|
237
|
+
|
|
238
|
+
Save an attachment to the document
|
|
239
|
+
"""
|
|
240
|
+
|
|
241
|
+
retval = self.database.addAttachment(self.document["_id"],
|
|
242
|
+
self.document["_rev"],
|
|
243
|
+
attachment,
|
|
244
|
+
name)
|
|
245
|
+
|
|
246
|
+
if retval.get('ok', False) != True:
|
|
247
|
+
# Then we have a problem
|
|
248
|
+
msg = "Adding an attachment to document failed\n"
|
|
249
|
+
msg += str(retval)
|
|
250
|
+
msg += "ID: %s, Rev: %s" % (self.document["_id"], self.document["_rev"])
|
|
251
|
+
logging.error(msg)
|
|
252
|
+
raise ConfigCacheException(msg)
|
|
253
|
+
|
|
254
|
+
self.document["_rev"] = retval['rev']
|
|
255
|
+
self.document["_id"] = retval['id']
|
|
256
|
+
self.attachments[name] = attachment
|
|
257
|
+
|
|
258
|
+
return
|
|
259
|
+
|
|
260
|
+
def loadDocument(self, configID):
|
|
261
|
+
"""
|
|
262
|
+
_loadDocument_
|
|
263
|
+
|
|
264
|
+
Load a document from the document cache given its couchID
|
|
265
|
+
"""
|
|
266
|
+
self.document = self.docs_cache[configID]
|
|
267
|
+
|
|
268
|
+
def loadByID(self, configID):
|
|
269
|
+
"""
|
|
270
|
+
_loadByID_
|
|
271
|
+
|
|
272
|
+
Load a document from the server given its couchID
|
|
273
|
+
"""
|
|
274
|
+
try:
|
|
275
|
+
self.document = self.database.document(id=configID)
|
|
276
|
+
if 'owner' in self.document:
|
|
277
|
+
self.connectUserGroup(groupname=self.document['owner'].get('group', None),
|
|
278
|
+
username=self.document['owner'].get('user', None))
|
|
279
|
+
if '_attachments' in self.document:
|
|
280
|
+
# Then we need to load the attachments
|
|
281
|
+
for key in viewkeys(self.document['_attachments']):
|
|
282
|
+
self.loadAttachment(name=key)
|
|
283
|
+
except CouchNotFoundError as ex:
|
|
284
|
+
msg = "Document with id %s not found in couch\n" % (configID)
|
|
285
|
+
msg += str(ex)
|
|
286
|
+
msg += str(traceback.format_exc())
|
|
287
|
+
logging.error(msg)
|
|
288
|
+
raise ConfigCacheException(message=msg)
|
|
289
|
+
except Exception as ex:
|
|
290
|
+
msg = "Error loading document from couch\n"
|
|
291
|
+
msg += str(ex)
|
|
292
|
+
msg += str(traceback.format_exc())
|
|
293
|
+
logging.error(msg)
|
|
294
|
+
raise ConfigCacheException(message=msg)
|
|
295
|
+
|
|
296
|
+
return
|
|
297
|
+
|
|
298
|
+
def loadAttachment(self, name, overwrite=True):
|
|
299
|
+
"""
|
|
300
|
+
_loadAttachment_
|
|
301
|
+
|
|
302
|
+
Load an attachment from the database and put it somewhere useful
|
|
303
|
+
"""
|
|
304
|
+
|
|
305
|
+
attach = self.database.getAttachment(self.document["_id"], name)
|
|
306
|
+
|
|
307
|
+
if not overwrite:
|
|
308
|
+
if name in self.attachments:
|
|
309
|
+
logging.info("Attachment already exists, so we're skipping")
|
|
310
|
+
return
|
|
311
|
+
|
|
312
|
+
self.attachments[name] = attach
|
|
313
|
+
|
|
314
|
+
return
|
|
315
|
+
|
|
316
|
+
def loadByView(self, view, value):
|
|
317
|
+
"""
|
|
318
|
+
_loadByView_
|
|
319
|
+
|
|
320
|
+
Underlying code to load views
|
|
321
|
+
"""
|
|
322
|
+
|
|
323
|
+
viewRes = self.database.loadView('ConfigCache', view, {}, [value])
|
|
324
|
+
|
|
325
|
+
if not viewRes['rows']:
|
|
326
|
+
# Then we have a problem
|
|
327
|
+
msg = "Unable to load using view %s and value %s" % (view, str(value))
|
|
328
|
+
logging.error(msg)
|
|
329
|
+
|
|
330
|
+
self.unwrapView(viewRes)
|
|
331
|
+
self.loadByID(self.document["_id"])
|
|
332
|
+
return
|
|
333
|
+
|
|
334
|
+
def saveConfigToDisk(self, targetFile):
|
|
335
|
+
"""
|
|
336
|
+
_saveConfigToDisk_
|
|
337
|
+
|
|
338
|
+
Make sure we can save our config file to disk
|
|
339
|
+
"""
|
|
340
|
+
config = self.getConfig()
|
|
341
|
+
if not config:
|
|
342
|
+
return
|
|
343
|
+
|
|
344
|
+
# Write to a file
|
|
345
|
+
with open(targetFile, 'w') as f:
|
|
346
|
+
f.write(config)
|
|
347
|
+
return
|
|
348
|
+
|
|
349
|
+
def load(self):
|
|
350
|
+
"""
|
|
351
|
+
_load_
|
|
352
|
+
|
|
353
|
+
Figure out how to load
|
|
354
|
+
"""
|
|
355
|
+
|
|
356
|
+
if self.document.get("_id", None) != None:
|
|
357
|
+
# Then we should load by ID
|
|
358
|
+
self.loadByID(self.document["_id"])
|
|
359
|
+
return
|
|
360
|
+
|
|
361
|
+
# Otherwise we have to load by view
|
|
362
|
+
|
|
363
|
+
if not self.document.get('md5_hash', None) is None:
|
|
364
|
+
# Then we have an md5_hash
|
|
365
|
+
self.loadByView(view='config_by_md5hash', value=self.document['md5_hash'])
|
|
366
|
+
# TODO: Add more views as they become available.
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
# elif not self.owner == None:
|
|
370
|
+
# Then we have an owner
|
|
371
|
+
# self.loadByView(view = 'config_by_owner', value = self.owner['name'])
|
|
372
|
+
|
|
373
|
+
def unwrapView(self, view):
|
|
374
|
+
"""
|
|
375
|
+
_unwrapView_
|
|
376
|
+
|
|
377
|
+
Move view information into the main document
|
|
378
|
+
"""
|
|
379
|
+
|
|
380
|
+
self.document["_id"] = view['rows'][0].get('id')
|
|
381
|
+
self.document["_rev"] = view['rows'][0].get('value').get('_rev')
|
|
382
|
+
|
|
383
|
+
def setPSetTweaks(self, PSetTweak):
|
|
384
|
+
"""
|
|
385
|
+
_setPSetTweaks_
|
|
386
|
+
|
|
387
|
+
Set the PSet tweak details for the config.
|
|
388
|
+
"""
|
|
389
|
+
self.document['pset_tweak_details'] = PSetTweak
|
|
390
|
+
return
|
|
391
|
+
|
|
392
|
+
def getPSetTweaks(self):
|
|
393
|
+
"""
|
|
394
|
+
_getPSetTweaks_
|
|
395
|
+
|
|
396
|
+
Retrieve the PSet tweak details.
|
|
397
|
+
"""
|
|
398
|
+
return self.document['pset_tweak_details']
|
|
399
|
+
|
|
400
|
+
def getOutputModuleInfo(self):
|
|
401
|
+
"""
|
|
402
|
+
_getOutputModuleInfo_
|
|
403
|
+
|
|
404
|
+
Retrieve the dataset information for the config in the ConfigCache.
|
|
405
|
+
"""
|
|
406
|
+
psetTweaks = self.getPSetTweaks()
|
|
407
|
+
if 'process' not in psetTweaks:
|
|
408
|
+
raise ConfigCacheException("Could not find process field in PSet while getting output modules!")
|
|
409
|
+
try:
|
|
410
|
+
outputModuleNames = psetTweaks["process"]["outputModules_"]
|
|
411
|
+
except KeyError as ex:
|
|
412
|
+
msg = "Could not find outputModules_ in psetTweaks['process'] while getting output modules.\n"
|
|
413
|
+
msg += str(ex)
|
|
414
|
+
logging.error(msg)
|
|
415
|
+
raise ConfigCacheException(msg)
|
|
416
|
+
|
|
417
|
+
results = {}
|
|
418
|
+
for outputModuleName in outputModuleNames:
|
|
419
|
+
try:
|
|
420
|
+
outModule = psetTweaks["process"][outputModuleName]
|
|
421
|
+
except KeyError:
|
|
422
|
+
msg = "Could not find outputModule %s in psetTweaks['process']" % outputModuleName
|
|
423
|
+
logging.error(msg)
|
|
424
|
+
raise ConfigCacheException(msg)
|
|
425
|
+
dataset = outModule.get("dataset", None)
|
|
426
|
+
if dataset:
|
|
427
|
+
results[outputModuleName] = {"dataTier": outModule["dataset"]["dataTier"],
|
|
428
|
+
"filterName": outModule["dataset"]["filterName"]}
|
|
429
|
+
else:
|
|
430
|
+
results[outputModuleName] = {"dataTier": None, "filterName": None}
|
|
431
|
+
|
|
432
|
+
return results
|
|
433
|
+
|
|
434
|
+
def addConfig(self, newConfig, psetHash=None):
|
|
435
|
+
"""
|
|
436
|
+
_addConfig_
|
|
437
|
+
|
|
438
|
+
|
|
439
|
+
"""
|
|
440
|
+
# The newConfig parameter is a URL suitable for passing to urlopen.
|
|
441
|
+
with closing(urllib.request.urlopen(newConfig)) as f:
|
|
442
|
+
configString = f.read(-1)
|
|
443
|
+
configMD5 = hashlib.md5(configString).hexdigest()
|
|
444
|
+
if PY3:
|
|
445
|
+
configString = decodeBytesToUnicode(configString)
|
|
446
|
+
|
|
447
|
+
self.document['md5_hash'] = configMD5
|
|
448
|
+
self.document['pset_hash'] = psetHash
|
|
449
|
+
self.attachments['configFile'] = configString
|
|
450
|
+
return
|
|
451
|
+
|
|
452
|
+
def getConfig(self):
|
|
453
|
+
"""
|
|
454
|
+
_getConfig_
|
|
455
|
+
|
|
456
|
+
Get the currently active config
|
|
457
|
+
"""
|
|
458
|
+
return self.attachments.get('configFile', None)
|
|
459
|
+
|
|
460
|
+
def getCouchID(self):
|
|
461
|
+
"""
|
|
462
|
+
_getCouchID_
|
|
463
|
+
|
|
464
|
+
Return the document's couchID
|
|
465
|
+
"""
|
|
466
|
+
|
|
467
|
+
return self.document["_id"]
|
|
468
|
+
|
|
469
|
+
def getCouchRev(self):
|
|
470
|
+
"""
|
|
471
|
+
_getCouchRev_
|
|
472
|
+
|
|
473
|
+
Return the document's couchRevision
|
|
474
|
+
"""
|
|
475
|
+
|
|
476
|
+
return self.document["_rev"]
|
|
477
|
+
|
|
478
|
+
@Decorators.requireGroup
|
|
479
|
+
@Decorators.requireUser
|
|
480
|
+
def delete(self):
|
|
481
|
+
"""
|
|
482
|
+
_delete_
|
|
483
|
+
|
|
484
|
+
Deletes the document with the current docid
|
|
485
|
+
"""
|
|
486
|
+
if not self.document["_id"]:
|
|
487
|
+
logging.error("Attempted to delete with no couch ID")
|
|
488
|
+
|
|
489
|
+
# TODO: Delete without loading first
|
|
490
|
+
try:
|
|
491
|
+
self.database.queueDelete(self.document)
|
|
492
|
+
self.database.commit()
|
|
493
|
+
except Exception as ex:
|
|
494
|
+
msg = "Error in deleting document from couch"
|
|
495
|
+
msg += str(ex)
|
|
496
|
+
msg += str(traceback.format_exc())
|
|
497
|
+
logging.error(msg)
|
|
498
|
+
raise ConfigCacheException(message=msg)
|
|
499
|
+
|
|
500
|
+
return
|
|
501
|
+
|
|
502
|
+
def getIDFromLabel(self, label):
|
|
503
|
+
"""
|
|
504
|
+
_getIDFromLabel_
|
|
505
|
+
|
|
506
|
+
Retrieve the ID of a config given it's label.
|
|
507
|
+
"""
|
|
508
|
+
results = self.database.loadView("ConfigCache", "config_by_label",
|
|
509
|
+
{"startkey": label,
|
|
510
|
+
"limit": 1})
|
|
511
|
+
|
|
512
|
+
if results["rows"][0]["key"] == label:
|
|
513
|
+
return results["rows"][0]["value"]
|
|
514
|
+
|
|
515
|
+
return None
|
|
516
|
+
|
|
517
|
+
def listAllConfigsByLabel(self):
|
|
518
|
+
"""
|
|
519
|
+
_listAllConfigsByLabel_
|
|
520
|
+
|
|
521
|
+
Retrieve a list of all the configs in the config cache. This is
|
|
522
|
+
returned in the form of a dictionary that is keyed by label.
|
|
523
|
+
"""
|
|
524
|
+
configs = {}
|
|
525
|
+
results = self.database.loadView("ConfigCache", "config_by_label")
|
|
526
|
+
|
|
527
|
+
for result in results["rows"]:
|
|
528
|
+
configs[result["key"]] = result["value"]
|
|
529
|
+
|
|
530
|
+
return configs
|
|
531
|
+
|
|
532
|
+
def __str__(self):
|
|
533
|
+
"""
|
|
534
|
+
Make something printable
|
|
535
|
+
|
|
536
|
+
"""
|
|
537
|
+
|
|
538
|
+
return self.document.__str__()
|
|
539
|
+
|
|
540
|
+
def validate(self, configID):
|
|
541
|
+
|
|
542
|
+
try:
|
|
543
|
+
# TODO: need to change to DataCache
|
|
544
|
+
# self.loadDocument(configID = configID)
|
|
545
|
+
self.loadByID(configID=configID)
|
|
546
|
+
except Exception as ex:
|
|
547
|
+
raise ConfigCacheException("Failure to load ConfigCache while validating workload: %s" % str(ex))
|
|
548
|
+
|
|
549
|
+
if self.detail:
|
|
550
|
+
duplicateCheck = {}
|
|
551
|
+
try:
|
|
552
|
+
outputModuleInfo = self.getOutputModuleInfo()
|
|
553
|
+
except Exception as ex:
|
|
554
|
+
# Something's gone wrong with trying to open the configCache
|
|
555
|
+
msg = "Error in getting output modules from ConfigCache during workload validation. Check ConfigCache formatting!"
|
|
556
|
+
raise ConfigCacheException("%s: %s" % (msg, str(ex)))
|
|
557
|
+
for outputModule in viewvalues(outputModuleInfo):
|
|
558
|
+
dataTier = outputModule.get('dataTier', None)
|
|
559
|
+
filterName = outputModule.get('filterName', None)
|
|
560
|
+
if not dataTier:
|
|
561
|
+
raise ConfigCacheException("No DataTier in output module.")
|
|
562
|
+
|
|
563
|
+
# Add dataTier to duplicate dictionary
|
|
564
|
+
if dataTier not in duplicateCheck:
|
|
565
|
+
duplicateCheck[dataTier] = []
|
|
566
|
+
if filterName in duplicateCheck[dataTier]:
|
|
567
|
+
# Then we've seen this combination before
|
|
568
|
+
raise ConfigCacheException("Duplicate dataTier/filterName combination.")
|
|
569
|
+
else:
|
|
570
|
+
duplicateCheck[dataTier].append(filterName)
|
|
571
|
+
return outputModuleInfo
|
|
572
|
+
return True
|
WMCore/Cache/__init__.py
ADDED
|
File without changes
|