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,442 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# pylint: disable=E1101, W0212
|
|
3
|
+
"""
|
|
4
|
+
_ConfigSectionTree_
|
|
5
|
+
|
|
6
|
+
Extension for a normal ConfigSection to provide a Tree structure
|
|
7
|
+
of ConfigSections
|
|
8
|
+
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
from builtins import str, bytes, object
|
|
14
|
+
|
|
15
|
+
from WMCore.Configuration import ConfigSection
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def nodeName(node):
|
|
19
|
+
"""
|
|
20
|
+
_nodeName_
|
|
21
|
+
|
|
22
|
+
Util for extracting node name
|
|
23
|
+
|
|
24
|
+
"""
|
|
25
|
+
return node._internal_name
|
|
26
|
+
|
|
27
|
+
def nodeParent(node):
|
|
28
|
+
"""
|
|
29
|
+
_nodeParent_
|
|
30
|
+
|
|
31
|
+
Util for extracting Node Parent reference
|
|
32
|
+
|
|
33
|
+
"""
|
|
34
|
+
return node._internal_parent_ref
|
|
35
|
+
|
|
36
|
+
def listNodes(topNode):
|
|
37
|
+
"""
|
|
38
|
+
_listNodes_
|
|
39
|
+
|
|
40
|
+
Util to return a list of all node names in a NodeData structure
|
|
41
|
+
returns them in execution order
|
|
42
|
+
|
|
43
|
+
"""
|
|
44
|
+
result = []
|
|
45
|
+
result.append(nodeName(topNode))
|
|
46
|
+
for child in topNode.tree.childNames:
|
|
47
|
+
result.extend(listNodes(getattr(topNode.tree.children, child)))
|
|
48
|
+
return result
|
|
49
|
+
|
|
50
|
+
def listChildNodes(topNode):
|
|
51
|
+
"""
|
|
52
|
+
_listChildNodes_
|
|
53
|
+
|
|
54
|
+
ListNodes but without including the top node
|
|
55
|
+
"""
|
|
56
|
+
result = []
|
|
57
|
+
for child in topNode.tree.childNames:
|
|
58
|
+
result.extend(listNodes(getattr(topNode.tree.children, child)))
|
|
59
|
+
return result
|
|
60
|
+
|
|
61
|
+
def listFirstGenChildNodes(topNode):
|
|
62
|
+
"""
|
|
63
|
+
_listFirstGenChildNodes_
|
|
64
|
+
|
|
65
|
+
Return a list of the first generator child nodes.
|
|
66
|
+
"""
|
|
67
|
+
# no real need to sort it, but we better have the same order between Py2/Py3
|
|
68
|
+
return sorted(list(topNode.tree.childNames))
|
|
69
|
+
|
|
70
|
+
def nodeMap(node):
|
|
71
|
+
"""
|
|
72
|
+
_nodeMap_
|
|
73
|
+
|
|
74
|
+
Generate a map of node name to node data instance
|
|
75
|
+
Note: This will *not* preserve the execution order of the child nodes
|
|
76
|
+
and should not be used to traverse and operate on nodes where order matters
|
|
77
|
+
|
|
78
|
+
"""
|
|
79
|
+
result = {}
|
|
80
|
+
result[nodeName(node)] = node
|
|
81
|
+
for child in node.tree.childNames:
|
|
82
|
+
result.update(nodeMap(getattr(node.tree.children, child)))
|
|
83
|
+
return result
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def findTopNode(node):
|
|
87
|
+
"""
|
|
88
|
+
_findTopNode_
|
|
89
|
+
|
|
90
|
+
Find the top node of a tree of nodes given an arbitrary node in the tree
|
|
91
|
+
Checks for non None parent, will also stop if the internal_treetop flag
|
|
92
|
+
is set for the parent
|
|
93
|
+
"""
|
|
94
|
+
parent = nodeParent(node)
|
|
95
|
+
if parent == None:
|
|
96
|
+
return node
|
|
97
|
+
if getattr(node, "_internal_treetop", False):
|
|
98
|
+
return node
|
|
99
|
+
|
|
100
|
+
if getattr(parent, "_internal_treetop", False):
|
|
101
|
+
return parent
|
|
102
|
+
return findTopNode(nodeParent(node))
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def allNodeNames(node):
|
|
106
|
+
"""
|
|
107
|
+
_allNodeNames_
|
|
108
|
+
|
|
109
|
+
Find the top node in the tree and then get a list of all known names
|
|
110
|
+
|
|
111
|
+
"""
|
|
112
|
+
topNode = findTopNode(node)
|
|
113
|
+
return listNodes(topNode)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def addNode(currentNode, newNode):
|
|
118
|
+
"""
|
|
119
|
+
_addNode_
|
|
120
|
+
|
|
121
|
+
Add a child node to the current node provided
|
|
122
|
+
|
|
123
|
+
"""
|
|
124
|
+
newName = nodeName(newNode)
|
|
125
|
+
allNames = allNodeNames(currentNode)
|
|
126
|
+
|
|
127
|
+
if newName in allNames:
|
|
128
|
+
msg = "Duplicate Node Name %s already exists in tree\n" % newName
|
|
129
|
+
msg += "%s\n" % allNames
|
|
130
|
+
raise RuntimeError(msg)
|
|
131
|
+
|
|
132
|
+
setattr(currentNode.tree.children, newName, newNode)
|
|
133
|
+
currentNode.tree.childNames.append(newName)
|
|
134
|
+
newNode.tree.parent = nodeName(currentNode)
|
|
135
|
+
return
|
|
136
|
+
|
|
137
|
+
def addTopNode(currentNode, newNode):
|
|
138
|
+
"""
|
|
139
|
+
_addTopNode_
|
|
140
|
+
|
|
141
|
+
Add a child node to the current node provided but insert it
|
|
142
|
+
at the head of the childNames list.
|
|
143
|
+
"""
|
|
144
|
+
newName = nodeName(newNode)
|
|
145
|
+
allNames = allNodeNames(currentNode)
|
|
146
|
+
|
|
147
|
+
if newName in allNames:
|
|
148
|
+
msg = "Duplicate Node Name %s already exists in tree\n" % newName
|
|
149
|
+
msg += "%s\n" % allNames
|
|
150
|
+
raise RuntimeError(msg)
|
|
151
|
+
|
|
152
|
+
setattr(currentNode.tree.children, newName, newNode)
|
|
153
|
+
currentNode.tree.childNames.insert(0, newName)
|
|
154
|
+
newNode.tree.parent = nodeName(currentNode)
|
|
155
|
+
return
|
|
156
|
+
|
|
157
|
+
def deleteNode(topNode, childName):
|
|
158
|
+
"""
|
|
159
|
+
_deleteNode_
|
|
160
|
+
|
|
161
|
+
Given a node within the tree, delete the child
|
|
162
|
+
with the given name if it exists
|
|
163
|
+
"""
|
|
164
|
+
if hasattr(topNode.tree.children, childName):
|
|
165
|
+
delattr(topNode.tree.children, childName)
|
|
166
|
+
topNode.tree.childNames.remove(childName)
|
|
167
|
+
|
|
168
|
+
def getNode(node, nodeNameToGet):
|
|
169
|
+
"""
|
|
170
|
+
_getNode_
|
|
171
|
+
|
|
172
|
+
Given a node within the tree, find the node with the name provided &
|
|
173
|
+
return it.
|
|
174
|
+
returns None if not found
|
|
175
|
+
|
|
176
|
+
"""
|
|
177
|
+
topNode = findTopNode(node)
|
|
178
|
+
mapping = nodeMap(topNode)
|
|
179
|
+
return mapping.get(nodeNameToGet, None)
|
|
180
|
+
|
|
181
|
+
def findTop(node):
|
|
182
|
+
"""
|
|
183
|
+
_findTop_
|
|
184
|
+
|
|
185
|
+
Ignoring tree structure, find the top node that contains the node
|
|
186
|
+
provided.
|
|
187
|
+
|
|
188
|
+
Will work for any ConfigSection, not limited to ConfigSectionTree
|
|
189
|
+
|
|
190
|
+
"""
|
|
191
|
+
if node._internal_parent_ref == None:
|
|
192
|
+
return node
|
|
193
|
+
return findTop(node._internal_parent_ref)
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def nodeIterator(node):
|
|
197
|
+
"""
|
|
198
|
+
_nodeIterator_
|
|
199
|
+
|
|
200
|
+
Generator function that delivers all nodes in order
|
|
201
|
+
|
|
202
|
+
"""
|
|
203
|
+
for i in listNodes(node):
|
|
204
|
+
yield getNode(node, i)
|
|
205
|
+
|
|
206
|
+
def nodeChildIterator(node):
|
|
207
|
+
"""
|
|
208
|
+
_nodeChildeIterator_
|
|
209
|
+
|
|
210
|
+
iterate over all nodes in order, except for the top node passed to this method
|
|
211
|
+
"""
|
|
212
|
+
for i in listChildNodes(node):
|
|
213
|
+
yield getNode(node, i)
|
|
214
|
+
|
|
215
|
+
def firstGenNodeChildIterator(node):
|
|
216
|
+
"""
|
|
217
|
+
_firstGenNodeChildIterator_
|
|
218
|
+
|
|
219
|
+
Iterator over all the first generation child nodes.
|
|
220
|
+
"""
|
|
221
|
+
for i in listFirstGenChildNodes(node):
|
|
222
|
+
yield getNode(node, i)
|
|
223
|
+
|
|
224
|
+
def format(value):
|
|
225
|
+
"""
|
|
226
|
+
_format_
|
|
227
|
+
|
|
228
|
+
format a value as python
|
|
229
|
+
keep parameters simple, trust python...
|
|
230
|
+
"""
|
|
231
|
+
if isinstance(value, (str, bytes)):
|
|
232
|
+
value = "\'%s\'" % value
|
|
233
|
+
return str(value)
|
|
234
|
+
|
|
235
|
+
def formatNative(value):
|
|
236
|
+
"""
|
|
237
|
+
_formatNative_
|
|
238
|
+
|
|
239
|
+
Like the format function, but allowing passing of ints, floats, etc.
|
|
240
|
+
"""
|
|
241
|
+
|
|
242
|
+
if isinstance(value, int):
|
|
243
|
+
return value
|
|
244
|
+
if isinstance(value, float):
|
|
245
|
+
return value
|
|
246
|
+
if isinstance(value, list):
|
|
247
|
+
return value
|
|
248
|
+
if isinstance(value, dict):
|
|
249
|
+
return value
|
|
250
|
+
else:
|
|
251
|
+
return format(value)
|
|
252
|
+
|
|
253
|
+
class TreeHelper(object):
|
|
254
|
+
"""
|
|
255
|
+
_TreeHelper_
|
|
256
|
+
|
|
257
|
+
Convienience wrapper for a ConfigSectionTree that provides
|
|
258
|
+
all the util methods as a wrapper class to avoid method name
|
|
259
|
+
and attribute collisions in the underlying ConfigSection
|
|
260
|
+
|
|
261
|
+
"""
|
|
262
|
+
def __init__(self, cfgSectTree):
|
|
263
|
+
self.data = cfgSectTree
|
|
264
|
+
|
|
265
|
+
def name(self):
|
|
266
|
+
"""get name of this node"""
|
|
267
|
+
return nodeName(self.data)
|
|
268
|
+
|
|
269
|
+
def setTopOfTree(self):
|
|
270
|
+
"""
|
|
271
|
+
flag this node as the top of the tree
|
|
272
|
+
"""
|
|
273
|
+
self.data._internal_treetop = True
|
|
274
|
+
|
|
275
|
+
def isTopOfTree(self):
|
|
276
|
+
"""
|
|
277
|
+
_isTopOfTree_
|
|
278
|
+
|
|
279
|
+
Determine if this section is the top of the tree.
|
|
280
|
+
"""
|
|
281
|
+
return self.data._internal_treetop
|
|
282
|
+
|
|
283
|
+
def listNodes(self):
|
|
284
|
+
"""list this node and all subnodes"""
|
|
285
|
+
return listNodes(self.data)
|
|
286
|
+
|
|
287
|
+
def getNode(self, nodeNameToGet):
|
|
288
|
+
"""get a node by name from this tree"""
|
|
289
|
+
return getNode(self.data, nodeNameToGet)
|
|
290
|
+
|
|
291
|
+
def getNodeWithHelper(self, nodeNameToGet):
|
|
292
|
+
"""get a node wrapped in a TreeHelper instance"""
|
|
293
|
+
return TreeHelper(getNode(self.data, nodeNameToGet))
|
|
294
|
+
|
|
295
|
+
def addNode(self, newNode):
|
|
296
|
+
"""
|
|
297
|
+
add a new Node, newNode can be a ConfigSectionTree or a TreeHelper
|
|
298
|
+
"""
|
|
299
|
+
if isinstance(newNode, TreeHelper):
|
|
300
|
+
return addNode(self.data, newNode.data)
|
|
301
|
+
return addNode(self.data, newNode)
|
|
302
|
+
|
|
303
|
+
def addTopNode(self, newNode):
|
|
304
|
+
"""
|
|
305
|
+
_addTopNode_
|
|
306
|
+
|
|
307
|
+
Add a child node to the current node provided but insert it
|
|
308
|
+
at the head of the childNames list.
|
|
309
|
+
"""
|
|
310
|
+
if isinstance(newNode, TreeHelper):
|
|
311
|
+
return addTopNode(self.data, newNode.data)
|
|
312
|
+
return addTopNode(self.data, newNode)
|
|
313
|
+
|
|
314
|
+
def deleteNode(self, nodeName):
|
|
315
|
+
"""
|
|
316
|
+
_deleteNode
|
|
317
|
+
|
|
318
|
+
Delete a child node given its name,
|
|
319
|
+
if it doesn't exists then do nothing
|
|
320
|
+
"""
|
|
321
|
+
deleteNode(self.data, nodeName)
|
|
322
|
+
return
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
def allNodeNames(self):
|
|
326
|
+
"""get list of all known node names in the tree containing this node"""
|
|
327
|
+
return allNodeNames(self.data)
|
|
328
|
+
|
|
329
|
+
def findTopNode(self):
|
|
330
|
+
"""get ref to the top node in the tree containing this node"""
|
|
331
|
+
return findTopNode(self.data)
|
|
332
|
+
|
|
333
|
+
def getTopConfigSection(self):
|
|
334
|
+
"""
|
|
335
|
+
_getTopConfigSection_
|
|
336
|
+
|
|
337
|
+
Ignore tree structure & fetch the absolute top of the pile
|
|
338
|
+
ConfigSection containing this node
|
|
339
|
+
|
|
340
|
+
"""
|
|
341
|
+
return findTop(self.data)
|
|
342
|
+
|
|
343
|
+
def nodeIterator(self):
|
|
344
|
+
"""
|
|
345
|
+
generator for processing all subnodes in execution order
|
|
346
|
+
"""
|
|
347
|
+
for i in listNodes(self.data):
|
|
348
|
+
yield getNode(self.data, i)
|
|
349
|
+
|
|
350
|
+
def nodeChildIterator(self):
|
|
351
|
+
"""
|
|
352
|
+
generator for processing all subnodes in execution order
|
|
353
|
+
"""
|
|
354
|
+
for i in listChildNodes(self.data):
|
|
355
|
+
yield getNode(self.data, i)
|
|
356
|
+
|
|
357
|
+
def firstGenNodeChildIterator(self):
|
|
358
|
+
"""
|
|
359
|
+
_fristGenNodeChildIterator_
|
|
360
|
+
|
|
361
|
+
Iterate over all the first generation child nodes.
|
|
362
|
+
"""
|
|
363
|
+
for i in listFirstGenChildNodes(self.data):
|
|
364
|
+
yield getNode(self.data, i)
|
|
365
|
+
|
|
366
|
+
def pythoniseDict(self, **options):
|
|
367
|
+
"""
|
|
368
|
+
convert self into dict of python format strings with
|
|
369
|
+
values in value position
|
|
370
|
+
|
|
371
|
+
"""
|
|
372
|
+
prefix = options.get('prefix', None)
|
|
373
|
+
sections = options.get('sections', False)
|
|
374
|
+
|
|
375
|
+
if prefix != None:
|
|
376
|
+
myName = "%s.%s" % (prefix, self.data._internal_name)
|
|
377
|
+
else:
|
|
378
|
+
myName = self.data._internal_name
|
|
379
|
+
|
|
380
|
+
result = {}
|
|
381
|
+
|
|
382
|
+
for attr in self.data._internal_settings:
|
|
383
|
+
if attr in self.data._internal_children:
|
|
384
|
+
if sections:
|
|
385
|
+
result["%s.section_(\'%s\')" % (myName, attr)] = '_Section_'
|
|
386
|
+
result.update(TreeHelper(getattr(self.data, attr)).pythoniseDict(prefix = myName))
|
|
387
|
+
continue
|
|
388
|
+
|
|
389
|
+
#This is potentially dangerous, because it adds lists, dicts.
|
|
390
|
+
result["%s.%s" %(myName, attr)] = formatNative(getattr(self.data, attr))
|
|
391
|
+
|
|
392
|
+
return result
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
def addValue(self, value):
|
|
396
|
+
"""
|
|
397
|
+
_addValue_
|
|
398
|
+
|
|
399
|
+
adds an arbitrary value as a dictionary. Can have multiple values
|
|
400
|
+
"""
|
|
401
|
+
|
|
402
|
+
if not isinstance(value, dict):
|
|
403
|
+
raise Exception("TreeHelper.addValue passed a value that was not a dictionary")
|
|
404
|
+
|
|
405
|
+
for key in value:
|
|
406
|
+
splitList = key.split('.')
|
|
407
|
+
setResult = value[key]
|
|
408
|
+
if len(splitList) == 1:
|
|
409
|
+
#Then there is only one level, and we put it here
|
|
410
|
+
setattr(self.data, key, setResult)
|
|
411
|
+
else:
|
|
412
|
+
if splitList[0] in self.data.listSections_():
|
|
413
|
+
#If the section exists, go to it directly
|
|
414
|
+
helper = TreeHelper(getattr(self.data, splitList[0]))
|
|
415
|
+
helper.addValue({splitList[1:]:setResult})
|
|
416
|
+
else:
|
|
417
|
+
#If the section doesn't exist, create it
|
|
418
|
+
self.data.section_(splitList[0])
|
|
419
|
+
helper = TreeHelper(getattr(self.data, splitList[0]))
|
|
420
|
+
helper.addValue({"".join(splitList[1:]):setResult})
|
|
421
|
+
return
|
|
422
|
+
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
class ConfigSectionTree(ConfigSection):
|
|
428
|
+
"""
|
|
429
|
+
_ConfigSectionTree_
|
|
430
|
+
|
|
431
|
+
Node Tree structure that can be embedded into a ConfigSection
|
|
432
|
+
structure
|
|
433
|
+
|
|
434
|
+
"""
|
|
435
|
+
|
|
436
|
+
def __init__(self, name):
|
|
437
|
+
ConfigSection.__init__(self, name)
|
|
438
|
+
self._internal_treetop = False
|
|
439
|
+
self.section_("tree")
|
|
440
|
+
self.tree.section_("children")
|
|
441
|
+
self.tree.childNames = []
|
|
442
|
+
self.tree.parent = None
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""
|
|
3
|
+
_PersistencyHelper_
|
|
4
|
+
|
|
5
|
+
Util class to provide a common persistency layer for ConfigSection derived
|
|
6
|
+
objects, with options to save in different formats
|
|
7
|
+
|
|
8
|
+
Placeholder for ideas at present....
|
|
9
|
+
|
|
10
|
+
"""
|
|
11
|
+
from __future__ import print_function
|
|
12
|
+
|
|
13
|
+
from future.moves.urllib.parse import urlparse
|
|
14
|
+
from future.moves.urllib.request import urlopen, Request
|
|
15
|
+
|
|
16
|
+
from builtins import object
|
|
17
|
+
|
|
18
|
+
import pickle
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class PersistencyHelper(object):
|
|
22
|
+
"""
|
|
23
|
+
_PersistencyHelper_
|
|
24
|
+
|
|
25
|
+
Save a WMSpec object to a file using pickle
|
|
26
|
+
|
|
27
|
+
Future ideas:
|
|
28
|
+
- pickle mode: read/write using pickle
|
|
29
|
+
- python mode: write using pythonise, read using import
|
|
30
|
+
Needs work to preserve tree information
|
|
31
|
+
- gzip mode: also gzip/unzip content if set to True
|
|
32
|
+
- json mode: read/write using json
|
|
33
|
+
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
def save(self, filename):
|
|
37
|
+
"""
|
|
38
|
+
_save_
|
|
39
|
+
|
|
40
|
+
Save data to a file
|
|
41
|
+
Saved format is defined depending on the extension
|
|
42
|
+
"""
|
|
43
|
+
with open(filename, 'wb') as handle:
|
|
44
|
+
# TODO: use different encoding scheme for different extension
|
|
45
|
+
# extension = filename.split(".")[-1].lower()
|
|
46
|
+
# FIXME: once both central services and WMAgent are in Py3, we can remove protocol=0
|
|
47
|
+
pickle.dump(self.data, handle, protocol=0)
|
|
48
|
+
return
|
|
49
|
+
|
|
50
|
+
def load(self, filename):
|
|
51
|
+
"""
|
|
52
|
+
_load_
|
|
53
|
+
|
|
54
|
+
Unpickle data from file
|
|
55
|
+
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
# TODO: currently support both loading from file path or url
|
|
59
|
+
# if there are more things to filter may be separate the load function
|
|
60
|
+
|
|
61
|
+
# urllib2 needs a scheme - assume local file if none given
|
|
62
|
+
if not urlparse(filename)[0]:
|
|
63
|
+
filename = 'file:' + filename
|
|
64
|
+
handle = urlopen(Request(filename, headers={"Accept": "*/*"}))
|
|
65
|
+
self.data = pickle.load(handle)
|
|
66
|
+
handle.close()
|
|
67
|
+
elif filename.startswith('file:'):
|
|
68
|
+
handle = urlopen(Request(filename, headers={"Accept": "*/*"}))
|
|
69
|
+
self.data = pickle.load(handle)
|
|
70
|
+
handle.close()
|
|
71
|
+
else:
|
|
72
|
+
# use own request class so we get authentication if needed
|
|
73
|
+
from WMCore.Services.Requests import Requests
|
|
74
|
+
request = Requests(filename)
|
|
75
|
+
data = request.makeRequest('', incoming_headers={"Accept": "*/*"}, decoder=False)
|
|
76
|
+
self.data = pickle.loads(data[0])
|
|
77
|
+
|
|
78
|
+
return
|
|
79
|
+
|
|
80
|
+
def saveCouch(self, couchUrl, couchDBName, metadata=None):
|
|
81
|
+
""" Save this spec in CouchDB. Returns URL """
|
|
82
|
+
from WMCore.Database.CMSCouch import CouchServer, CouchInternalServerError
|
|
83
|
+
metadata = metadata or {}
|
|
84
|
+
server = CouchServer(couchUrl)
|
|
85
|
+
database = server.connectDatabase(couchDBName)
|
|
86
|
+
name = self.name()
|
|
87
|
+
uri = '/%s/%s' % (couchDBName, name)
|
|
88
|
+
specuri = uri + '/spec'
|
|
89
|
+
if not database.documentExists(name):
|
|
90
|
+
self.setSpecUrl(couchUrl + specuri)
|
|
91
|
+
doc = database.put(uri, data=metadata, contentType='application/json')
|
|
92
|
+
# doc = database.commitOne(self.name(), metadata)
|
|
93
|
+
rev = doc['rev']
|
|
94
|
+
else:
|
|
95
|
+
# doc = database.get(uri+'?revs=true')
|
|
96
|
+
doc = database.document(name)
|
|
97
|
+
rev = doc['_rev']
|
|
98
|
+
|
|
99
|
+
# specuriwrev = specuri + '?rev=%s' % rev
|
|
100
|
+
# FIXME: once both central services and WMAgent are in Py3, we can remove protocol=0
|
|
101
|
+
workloadString = pickle.dumps(self.data, protocol=0)
|
|
102
|
+
# result = database.put(specuriwrev, workloadString, contentType='application/text')
|
|
103
|
+
retval = database.addAttachment(name, rev, workloadString, 'spec')
|
|
104
|
+
if retval.get('ok', False) is not True:
|
|
105
|
+
msg = "Failed to save a spec attachment in CouchDB for %s" % name
|
|
106
|
+
raise CouchInternalServerError(msg, data=None, result=retval)
|
|
107
|
+
|
|
108
|
+
url = couchUrl + specuri
|
|
109
|
+
return url
|
|
110
|
+
|
|
111
|
+
def splitCouchUrl(self, url):
|
|
112
|
+
""" Splits a URL into baseURL, dbname, and document """
|
|
113
|
+
toks = url.split('/')
|
|
114
|
+
dbname = toks[3]
|
|
115
|
+
# assume that the name "couchdb" is a redirected URL
|
|
116
|
+
if dbname == "couchdb":
|
|
117
|
+
dbname = toks[4]
|
|
118
|
+
toks = url.split('/%s/' % dbname)
|
|
119
|
+
return toks[0], dbname, toks[1]
|
|
120
|
+
|
|
121
|
+
def saveCouchUrl(self, url):
|
|
122
|
+
""" Saves the spec to a given Couch URL """
|
|
123
|
+
couchUrl, dbname, doc = self.splitCouchUrl(url)
|
|
124
|
+
return self.saveCouch(couchUrl, dbname)
|
|
125
|
+
|
|
126
|
+
def deleteCouch(self, couchUrl, couchDBName, id):
|
|
127
|
+
import WMCore.Database.CMSCouch
|
|
128
|
+
server = WMCore.Database.CMSCouch.CouchServer(couchUrl)
|
|
129
|
+
database = server.connectDatabase(couchDBName)
|
|
130
|
+
# doesn't work
|
|
131
|
+
if not database.documentExists(id):
|
|
132
|
+
print("Could not find document " + id)
|
|
133
|
+
return
|
|
134
|
+
doc = database.delete_doc(id)
|
|
135
|
+
return
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""
|
|
3
|
+
_BuildMaster_
|
|
4
|
+
|
|
5
|
+
Overseer object that traverses a task and invokes the type based builder
|
|
6
|
+
for each step
|
|
7
|
+
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
from builtins import object
|
|
14
|
+
import os
|
|
15
|
+
|
|
16
|
+
import WMCore.WMSpec.Steps.StepFactory as StepFactory
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
header = \
|
|
20
|
+
"""
|
|
21
|
+
#!/usr/bin/env python
|
|
22
|
+
|
|
23
|
+
#
|
|
24
|
+
# WMTaskSpace entry point
|
|
25
|
+
# Autogenerated by WMCore.WMSpec.Steps.BuildMaster Module
|
|
26
|
+
__all__ = []
|
|
27
|
+
|
|
28
|
+
from WMCore.WMRuntime.Bootstrap import establishTaskSpace
|
|
29
|
+
def _Locator():
|
|
30
|
+
pass
|
|
31
|
+
args = {}
|
|
32
|
+
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def initialiseWMTaskSpace(directory, taskName):
|
|
37
|
+
"""
|
|
38
|
+
_initialiseWMTaskSpace_
|
|
39
|
+
|
|
40
|
+
Build a top level working directory with the appropriate __init__.py
|
|
41
|
+
module to define the top of a working area for a job
|
|
42
|
+
|
|
43
|
+
"""
|
|
44
|
+
if not os.path.exists(directory):
|
|
45
|
+
msg = "Directory %s not found" % directory
|
|
46
|
+
raise RuntimeError(msg)
|
|
47
|
+
|
|
48
|
+
spaceDir = "%s/WMTaskSpace" % directory
|
|
49
|
+
if os.path.exists(spaceDir):
|
|
50
|
+
os.system("/bin/rm -r %s" % spaceDir)
|
|
51
|
+
os.makedirs(spaceDir)
|
|
52
|
+
|
|
53
|
+
initFile = "%s/__init__.py" % spaceDir
|
|
54
|
+
with open(initFile, "w") as handle:
|
|
55
|
+
handle.write(header)
|
|
56
|
+
handle.write("""args["TaskName"] = "%s"\n""" % taskName)
|
|
57
|
+
handle.write("""args["Locator"] = _Locator\n""")
|
|
58
|
+
handle.write("""taskSpace = establishTaskSpace(**args)\n""")
|
|
59
|
+
return spaceDir
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class BuildMaster(object):
|
|
64
|
+
"""
|
|
65
|
+
_BuildMaster_
|
|
66
|
+
|
|
67
|
+
"""
|
|
68
|
+
def __init__(self, workingDir):
|
|
69
|
+
self.workDir = workingDir
|
|
70
|
+
self.taskSpace = None
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def __call__(self, task):
|
|
74
|
+
"""
|
|
75
|
+
_operator(task)_
|
|
76
|
+
|
|
77
|
+
Invoke the builder on the task provided
|
|
78
|
+
|
|
79
|
+
TODO: Exception handling
|
|
80
|
+
|
|
81
|
+
"""
|
|
82
|
+
taskName = task.getPathName()
|
|
83
|
+
self.taskSpace = initialiseWMTaskSpace(self.workDir, taskName)
|
|
84
|
+
for step in task.steps().nodeIterator():
|
|
85
|
+
stepType = step.stepType
|
|
86
|
+
builder = StepFactory.getStepBuilder(stepType)
|
|
87
|
+
builder(step, task.name(), self.taskSpace)
|