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,485 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# encoding: utf-8
|
|
3
|
+
"""
|
|
4
|
+
DataCollectionInterface.py
|
|
5
|
+
|
|
6
|
+
Created by Dave Evans on 2010-07-30.
|
|
7
|
+
Copyright (c) 2010 Fermilab. All rights reserved.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from builtins import next
|
|
11
|
+
from future.utils import viewitems, listvalues
|
|
12
|
+
|
|
13
|
+
import logging
|
|
14
|
+
import threading
|
|
15
|
+
from operator import itemgetter
|
|
16
|
+
|
|
17
|
+
import WMCore.ACDC.CollectionTypes as CollectionTypes
|
|
18
|
+
import WMCore.Database.CouchUtils as CouchUtils
|
|
19
|
+
from WMCore.ACDC.CouchCollection import CouchCollection
|
|
20
|
+
from WMCore.ACDC.CouchFileset import CouchFileset
|
|
21
|
+
from WMCore.ACDC.CouchService import CouchService
|
|
22
|
+
from WMCore.DAOFactory import DAOFactory
|
|
23
|
+
from WMCore.DataStructs.File import File
|
|
24
|
+
from WMCore.DataStructs.LumiList import LumiList
|
|
25
|
+
from WMCore.DataStructs.Run import Run
|
|
26
|
+
from WMCore.WMException import WMException
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def mergeFilesInfo(chunkFiles):
|
|
30
|
+
"""
|
|
31
|
+
_mergeFilesInfo_
|
|
32
|
+
|
|
33
|
+
Receive a list of dicts with acdc files information and merge them when
|
|
34
|
+
it belongs to the same file. It also removes any possible duplicate lumi
|
|
35
|
+
section (for the same file) in case ErrorHandler happened to upload the
|
|
36
|
+
same job error document twice.
|
|
37
|
+
"""
|
|
38
|
+
mergedFiles = {}
|
|
39
|
+
|
|
40
|
+
# Merge ACDC docs without any real input data (aka MCFakeFile)
|
|
41
|
+
if chunkFiles[0]['lfn'].startswith('MCFakeFile'):
|
|
42
|
+
logging.info("Merging %d ACDC FakeFiles...", len(chunkFiles))
|
|
43
|
+
for acdcFile in chunkFiles:
|
|
44
|
+
fName = acdcFile['lfn']
|
|
45
|
+
if fName not in mergedFiles:
|
|
46
|
+
mergedFiles[fName] = acdcFile
|
|
47
|
+
else:
|
|
48
|
+
lumiSet = set(acdcFile['runs'][0]['lumis'])
|
|
49
|
+
if lumiSet.issubset(set(mergedFiles[fName]['runs'][0]['lumis'])):
|
|
50
|
+
# every element in lumiSet is already in mergedFiles, it's a dup!
|
|
51
|
+
continue
|
|
52
|
+
mergedFiles[fName]['events'] += acdcFile['events']
|
|
53
|
+
mergedFiles[fName]['runs'][0]['lumis'].extend(acdcFile['runs'][0]['lumis'])
|
|
54
|
+
else:
|
|
55
|
+
logging.info("Merging %d real input files...", len(chunkFiles))
|
|
56
|
+
for acdcFile in chunkFiles:
|
|
57
|
+
fName = acdcFile['lfn']
|
|
58
|
+
if fName not in mergedFiles:
|
|
59
|
+
mergedFiles[fName] = acdcFile
|
|
60
|
+
else:
|
|
61
|
+
# if one run/lumi pair is there, then it's a duplicate job
|
|
62
|
+
runNum = acdcFile['runs'][0]['run_number']
|
|
63
|
+
lumiSet = set(acdcFile['runs'][0]['lumis'])
|
|
64
|
+
if _isRunMaskDuplicate(runNum, lumiSet, mergedFiles[fName]['runs']):
|
|
65
|
+
continue
|
|
66
|
+
# union of parents
|
|
67
|
+
allParents = list(set(mergedFiles[fName]['parents']).union(acdcFile['parents']))
|
|
68
|
+
mergedFiles[fName]['parents'] = allParents
|
|
69
|
+
# just add up run/lumi pairs (don't try to merge them)
|
|
70
|
+
mergedFiles[fName]['runs'].extend(acdcFile['runs'])
|
|
71
|
+
_mergeRealDataRunLumis(mergedFiles)
|
|
72
|
+
|
|
73
|
+
logging.info(" ... resulted in %d unique files.", len(mergedFiles))
|
|
74
|
+
return listvalues(mergedFiles)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def _isRunMaskDuplicate(run, lumis, runLumis):
|
|
78
|
+
"""
|
|
79
|
+
Test whether run and lumi is a subset of one of the
|
|
80
|
+
runLumi pairs in runLumis
|
|
81
|
+
:param run: integer run number
|
|
82
|
+
:param lumi: set of lumis
|
|
83
|
+
:param runLumis: list of dictionaries containing run and lumis
|
|
84
|
+
"""
|
|
85
|
+
for runLumi in runLumis:
|
|
86
|
+
if run == runLumi['run_number']:
|
|
87
|
+
if lumis.issubset(runLumi['lumis']):
|
|
88
|
+
return True
|
|
89
|
+
return False
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def _mergeRealDataRunLumis(mergedFiles):
|
|
93
|
+
"""
|
|
94
|
+
Function to scan and merge run/lumi pairs in the same file, thus
|
|
95
|
+
getting rid of duplicate lumi sections in real data.
|
|
96
|
+
:param mergedFiles: list of dictionaries with ACDC file info
|
|
97
|
+
:return: update data structure in place
|
|
98
|
+
"""
|
|
99
|
+
for fname in mergedFiles:
|
|
100
|
+
runLumis = {}
|
|
101
|
+
for item in mergedFiles[fname]['runs']:
|
|
102
|
+
runLumis.setdefault(item['run_number'], [])
|
|
103
|
+
runLumis[item['run_number']].extend(item['lumis'])
|
|
104
|
+
# now write those back to the original data structure
|
|
105
|
+
mergedFiles[fname]['runs'] = []
|
|
106
|
+
for run, lumis in viewitems(runLumis):
|
|
107
|
+
mergedFiles[fname]['runs'].append({'run_number': run,
|
|
108
|
+
'lumis': list(set(lumis))})
|
|
109
|
+
return
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def fixupMCFakeLumis(files, acdcVersion):
|
|
113
|
+
"""
|
|
114
|
+
This is complicated!
|
|
115
|
+
The lumi list uploaded to the ACDC Server is incorrect for, at least,
|
|
116
|
+
the MCFakeFiles. Reason being that it also includes the LastLumi, which
|
|
117
|
+
is actually not processed by the job, but just set as an upper boundary
|
|
118
|
+
(inclusiveMask). However, if the job is the last one for a given MCFakeFile,
|
|
119
|
+
then it might have a single lumi section in the list, and in this case it
|
|
120
|
+
would be correct...
|
|
121
|
+
|
|
122
|
+
This function updates data in-place.
|
|
123
|
+
|
|
124
|
+
For more info, see issue: https://github.com/dmwm/WMCore/issues/9126
|
|
125
|
+
"""
|
|
126
|
+
for fname, fvalues in viewitems(files):
|
|
127
|
+
if fname.startswith('MCFakeFile') and acdcVersion < 2:
|
|
128
|
+
for run in fvalues['runs']:
|
|
129
|
+
if len(run['lumis']) > 1:
|
|
130
|
+
run['lumis'].pop()
|
|
131
|
+
else:
|
|
132
|
+
break
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
class ACDCDCSException(WMException):
|
|
136
|
+
"""
|
|
137
|
+
Yet another dummy variable class
|
|
138
|
+
|
|
139
|
+
"""
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
class DataCollectionService(CouchService):
|
|
143
|
+
def __init__(self, url, database, **opts):
|
|
144
|
+
CouchService.__init__(self, url=url, database=database, **opts)
|
|
145
|
+
|
|
146
|
+
@CouchUtils.connectToCouch
|
|
147
|
+
def getDataCollection(self, collName):
|
|
148
|
+
"""
|
|
149
|
+
_getDataCollection_
|
|
150
|
+
|
|
151
|
+
Get a data collection by name
|
|
152
|
+
"""
|
|
153
|
+
coll = CouchCollection(name=collName, database=self.database, url=self.url)
|
|
154
|
+
|
|
155
|
+
coll.populate()
|
|
156
|
+
return coll
|
|
157
|
+
|
|
158
|
+
@CouchUtils.connectToCouch
|
|
159
|
+
def failedJobs(self, failedJobs, useMask=True):
|
|
160
|
+
"""
|
|
161
|
+
_failedJobs_
|
|
162
|
+
|
|
163
|
+
Given a list of failed jobs, sort them into Filesets and record them
|
|
164
|
+
|
|
165
|
+
NOTE: jobs must have a non-standard task, workflow attributes assigned to them.
|
|
166
|
+
"""
|
|
167
|
+
# first we sort the list of dictionary by two keys: workflow then task
|
|
168
|
+
failedJobs.sort(key=itemgetter('workflow'))
|
|
169
|
+
failedJobs.sort(key=itemgetter('task'))
|
|
170
|
+
|
|
171
|
+
previousWorkflow = ""
|
|
172
|
+
previousTask = ""
|
|
173
|
+
for job in failedJobs:
|
|
174
|
+
try:
|
|
175
|
+
workflow = job['workflow']
|
|
176
|
+
taskName = job['task']
|
|
177
|
+
except KeyError as ex:
|
|
178
|
+
msg = "Missing required, non-standard key %s in job in ACDC.DataCollectionService" % (str(ex))
|
|
179
|
+
logging.error(msg)
|
|
180
|
+
raise ACDCDCSException(msg)
|
|
181
|
+
|
|
182
|
+
if workflow != previousWorkflow:
|
|
183
|
+
coll = CouchCollection(database=self.database, url=self.url,
|
|
184
|
+
name=workflow,
|
|
185
|
+
type=CollectionTypes.DataCollection)
|
|
186
|
+
if taskName != previousTask:
|
|
187
|
+
fileset = CouchFileset(database=self.database, url=self.url,
|
|
188
|
+
name=taskName)
|
|
189
|
+
coll.addFileset(fileset)
|
|
190
|
+
inputFiles = job['input_files']
|
|
191
|
+
for fInfo in inputFiles:
|
|
192
|
+
if int(fInfo["merged"]) == 1: # Looks like Oracle and MySQL return diff type
|
|
193
|
+
fInfo["parents"] = []
|
|
194
|
+
elif fInfo.get("parents", []):
|
|
195
|
+
firstParent = next(iter(fInfo["parents"]))
|
|
196
|
+
if "/store/unmerged/" in firstParent:
|
|
197
|
+
# parents and input files are unmerged files - need to find merged ascendant
|
|
198
|
+
fInfo["parents"] = list(getMergedParents(fInfo["parents"]))
|
|
199
|
+
elif "MCFakeFile" in firstParent:
|
|
200
|
+
fInfo["parents"] = []
|
|
201
|
+
# other case, fInfo["parents"] all or merged parents
|
|
202
|
+
if useMask:
|
|
203
|
+
fileset.add(files=inputFiles, mask=job['mask'])
|
|
204
|
+
else:
|
|
205
|
+
fileset.add(files=inputFiles)
|
|
206
|
+
|
|
207
|
+
previousWorkflow = workflow
|
|
208
|
+
previousTask = taskName
|
|
209
|
+
|
|
210
|
+
return
|
|
211
|
+
|
|
212
|
+
@staticmethod
|
|
213
|
+
def _sortLocationInPlace(fileInfo):
|
|
214
|
+
fileInfo["locations"].sort()
|
|
215
|
+
return fileInfo["locations"]
|
|
216
|
+
|
|
217
|
+
@CouchUtils.connectToCouch
|
|
218
|
+
def _getFilesetInfo(self, collectionName, filesetName, chunkOffset=None, chunkSize=None):
|
|
219
|
+
"""
|
|
220
|
+
Fetches all the data from the ACDC Server that matches the collection
|
|
221
|
+
and fileset names.
|
|
222
|
+
"""
|
|
223
|
+
option = {"include_docs": True, "reduce": False}
|
|
224
|
+
keys = [[collectionName, filesetName]]
|
|
225
|
+
results = self.couchdb.loadView("ACDC", "coll_fileset_docs", option, keys)
|
|
226
|
+
|
|
227
|
+
filesInfo = []
|
|
228
|
+
for row in results["rows"]:
|
|
229
|
+
files = row["doc"].get("files", [])
|
|
230
|
+
fixupMCFakeLumis(files, row['doc'].get("acdc_version", 1))
|
|
231
|
+
filesInfo.extend(listvalues(files))
|
|
232
|
+
|
|
233
|
+
# second lfn sort
|
|
234
|
+
filesInfo.sort(key=lambda x: x["lfn"])
|
|
235
|
+
# primary location sort (python preserve sort result)
|
|
236
|
+
filesInfo.sort(key=lambda x: "".join(self._sortLocationInPlace(x)))
|
|
237
|
+
|
|
238
|
+
if chunkOffset is not None and chunkSize is not None:
|
|
239
|
+
return filesInfo[chunkOffset: chunkOffset + chunkSize]
|
|
240
|
+
else:
|
|
241
|
+
return filesInfo
|
|
242
|
+
|
|
243
|
+
@CouchUtils.connectToCouch
|
|
244
|
+
def chunkFileset(self, collectionName, filesetName, chunkSize=100):
|
|
245
|
+
"""
|
|
246
|
+
_chunkFileset_
|
|
247
|
+
|
|
248
|
+
Split all of the fileset in a given collection/task into chunks. This
|
|
249
|
+
will return a list of dictionaries that contain the offset into the
|
|
250
|
+
fileset and a summary of files/events/lumis that are in the fileset
|
|
251
|
+
chunk.
|
|
252
|
+
"""
|
|
253
|
+
chunks = []
|
|
254
|
+
results = self._getFilesetInfo(collectionName, filesetName)
|
|
255
|
+
|
|
256
|
+
totalFiles = 0
|
|
257
|
+
currentLocation = None
|
|
258
|
+
numFilesInBlock = 0
|
|
259
|
+
numLumisInBlock = 0
|
|
260
|
+
numEventsInBlock = 0
|
|
261
|
+
|
|
262
|
+
for value in results:
|
|
263
|
+
if currentLocation is None:
|
|
264
|
+
currentLocation = value["locations"]
|
|
265
|
+
if numFilesInBlock == chunkSize or currentLocation != value["locations"]:
|
|
266
|
+
chunks.append({"offset": totalFiles, "files": numFilesInBlock,
|
|
267
|
+
"events": numEventsInBlock, "lumis": numLumisInBlock,
|
|
268
|
+
"locations": currentLocation})
|
|
269
|
+
totalFiles += numFilesInBlock
|
|
270
|
+
currentLocation = value["locations"]
|
|
271
|
+
numFilesInBlock = 0
|
|
272
|
+
numLumisInBlock = 0
|
|
273
|
+
numEventsInBlock = 0
|
|
274
|
+
|
|
275
|
+
numFilesInBlock += 1
|
|
276
|
+
lumis = 0
|
|
277
|
+
for runLumi in value["runs"]:
|
|
278
|
+
lumis += len(runLumi["lumis"])
|
|
279
|
+
numLumisInBlock += lumis
|
|
280
|
+
numEventsInBlock += value["events"]
|
|
281
|
+
|
|
282
|
+
if numFilesInBlock > 0:
|
|
283
|
+
chunks.append({"offset": totalFiles, "files": numFilesInBlock,
|
|
284
|
+
"events": numEventsInBlock, "lumis": numLumisInBlock,
|
|
285
|
+
"locations": currentLocation})
|
|
286
|
+
return chunks
|
|
287
|
+
|
|
288
|
+
@CouchUtils.connectToCouch
|
|
289
|
+
def singleChunkFileset(self, collectionName, filesetName):
|
|
290
|
+
"""
|
|
291
|
+
_singleChunkFileset_
|
|
292
|
+
|
|
293
|
+
Put all of the fileset in a given collection/task into a single chunk. This
|
|
294
|
+
will return a dictionary that contains the offset into the
|
|
295
|
+
fileset and a summary of files/events/lumis that are in the fileset
|
|
296
|
+
chunk.
|
|
297
|
+
"""
|
|
298
|
+
|
|
299
|
+
files = self._getFilesetInfo(collectionName, filesetName)
|
|
300
|
+
|
|
301
|
+
locations = set()
|
|
302
|
+
numFilesInBlock = 0
|
|
303
|
+
numLumisInBlock = 0
|
|
304
|
+
numEventsInBlock = 0
|
|
305
|
+
|
|
306
|
+
for fileInfo in files:
|
|
307
|
+
locations |= set(fileInfo["locations"])
|
|
308
|
+
|
|
309
|
+
numFilesInBlock += 1
|
|
310
|
+
lumis = 0
|
|
311
|
+
for runLumi in fileInfo["runs"]:
|
|
312
|
+
lumis += len(runLumi["lumis"])
|
|
313
|
+
numLumisInBlock += lumis
|
|
314
|
+
numEventsInBlock += fileInfo["events"]
|
|
315
|
+
|
|
316
|
+
return {"offset": 0, "files": numFilesInBlock,
|
|
317
|
+
"events": numEventsInBlock, "lumis": numLumisInBlock,
|
|
318
|
+
"locations": locations}
|
|
319
|
+
|
|
320
|
+
@CouchUtils.connectToCouch
|
|
321
|
+
def getChunkInfo(self, collectionName, filesetName, chunkOffset, chunkSize):
|
|
322
|
+
"""
|
|
323
|
+
_getChunkInfo_
|
|
324
|
+
|
|
325
|
+
Retrieve metadata for a particular chunk.
|
|
326
|
+
"""
|
|
327
|
+
|
|
328
|
+
files = self._getFilesetInfo(collectionName, filesetName, chunkOffset, chunkSize)
|
|
329
|
+
|
|
330
|
+
totalFiles = 0
|
|
331
|
+
currentLocation = set()
|
|
332
|
+
numFilesInBlock = 0
|
|
333
|
+
numLumisInBlock = 0
|
|
334
|
+
numEventsInBlock = 0
|
|
335
|
+
|
|
336
|
+
for fileInfo in files:
|
|
337
|
+
# locations is a list
|
|
338
|
+
currentLocation.update(fileInfo["locations"])
|
|
339
|
+
numFilesInBlock += 1
|
|
340
|
+
lumis = 0
|
|
341
|
+
for runLumi in fileInfo["runs"]:
|
|
342
|
+
lumis += len(runLumi["lumis"])
|
|
343
|
+
numLumisInBlock += lumis
|
|
344
|
+
numEventsInBlock += fileInfo["events"]
|
|
345
|
+
|
|
346
|
+
return {"offset": totalFiles, "files": numFilesInBlock,
|
|
347
|
+
"events": numEventsInBlock, "lumis": numLumisInBlock,
|
|
348
|
+
"locations": list(currentLocation)}
|
|
349
|
+
|
|
350
|
+
@CouchUtils.connectToCouch
|
|
351
|
+
def getChunkFiles(self, collectionName, filesetName, chunkOffset, chunkSize=100):
|
|
352
|
+
"""
|
|
353
|
+
_getChunkFiles_
|
|
354
|
+
|
|
355
|
+
Retrieve a chunk of files from the given collection and task.
|
|
356
|
+
"""
|
|
357
|
+
chunkFiles = []
|
|
358
|
+
files = self._getFilesetInfo(collectionName, filesetName, chunkOffset, chunkSize)
|
|
359
|
+
|
|
360
|
+
files = mergeFilesInfo(files)
|
|
361
|
+
for fileInfo in files:
|
|
362
|
+
newFile = File(lfn=fileInfo["lfn"], size=fileInfo["size"],
|
|
363
|
+
events=fileInfo["events"], parents=set(fileInfo["parents"]),
|
|
364
|
+
locations=set(fileInfo["locations"]), merged=fileInfo["merged"])
|
|
365
|
+
for run in fileInfo["runs"]:
|
|
366
|
+
newRun = Run(run["run_number"])
|
|
367
|
+
newRun.extendLumis(run["lumis"])
|
|
368
|
+
newFile.addRun(newRun)
|
|
369
|
+
|
|
370
|
+
chunkFiles.append(newFile)
|
|
371
|
+
|
|
372
|
+
return chunkFiles
|
|
373
|
+
|
|
374
|
+
@CouchUtils.connectToCouch
|
|
375
|
+
def getProductionACDCInfo(self, collectionID, taskName):
|
|
376
|
+
"""
|
|
377
|
+
_getFileInfo_
|
|
378
|
+
|
|
379
|
+
Query ACDC for all of the files in the given collection and task.
|
|
380
|
+
Return an entry for each file with lumis and event info.
|
|
381
|
+
Format is:
|
|
382
|
+
[{'lfn': 'someLfn',
|
|
383
|
+
'first_event': XXX,
|
|
384
|
+
'lumis': [lumi0,lumi1],
|
|
385
|
+
'events': XXX}]
|
|
386
|
+
"""
|
|
387
|
+
files = self._getFilesetInfo(collectionID, taskName)
|
|
388
|
+
files = mergeFilesInfo(files)
|
|
389
|
+
|
|
390
|
+
acdcInfo = []
|
|
391
|
+
for value in files:
|
|
392
|
+
fileInfo = {"lfn": value["lfn"],
|
|
393
|
+
"first_event": value["first_event"],
|
|
394
|
+
"lumis": value["runs"][0]["lumis"],
|
|
395
|
+
"events": value["events"]}
|
|
396
|
+
acdcInfo.append(fileInfo)
|
|
397
|
+
return acdcInfo
|
|
398
|
+
|
|
399
|
+
@CouchUtils.connectToCouch
|
|
400
|
+
def getLumiWhitelist(self, collectionID, taskName):
|
|
401
|
+
"""
|
|
402
|
+
_getLumiWhitelist_
|
|
403
|
+
|
|
404
|
+
Query ACDC for all of the files in the given collection and task.
|
|
405
|
+
Generate a run and lumi whitelist for the given files with the following
|
|
406
|
+
format:
|
|
407
|
+
{"run1": [[lumi1, lumi4], [lumi6, lumi10]],
|
|
408
|
+
"run3": [lumi5, lumi10]}
|
|
409
|
+
|
|
410
|
+
Note that the run numbers are strings.
|
|
411
|
+
"""
|
|
412
|
+
|
|
413
|
+
files = self._getFilesetInfo(collectionID, taskName)
|
|
414
|
+
|
|
415
|
+
allRuns = {}
|
|
416
|
+
whiteList = {}
|
|
417
|
+
|
|
418
|
+
for fileInfo in files:
|
|
419
|
+
for run in fileInfo["runs"]:
|
|
420
|
+
if run["run_number"] not in allRuns:
|
|
421
|
+
allRuns[run["run_number"]] = []
|
|
422
|
+
allRuns[run["run_number"]].extend(run["lumis"])
|
|
423
|
+
|
|
424
|
+
for run in allRuns:
|
|
425
|
+
lumis = []
|
|
426
|
+
lumis.extend(set(allRuns[run]))
|
|
427
|
+
lumis.sort()
|
|
428
|
+
|
|
429
|
+
whiteList[str(run)] = []
|
|
430
|
+
lastLumi = None
|
|
431
|
+
currentSet = None
|
|
432
|
+
|
|
433
|
+
while len(lumis) > 0:
|
|
434
|
+
currentLumi = lumis.pop(0)
|
|
435
|
+
if currentLumi - 1 != lastLumi:
|
|
436
|
+
if currentSet is None:
|
|
437
|
+
currentSet = [currentLumi]
|
|
438
|
+
else:
|
|
439
|
+
currentSet.append(lastLumi)
|
|
440
|
+
whiteList[str(run)].append(currentSet)
|
|
441
|
+
currentSet = [currentLumi]
|
|
442
|
+
|
|
443
|
+
lastLumi = currentLumi
|
|
444
|
+
|
|
445
|
+
currentSet.append(lastLumi)
|
|
446
|
+
whiteList[str(run)].append(currentSet)
|
|
447
|
+
|
|
448
|
+
return whiteList
|
|
449
|
+
|
|
450
|
+
def getLumilistWhitelist(self, collectionID, taskName):
|
|
451
|
+
"""
|
|
452
|
+
Args:
|
|
453
|
+
collectionID, taskName: Parameters for getLumiWhitelist
|
|
454
|
+
|
|
455
|
+
Returns: a LumiList object describing the lumi list from the collection
|
|
456
|
+
"""
|
|
457
|
+
|
|
458
|
+
lumiList = LumiList(compactList=self.getLumiWhitelist(collectionID, taskName))
|
|
459
|
+
return lumiList
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
def getMergedParents(childLFNs):
|
|
463
|
+
myThread = threading.currentThread()
|
|
464
|
+
daoFactory = DAOFactory(package="WMCore.WMBS", logger=myThread.logger,
|
|
465
|
+
dbinterface=myThread.dbi)
|
|
466
|
+
|
|
467
|
+
getParentInfoAction = daoFactory(classname="Files.GetParentInfo")
|
|
468
|
+
|
|
469
|
+
parentsInfo = getParentInfoAction.execute(childLFNs)
|
|
470
|
+
newParents = set()
|
|
471
|
+
unmergedParents = set()
|
|
472
|
+
for parentInfo in parentsInfo:
|
|
473
|
+
# This will catch straight to merge files that do not have redneck
|
|
474
|
+
# parents. We will mark the straight to merge file from the job
|
|
475
|
+
# as a child of the merged parent.
|
|
476
|
+
if int(parentInfo["merged"]) == 1:
|
|
477
|
+
newParents.add(parentInfo["lfn"])
|
|
478
|
+
else:
|
|
479
|
+
unmergedParents.add(parentInfo["lfn"])
|
|
480
|
+
|
|
481
|
+
if len(unmergedParents) > 0:
|
|
482
|
+
grandParentSet = getMergedParents(unmergedParents)
|
|
483
|
+
newParents.union(grandParentSet)
|
|
484
|
+
|
|
485
|
+
return newParents
|
WMCore/ACDC/Fileset.py
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""
|
|
3
|
+
Fileset.py
|
|
4
|
+
|
|
5
|
+
Created by Dave Evans on 2010-03-18.
|
|
6
|
+
Copyright (c) 2010 Fermilab. All rights reserved.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from WMCore.DataStructs.WMObject import WMObject
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class Fileset(dict, WMObject):
|
|
13
|
+
"""
|
|
14
|
+
_Fileset_
|
|
15
|
+
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
def __init__(self, **options):
|
|
19
|
+
dict.__init__(self)
|
|
20
|
+
WMObject.__init__(self)
|
|
21
|
+
self.setdefault("name", None)
|
|
22
|
+
self.setdefault("files", {})
|
|
23
|
+
self.update(options)
|
|
24
|
+
self.collection = None
|
|
25
|
+
|
|
26
|
+
def setCollection(self, collection):
|
|
27
|
+
"""
|
|
28
|
+
_setCollection_
|
|
29
|
+
|
|
30
|
+
Associate this fileset with a collection.
|
|
31
|
+
"""
|
|
32
|
+
self.collectionName = collection["name"]
|
|
33
|
+
self.collectionType = collection["type"]
|
|
34
|
+
return
|
|
35
|
+
|
|
36
|
+
def create(self):
|
|
37
|
+
"""
|
|
38
|
+
_create_
|
|
39
|
+
|
|
40
|
+
create a new fileset within a collection
|
|
41
|
+
"""
|
|
42
|
+
pass
|
|
43
|
+
|
|
44
|
+
def populate(self):
|
|
45
|
+
"""
|
|
46
|
+
_populate_
|
|
47
|
+
|
|
48
|
+
populate information about this fileset
|
|
49
|
+
"""
|
|
50
|
+
pass
|
|
51
|
+
|
|
52
|
+
def drop(self):
|
|
53
|
+
"""
|
|
54
|
+
_drop_
|
|
55
|
+
|
|
56
|
+
Remove the fileset from its collection
|
|
57
|
+
"""
|
|
58
|
+
pass
|
|
59
|
+
|
|
60
|
+
def add(self, files, mask):
|
|
61
|
+
"""
|
|
62
|
+
_add_
|
|
63
|
+
|
|
64
|
+
Add files to this fileset
|
|
65
|
+
files should be a list of WMCore.DataStruct.File objects
|
|
66
|
+
|
|
67
|
+
"""
|
|
68
|
+
pass
|
|
69
|
+
|
|
70
|
+
def listFiles(self):
|
|
71
|
+
"""
|
|
72
|
+
_listFiles_
|
|
73
|
+
|
|
74
|
+
Iterate/yield the files in this fileset
|
|
75
|
+
"""
|
|
76
|
+
pass
|
|
77
|
+
|
|
78
|
+
def fileCount(self):
|
|
79
|
+
"""
|
|
80
|
+
_fileCount_
|
|
81
|
+
|
|
82
|
+
Total number of files in this fileset
|
|
83
|
+
"""
|
|
84
|
+
pass
|
|
85
|
+
|
|
86
|
+
def fileset(self):
|
|
87
|
+
"""
|
|
88
|
+
_fileset_
|
|
89
|
+
|
|
90
|
+
Create and return an instance of a WMCore.DataStructs.Fileset
|
|
91
|
+
containing the files in this (ACDC) fileset
|
|
92
|
+
|
|
93
|
+
"""
|
|
94
|
+
pass
|
WMCore/ACDC/__init__.py
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
_Alarm_
|
|
5
|
+
|
|
6
|
+
Silly, pointless, bogus classes that you have to have
|
|
7
|
+
in order to raise an alarm
|
|
8
|
+
|
|
9
|
+
Mainly, this is just where I stick the documentation:
|
|
10
|
+
|
|
11
|
+
To run this you need to use python's signal module:
|
|
12
|
+
|
|
13
|
+
First set the alarm:
|
|
14
|
+
signal.signal(signal.SIGALRM, alarmHandler)
|
|
15
|
+
signal.alarm(waitTime)
|
|
16
|
+
|
|
17
|
+
Then run your code:
|
|
18
|
+
try:
|
|
19
|
+
doX()
|
|
20
|
+
except Alarm:
|
|
21
|
+
pass
|
|
22
|
+
|
|
23
|
+
Afterwards, reset the alarm
|
|
24
|
+
|
|
25
|
+
signal.alarm(0)
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
class Alarm(Exception):
|
|
29
|
+
"""
|
|
30
|
+
Silly exception
|
|
31
|
+
|
|
32
|
+
"""
|
|
33
|
+
pass
|
|
34
|
+
|
|
35
|
+
def alarmHandler(signum, frame):
|
|
36
|
+
"""
|
|
37
|
+
Silly handler (raise if you have an alarm)
|
|
38
|
+
"""
|
|
39
|
+
raise Alarm
|