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,173 @@
|
|
|
1
|
+
#! /bin/env python
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
A service class for retrieving data from McM using
|
|
5
|
+
an SSO cookie since it sits behind CERN SSO
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from builtins import str, object
|
|
9
|
+
import json
|
|
10
|
+
import os
|
|
11
|
+
import pycurl
|
|
12
|
+
import subprocess
|
|
13
|
+
import logging
|
|
14
|
+
from typing import List
|
|
15
|
+
from io import BytesIO
|
|
16
|
+
from WMCore.WMException import WMException
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class McMNoDataError(WMException):
|
|
20
|
+
"""
|
|
21
|
+
_McMNoDataError_
|
|
22
|
+
McM responded but has no data for the request
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
def __init__(self):
|
|
26
|
+
WMException.__init__(self, 'McM responded correctly but has no data')
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class McM(object):
|
|
30
|
+
"""
|
|
31
|
+
A service class for retrieving data from McM using
|
|
32
|
+
an SSO cookie since it sits behind CERN SSO
|
|
33
|
+
'key' must be unencrypted
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
def __init__(self, url='https://cms-pdmv.cern.ch/mcm', tmpDir='/tmp'):
|
|
37
|
+
self.url = url
|
|
38
|
+
self.tmpDir = tmpDir
|
|
39
|
+
self.logger = self._get_logger()
|
|
40
|
+
self.cookieFile = None
|
|
41
|
+
|
|
42
|
+
def __enter__(self):
|
|
43
|
+
self._krb_ticket()
|
|
44
|
+
self._get_cookie()
|
|
45
|
+
return self
|
|
46
|
+
|
|
47
|
+
def __exit__(self, exception_type, exception_value, traceback):
|
|
48
|
+
if self.cookieFile:
|
|
49
|
+
try:
|
|
50
|
+
os.remove(self.cookieFile)
|
|
51
|
+
except OSError:
|
|
52
|
+
return
|
|
53
|
+
return
|
|
54
|
+
|
|
55
|
+
def _get_logger(self) -> logging.Logger:
|
|
56
|
+
"""
|
|
57
|
+
Create a logger for McM client
|
|
58
|
+
"""
|
|
59
|
+
logger: logging.Logger = logging.getLogger("mcm_client")
|
|
60
|
+
date_format: str = "%Y-%m-%d %H:%M:%S %z"
|
|
61
|
+
format: str = "[%(levelname)s][%(name)s][%(asctime)s]: %(message)s"
|
|
62
|
+
formatter: logging.Formatter = logging.Formatter(fmt=format, datefmt=date_format)
|
|
63
|
+
handler: logging.StreamHandler = logging.StreamHandler()
|
|
64
|
+
|
|
65
|
+
handler.setLevel(logging.INFO)
|
|
66
|
+
handler.setFormatter(formatter)
|
|
67
|
+
logger.addHandler(handler)
|
|
68
|
+
return logger
|
|
69
|
+
|
|
70
|
+
def _krb_ticket(self) -> None:
|
|
71
|
+
"""
|
|
72
|
+
Check there is a valid Kerberos ticket for requesting a SSO
|
|
73
|
+
cookie. Raise a RuntimeError if there is not one.
|
|
74
|
+
"""
|
|
75
|
+
process = subprocess.Popen(["klist", "-f"],
|
|
76
|
+
stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=False)
|
|
77
|
+
stdout: str = process.communicate()[0].decode("utf-8")
|
|
78
|
+
if process.returncode != 0:
|
|
79
|
+
msg: str = ("There is no valid Kerberos ticket for requesting a SSO cookie. "
|
|
80
|
+
"Please make sure to provide one for your runtime environment"
|
|
81
|
+
)
|
|
82
|
+
self.logger.error(msg)
|
|
83
|
+
raise RuntimeError("FATAL -- %s\nError msg: %s" % (msg, stdout))
|
|
84
|
+
|
|
85
|
+
def _get_cookie(self) -> None:
|
|
86
|
+
"""
|
|
87
|
+
Request a SSO cookie to authenticate to McM.
|
|
88
|
+
"""
|
|
89
|
+
self.cookieFile = os.path.join(self.tmpDir, 'ssoCookie.txt')
|
|
90
|
+
command: List[str] = ["auth-get-sso-cookie", "-u", self.url, "-o", self.cookieFile, "-vv"]
|
|
91
|
+
callback_not_invoked: str = "DEBUG: Not automatically redirected: trying SAML authentication"
|
|
92
|
+
cookie_stored: str = "INFO: Saving cookies"
|
|
93
|
+
|
|
94
|
+
process = subprocess.Popen(command, stdout=subprocess.PIPE,
|
|
95
|
+
stderr=subprocess.STDOUT, shell=False)
|
|
96
|
+
stdout: str = process.communicate()[0].decode("utf-8")
|
|
97
|
+
stdout_list: List[str] = stdout.strip().split("\n")
|
|
98
|
+
if process.returncode != 0:
|
|
99
|
+
raise RuntimeError("FATAL -- Error requesting SSO cookie\nError msg: %s" % (stdout))
|
|
100
|
+
|
|
101
|
+
if callback_not_invoked in stdout:
|
|
102
|
+
callback_idx: int = stdout_list.index(callback_not_invoked)
|
|
103
|
+
stored_after_issue: bool = cookie_stored in stdout_list[callback_idx + 1]
|
|
104
|
+
if stored_after_issue:
|
|
105
|
+
msg: str = ("Callback method was not invoked. "
|
|
106
|
+
"Please make sure the provided Kerberos ticket is not linked to an account with 2FA"
|
|
107
|
+
)
|
|
108
|
+
raise RuntimeError(msg)
|
|
109
|
+
|
|
110
|
+
def _getURL(self, extendURL):
|
|
111
|
+
"""
|
|
112
|
+
Fetch an MCM URL with CURL using the SSO cookie.
|
|
113
|
+
Only intended to be used internally
|
|
114
|
+
"""
|
|
115
|
+
|
|
116
|
+
try:
|
|
117
|
+
b = BytesIO()
|
|
118
|
+
c = pycurl.Curl()
|
|
119
|
+
|
|
120
|
+
fullUrl = '%s/%s' % (self.url, extendURL)
|
|
121
|
+
|
|
122
|
+
c.setopt(c.URL, fullUrl)
|
|
123
|
+
c.setopt(c.SSL_VERIFYPEER, False)
|
|
124
|
+
c.setopt(c.SSL_VERIFYHOST, False)
|
|
125
|
+
c.setopt(c.FOLLOWLOCATION, True)
|
|
126
|
+
c.setopt(c.COOKIEJAR, self.cookieFile)
|
|
127
|
+
c.setopt(c.COOKIEFILE, self.cookieFile)
|
|
128
|
+
c.setopt(c.WRITEFUNCTION, b.write)
|
|
129
|
+
c.perform()
|
|
130
|
+
if c.getinfo(pycurl.HTTP_CODE) != 200:
|
|
131
|
+
raise IOError
|
|
132
|
+
except:
|
|
133
|
+
c.close()
|
|
134
|
+
raise IOError('Was not able to fetch or decode URL from McM')
|
|
135
|
+
|
|
136
|
+
try:
|
|
137
|
+
body = b.getvalue()
|
|
138
|
+
res = json.loads(body)
|
|
139
|
+
except ValueError:
|
|
140
|
+
c.close()
|
|
141
|
+
raise IOError('Was not able to decode JSON from McM')
|
|
142
|
+
|
|
143
|
+
c.close()
|
|
144
|
+
return res
|
|
145
|
+
|
|
146
|
+
def getHistory(self, prepID):
|
|
147
|
+
"""
|
|
148
|
+
Get the history record which has who did what to an McM request
|
|
149
|
+
"""
|
|
150
|
+
|
|
151
|
+
try:
|
|
152
|
+
url = 'search?db_name=batches&contains=%s&get_raw' % prepID
|
|
153
|
+
res = self._getURL(url)
|
|
154
|
+
history = res.get("results", [])[0].get("history", [])
|
|
155
|
+
return history
|
|
156
|
+
except IndexError:
|
|
157
|
+
raise McMNoDataError
|
|
158
|
+
|
|
159
|
+
def getRequest(self, prepID):
|
|
160
|
+
"""
|
|
161
|
+
Get the request record which has, among other things,
|
|
162
|
+
the number of requested events
|
|
163
|
+
"""
|
|
164
|
+
|
|
165
|
+
url = 'public/restapi/requests/get/%s' % prepID
|
|
166
|
+
res = self._getURL(url)
|
|
167
|
+
return res['results']
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
if __name__ == '__main__':
|
|
171
|
+
with McM() as mcm:
|
|
172
|
+
history = mcm.getHistory(prepID='BTV-Upg2023SHCAL14DR-00002')
|
|
173
|
+
request = mcm.getRequest(prepID='BTV-Upg2023SHCAL14DR-00002')
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# coding=utf-8
|
|
3
|
+
"""
|
|
4
|
+
Wrapper class, based on the PyCuRL module, providing an interface
|
|
5
|
+
to CERN MonIT Grafana APIs
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import division, print_function, absolute_import
|
|
8
|
+
from builtins import str, object
|
|
9
|
+
from future import standard_library
|
|
10
|
+
standard_library.install_aliases()
|
|
11
|
+
|
|
12
|
+
import logging
|
|
13
|
+
import json
|
|
14
|
+
from copy import copy
|
|
15
|
+
from pprint import pformat
|
|
16
|
+
from urllib.parse import urljoin
|
|
17
|
+
|
|
18
|
+
from WMCore.Services.pycurl_manager import RequestHandler
|
|
19
|
+
|
|
20
|
+
class Grafana(object):
|
|
21
|
+
"""
|
|
22
|
+
Service class providing functionality to CERN monitoring Grafana APIs
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
def __init__(self, token, configDict=None):
|
|
26
|
+
"""
|
|
27
|
+
Constructs a Grafana object.
|
|
28
|
+
:param token: mandatory string with the key/token string
|
|
29
|
+
:param configDict: dictionary with extra parameters, such as:
|
|
30
|
+
logger: logger object
|
|
31
|
+
endpoint: string with the url/endpoint to be used
|
|
32
|
+
cacheduration: float with the cache duration, in hours
|
|
33
|
+
headers: dictionary with the headers to be used
|
|
34
|
+
"""
|
|
35
|
+
self._token = token
|
|
36
|
+
self.configDict = configDict or {}
|
|
37
|
+
self.configDict.setdefault('endpoint', "https://monit-grafana.cern.ch")
|
|
38
|
+
self.configDict.setdefault('cacheduration', 0) # in hours
|
|
39
|
+
if 'headers' not in self.configDict:
|
|
40
|
+
self.configDict.setdefault('headers', {})
|
|
41
|
+
self.configDict['headers'].update({"Accept": "application/json"})
|
|
42
|
+
self.configDict['headers'].update({"Content-Type": "application/json"})
|
|
43
|
+
|
|
44
|
+
self.logger = self.configDict.get("logger", logging.getLogger())
|
|
45
|
+
self.logger.info("MonIT service initialized with parameters: %s", self.configDict)
|
|
46
|
+
|
|
47
|
+
def updateToken(self, token):
|
|
48
|
+
"""
|
|
49
|
+
Update token to be used in requests made through this module
|
|
50
|
+
:param token: string with the new token
|
|
51
|
+
"""
|
|
52
|
+
self._token = token
|
|
53
|
+
|
|
54
|
+
def _postRequest(self, url, params, verb='POST', verbose=0):
|
|
55
|
+
"Helper function to POST request to given URL"
|
|
56
|
+
mgr = RequestHandler(logger=self.logger)
|
|
57
|
+
headers = copy(self.configDict['headers'])
|
|
58
|
+
headers.update({"Authorization": self._token})
|
|
59
|
+
|
|
60
|
+
try:
|
|
61
|
+
data = mgr.getdata(url, params, headers, verb=verb, verbose=verbose)
|
|
62
|
+
return json.loads(data)
|
|
63
|
+
except Exception as exc:
|
|
64
|
+
self.logger.error("Failed to retrieve data from MonIT. Error: %s", str(exc))
|
|
65
|
+
return None
|
|
66
|
+
|
|
67
|
+
def getAPIData(self, apiName, queryStr=''):
|
|
68
|
+
"""
|
|
69
|
+
_getAPIData_
|
|
70
|
+
|
|
71
|
+
Retrieve data from a given Grafana API and index name
|
|
72
|
+
:param apiName: string with the API name/number
|
|
73
|
+
:param queryStr: string with the whole query logic
|
|
74
|
+
:return: data as retrieved from Grafana
|
|
75
|
+
"""
|
|
76
|
+
uri = urljoin(self.configDict['endpoint'], "/api/datasources/proxy/%s/_msearch" % apiName)
|
|
77
|
+
return self._postRequest(uri, queryStr)
|
|
78
|
+
|
|
79
|
+
def getSSBData(self, pathName, metricName, indexName="monit_prod_cmssst_*",
|
|
80
|
+
apiName="9475", queryStr=''):
|
|
81
|
+
"""
|
|
82
|
+
_getSSBData_
|
|
83
|
+
|
|
84
|
+
Retrieve data from the SSB index in Grafana
|
|
85
|
+
:param pathName: string with the path to the correct metric, mapped from SSB as:
|
|
86
|
+
columnid=237 ProdStatus path="sts15min" data.prod_status
|
|
87
|
+
columnid=160 CPU bound path="scap15min" data.core_cpu_intensive
|
|
88
|
+
columnid=161 I/O bound path="scap15min" data.core_io_intensive
|
|
89
|
+
columnid=159 Prod Cores path="scap15min" data.core_production
|
|
90
|
+
columnid=136 Real Cores path="scap15min" data.core_max_used
|
|
91
|
+
columnid=107 Tape Pledge path="scap15min" data.tape_pledge
|
|
92
|
+
:param indexName: optional string with the grafana index name
|
|
93
|
+
:param apiName: optional string with the Grafana API number
|
|
94
|
+
:param queryStr: optional string with the full query logic
|
|
95
|
+
:return: dictionary with the site names and the metric value
|
|
96
|
+
"""
|
|
97
|
+
# TODO: allow flexible time range instead of the hardwired last 24h
|
|
98
|
+
# TODO: allow flexible number of rows, instead of the hardwired 500
|
|
99
|
+
results = {}
|
|
100
|
+
if metricName not in ('prod_status', 'core_cpu_intensive', 'core_io_intensive',
|
|
101
|
+
'core_production', 'core_max_used', 'tape_pledge'):
|
|
102
|
+
self.logger.error("SSB metric name '%s' is NOT supported.", metricName)
|
|
103
|
+
return results
|
|
104
|
+
|
|
105
|
+
uri = urljoin(self.configDict['endpoint'], "/api/datasources/proxy/%s/_msearch" % apiName)
|
|
106
|
+
if not queryStr:
|
|
107
|
+
### NOTE: these '\n' new lines are mandatory to get it working...
|
|
108
|
+
queryStr = '{"search_type":"query_then_fetch","ignore_unavailable":true,"index":["%s"]}\n' % indexName
|
|
109
|
+
queryStr += '{"size":500,"query":{"bool":{"filter":[{"range":{"metadata.timestamp":{"gte":"now-1d","lte":"now","format":"epoch_millis"}}},' \
|
|
110
|
+
'{"query_string":{"analyze_wildcard":true,' \
|
|
111
|
+
'"query":"metadata.type: ssbmetric AND metadata.type_prefix:raw AND metadata.monit_hdfs_path: %s"}}]}},' \
|
|
112
|
+
'"sort":{"metadata.timestamp":{"order":"desc","unmapped_type":"boolean"}},' \
|
|
113
|
+
'"script_fields":{},"docvalue_fields":["metadata.timestamp"]}\n' % pathName
|
|
114
|
+
self.logger.info("Calling API: %s with query: %s", uri, pformat(queryStr))
|
|
115
|
+
|
|
116
|
+
data = self._postRequest(uri, queryStr)
|
|
117
|
+
#self.logger.debug("Data retrieved: %s", pformat(data))
|
|
118
|
+
if data:
|
|
119
|
+
# now parse the ugly output
|
|
120
|
+
hits = data['responses'][0]['hits']['hits']
|
|
121
|
+
for item in hits:
|
|
122
|
+
site = item['_source']['data']['name']
|
|
123
|
+
metricValue = item['_source']['data'][metricName]
|
|
124
|
+
tStamp = int(item['sort'][0])
|
|
125
|
+
|
|
126
|
+
results.setdefault(site, {})
|
|
127
|
+
if tStamp > results[site].get("timeStamp", 0):
|
|
128
|
+
results[site][metricName] = metricValue
|
|
129
|
+
results[site]["timeStamp"] = tStamp
|
|
130
|
+
|
|
131
|
+
data = results
|
|
132
|
+
|
|
133
|
+
return data
|
|
File without changes
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"""
|
|
2
|
+
_PyCondorAPI_
|
|
3
|
+
|
|
4
|
+
Class used to interact with Condor daemons on the agent
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import print_function, division
|
|
8
|
+
|
|
9
|
+
from builtins import str, object
|
|
10
|
+
from past.builtins import basestring
|
|
11
|
+
import logging
|
|
12
|
+
try:
|
|
13
|
+
# This module has dependency with python binding for condor package (condor)
|
|
14
|
+
import htcondor2 as htcondor
|
|
15
|
+
except ImportError:
|
|
16
|
+
pass
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class PyCondorAPI(object):
|
|
20
|
+
"""
|
|
21
|
+
Some APIs to interact with HTCondor via the HTCondor python bindings.
|
|
22
|
+
"""
|
|
23
|
+
def __init__(self):
|
|
24
|
+
self.schedd = htcondor.Schedd()
|
|
25
|
+
self.coll = htcondor.Collector()
|
|
26
|
+
|
|
27
|
+
def recreateSchedd(self):
|
|
28
|
+
"""
|
|
29
|
+
In case our current schedd object is in a "strange" state, we
|
|
30
|
+
better recreate it.
|
|
31
|
+
"""
|
|
32
|
+
logging.warning("Recreating Schedd instance due to query error...")
|
|
33
|
+
self.schedd = htcondor.Schedd()
|
|
34
|
+
|
|
35
|
+
def getCondorJobsSummary(self):
|
|
36
|
+
"""
|
|
37
|
+
Retrieves a job summary from the HTCondor Schedd object
|
|
38
|
+
:return: a list of classads representing the matching jobs, or None if failed
|
|
39
|
+
"""
|
|
40
|
+
jobs = None # return None to signalize the query failed
|
|
41
|
+
queryOpts = htcondor.htcondor.QueryOpts.SummaryOnly
|
|
42
|
+
try:
|
|
43
|
+
return self.schedd.query(opts=queryOpts)
|
|
44
|
+
except Exception:
|
|
45
|
+
self.recreateSchedd()
|
|
46
|
+
|
|
47
|
+
try:
|
|
48
|
+
jobs = self.schedd.query(opts=queryOpts)
|
|
49
|
+
except Exception as ex:
|
|
50
|
+
logging.exception("Failed to fetch summary of jobs from Condor Schedd. Error: %s", str(ex))
|
|
51
|
+
return jobs
|
|
52
|
+
|
|
53
|
+
def getCondorJobs(self, constraint='true', attrList=None, limit=-1, opts="Default"):
|
|
54
|
+
"""
|
|
55
|
+
Given a job/schedd constraint, return a list of job classad.
|
|
56
|
+
:param constraint: the query constraint (str or ExprTree). Defaults to 'true'
|
|
57
|
+
:param attrList: a list of attribute strings to be returned in the call.
|
|
58
|
+
It defaults to all attributes.
|
|
59
|
+
:param limit: a limit on the number of matches to return. Defaults to -1 (all)
|
|
60
|
+
:param opts: string with additional flags for the query. Defaults to Default.
|
|
61
|
+
https://htcondor.readthedocs.io/en/v8_9_7/apis/python-bindings/api/htcondor.html#htcondor.QueryOpts
|
|
62
|
+
:return: returns an iterator to the job classads
|
|
63
|
+
"""
|
|
64
|
+
attrList = attrList or []
|
|
65
|
+
# if option parameter is invalid, default it to the standard behavior
|
|
66
|
+
opts = getattr(htcondor.htcondor.QueryOpts, opts, "Default")
|
|
67
|
+
msg = "Querying condor schedd with params: constraint=%s, attrList=%s, limit=%s, opts=%s"
|
|
68
|
+
logging.info(msg, constraint, attrList, limit, opts)
|
|
69
|
+
try:
|
|
70
|
+
return self.schedd.query(constraint, attrList, limit, opts=opts)
|
|
71
|
+
except Exception:
|
|
72
|
+
self.recreateSchedd()
|
|
73
|
+
|
|
74
|
+
# if we hit another exception, let it be raised up in the chain
|
|
75
|
+
return self.schedd.query(constraint, attrList, limit, opts=opts)
|
|
76
|
+
|
|
77
|
+
def editCondorJobs(self, job_spec, attr, value):
|
|
78
|
+
"""
|
|
79
|
+
_editCondorJobs_
|
|
80
|
+
|
|
81
|
+
Edit a set of condor jobs given an attribute and value
|
|
82
|
+
job_spec can be a list of job IDs or a string specifying a constraint
|
|
83
|
+
"""
|
|
84
|
+
success = False
|
|
85
|
+
try:
|
|
86
|
+
self.schedd.edit(job_spec, attr, value)
|
|
87
|
+
success = True
|
|
88
|
+
except Exception as ex:
|
|
89
|
+
# edit doesn't distinguish between an error and not matching any jobs
|
|
90
|
+
# check for this message and assume it just didn't match any jobs
|
|
91
|
+
if isinstance(ex, RuntimeError) and str(ex) == "Unable to edit jobs matching constraint":
|
|
92
|
+
success = True
|
|
93
|
+
msg = "Condor constraint did not match any jobs. "
|
|
94
|
+
msg += "Message from schedd: %s" % str(ex)
|
|
95
|
+
logging.info(msg)
|
|
96
|
+
else:
|
|
97
|
+
msg = "Condor failed to edit the jobs. "
|
|
98
|
+
msg += "Error message: %s" % str(ex)
|
|
99
|
+
logging.exception(msg)
|
|
100
|
+
|
|
101
|
+
return success
|
|
102
|
+
|
|
103
|
+
def isScheddOverloaded(self):
|
|
104
|
+
"""
|
|
105
|
+
check whether job limit is reached in local schedd.
|
|
106
|
+
Condition is check by following logic.
|
|
107
|
+
( ShadowsRunning > 9.700000000000000E-01 * MAX_RUNNING_JOBS) )
|
|
108
|
+
|| ( RecentDaemonCoreDutyCycle > 9.800000000000000E-01 )
|
|
109
|
+
"""
|
|
110
|
+
try:
|
|
111
|
+
scheddAd = self.coll.locate(htcondor.DaemonTypes.Schedd)
|
|
112
|
+
q = self.coll.query(htcondor.AdTypes.Schedd, 'Name == "%s"' % scheddAd['Name'],
|
|
113
|
+
projection=['CurbMatchmaking'])[0]
|
|
114
|
+
isOverloaded = q['CurbMatchmaking'].eval(q)
|
|
115
|
+
return isOverloaded
|
|
116
|
+
except Exception:
|
|
117
|
+
# if there is an error, try to recreate the collector instance
|
|
118
|
+
logging.info("Recreating Collector instance due to query error...")
|
|
119
|
+
self.coll = htcondor.Collector()
|
|
120
|
+
try:
|
|
121
|
+
scheddAd = self.coll.locate(htcondor.DaemonTypes.Schedd)
|
|
122
|
+
q = self.coll.query(htcondor.AdTypes.Schedd, 'Name == "%s"' % scheddAd['Name'],
|
|
123
|
+
projection=['CurbMatchmaking'])[0]
|
|
124
|
+
isOverloaded = q['CurbMatchmaking'].eval(q)
|
|
125
|
+
except Exception as ex:
|
|
126
|
+
msg = "Condor failed to fetch schedd attributes."
|
|
127
|
+
msg += "Error message: %s" % str(ex)
|
|
128
|
+
logging.exception(msg)
|
|
129
|
+
# since it failed, assume it's overloaded
|
|
130
|
+
isOverloaded = True
|
|
131
|
+
|
|
132
|
+
return isOverloaded
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def getScheddParamValue(param):
|
|
136
|
+
"""
|
|
137
|
+
_getScheddParamValue_
|
|
138
|
+
|
|
139
|
+
Given a schedd parameter, retrieve it's value with htcondor, e.g.:
|
|
140
|
+
MAX_JOBS_RUNNING, MAX_JOBS_PER_OWNER, etc
|
|
141
|
+
"""
|
|
142
|
+
paramResult = None
|
|
143
|
+
if not isinstance(param, basestring):
|
|
144
|
+
logging.error("Parameter %s must be string type", param)
|
|
145
|
+
return paramResult
|
|
146
|
+
|
|
147
|
+
try:
|
|
148
|
+
paramResult = htcondor.param[param]
|
|
149
|
+
except Exception as ex:
|
|
150
|
+
msg = "Condor failed to fetch schedd parameter: %s" % param
|
|
151
|
+
msg += "Error message: %s" % str(ex)
|
|
152
|
+
logging.exception(msg)
|
|
153
|
+
|
|
154
|
+
return paramResult
|
|
File without changes
|