panda-server-source 0.8.0__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.
Files changed (375) hide show
  1. panda_server_source-0.8.0.dist-info/METADATA +55 -0
  2. panda_server_source-0.8.0.dist-info/RECORD +375 -0
  3. panda_server_source-0.8.0.dist-info/WHEEL +4 -0
  4. panda_server_source-0.8.0.dist-info/licenses/LICENSE.txt +202 -0
  5. pandajedi/__init__.py +0 -0
  6. pandajedi/jedibrokerage/AtlasAnalJobBroker.py +2343 -0
  7. pandajedi/jedibrokerage/AtlasBrokerUtils.py +1292 -0
  8. pandajedi/jedibrokerage/AtlasProdJobBroker.py +2064 -0
  9. pandajedi/jedibrokerage/AtlasProdTaskBroker.py +629 -0
  10. pandajedi/jedibrokerage/GenJobBroker.py +381 -0
  11. pandajedi/jedibrokerage/JobBrokerBase.py +133 -0
  12. pandajedi/jedibrokerage/TaskBrokerBase.py +15 -0
  13. pandajedi/jedibrokerage/__init__.py +0 -0
  14. pandajedi/jediconfig/__init__.py +0 -0
  15. pandajedi/jediconfig/jedi_config.py +40 -0
  16. pandajedi/jedicore/FactoryBase.py +182 -0
  17. pandajedi/jedicore/Interaction.py +433 -0
  18. pandajedi/jedicore/JediDBProxy.py +56 -0
  19. pandajedi/jedicore/JediDBProxyPool.py +37 -0
  20. pandajedi/jedicore/JediDBSchemaInfo.py +17 -0
  21. pandajedi/jedicore/JediException.py +13 -0
  22. pandajedi/jedicore/JediTaskBuffer.py +984 -0
  23. pandajedi/jedicore/JediTaskBufferInterface.py +50 -0
  24. pandajedi/jedicore/MsgWrapper.py +124 -0
  25. pandajedi/jedicore/ProcessUtils.py +34 -0
  26. pandajedi/jedicore/SiteCandidate.py +90 -0
  27. pandajedi/jedicore/ThreadUtils.py +205 -0
  28. pandajedi/jedicore/__init__.py +0 -0
  29. pandajedi/jediddm/AtlasDDMClient.py +1708 -0
  30. pandajedi/jediddm/DDMClientBase.py +16 -0
  31. pandajedi/jediddm/DDMInterface.py +83 -0
  32. pandajedi/jediddm/GenDDMClient.py +17 -0
  33. pandajedi/jediddm/__init__.py +0 -0
  34. pandajedi/jedidog/AtlasAnalWatchDog.py +648 -0
  35. pandajedi/jedidog/AtlasDataCarouselWatchDog.py +189 -0
  36. pandajedi/jedidog/AtlasDataLocalityUpdaterWatchDog.py +215 -0
  37. pandajedi/jedidog/AtlasProdWatchDog.py +443 -0
  38. pandajedi/jedidog/AtlasQueueFillerWatchDog.py +800 -0
  39. pandajedi/jedidog/AtlasTaskWithholderWatchDog.py +245 -0
  40. pandajedi/jedidog/AtlasWorkflowManagerWatchDog.py +63 -0
  41. pandajedi/jedidog/GenWatchDog.py +21 -0
  42. pandajedi/jedidog/JumboWatchDog.py +147 -0
  43. pandajedi/jedidog/TypicalWatchDogBase.py +122 -0
  44. pandajedi/jedidog/WatchDogBase.py +53 -0
  45. pandajedi/jedidog/__init__.py +0 -0
  46. pandajedi/jediexec/reniceJEDI.py +25 -0
  47. pandajedi/jedigen/AtlasTaskGenerator.py +110 -0
  48. pandajedi/jedigen/TaskGeneratorBase.py +15 -0
  49. pandajedi/jedigen/__init__.py +0 -0
  50. pandajedi/jedimsgprocessor/__init__.py +0 -0
  51. pandajedi/jedimsgprocessor/ai_parameter_adjuster_msg_processor +71 -0
  52. pandajedi/jedimsgprocessor/atlas_idds_msg_processor.py +66 -0
  53. pandajedi/jedimsgprocessor/base_msg_processor.py +33 -0
  54. pandajedi/jedimsgprocessor/forwarding_msg_processor.py +29 -0
  55. pandajedi/jedimsgprocessor/hpo_msg_processor.py +93 -0
  56. pandajedi/jedimsgprocessor/jedi_contents_feeder_msg_processor.py +63 -0
  57. pandajedi/jedimsgprocessor/jedi_job_generator_msg_processor.py +185 -0
  58. pandajedi/jedimsgprocessor/jedi_post_processor_msg_processor.py +82 -0
  59. pandajedi/jedimsgprocessor/kafka_msg_processor.py +44 -0
  60. pandajedi/jedimsgprocessor/panda_callback_msg_processor.py +182 -0
  61. pandajedi/jedimsgprocessor/panda_to_jedi_msg_processor.py +74 -0
  62. pandajedi/jedimsgprocessor/processing_msg_processor.py +134 -0
  63. pandajedi/jedimsgprocessor/status_report_msg_processor.py +129 -0
  64. pandajedi/jedimsgprocessor/tape_carousel_msg_processor.py +118 -0
  65. pandajedi/jedimsgprocessor/workflow_manager_msg_processor.py +89 -0
  66. pandajedi/jediorder/ContentsFeeder.py +785 -0
  67. pandajedi/jediorder/JediDaemon.py +27 -0
  68. pandajedi/jediorder/JediKnight.py +55 -0
  69. pandajedi/jediorder/JediMaster.py +238 -0
  70. pandajedi/jediorder/JediMsgProcessor.py +32 -0
  71. pandajedi/jediorder/JobBroker.py +33 -0
  72. pandajedi/jediorder/JobGenerator.py +2763 -0
  73. pandajedi/jediorder/JobSplitter.py +308 -0
  74. pandajedi/jediorder/JobThrottler.py +28 -0
  75. pandajedi/jediorder/PostProcessor.py +166 -0
  76. pandajedi/jediorder/TaskBroker.py +268 -0
  77. pandajedi/jediorder/TaskCommando.py +334 -0
  78. pandajedi/jediorder/TaskGenerator.py +17 -0
  79. pandajedi/jediorder/TaskRefiner.py +611 -0
  80. pandajedi/jediorder/TaskSetupper.py +17 -0
  81. pandajedi/jediorder/WatchDog.py +79 -0
  82. pandajedi/jediorder/__init__.py +0 -0
  83. pandajedi/jedipprocess/AtlasAnalPostProcessor.py +404 -0
  84. pandajedi/jedipprocess/AtlasPostProcessorUtils.py +50 -0
  85. pandajedi/jedipprocess/AtlasProdPostProcessor.py +178 -0
  86. pandajedi/jedipprocess/GenPostProcessor.py +35 -0
  87. pandajedi/jedipprocess/MailTemplates.py +185 -0
  88. pandajedi/jedipprocess/PostProcessorBase.py +269 -0
  89. pandajedi/jedipprocess/__init__.py +0 -0
  90. pandajedi/jedirefine/AtlasAnalTaskRefiner.py +259 -0
  91. pandajedi/jedirefine/AtlasProdTaskRefiner.py +162 -0
  92. pandajedi/jedirefine/GenTaskRefiner.py +61 -0
  93. pandajedi/jedirefine/RefinerUtils.py +154 -0
  94. pandajedi/jedirefine/TaskRefinerBase.py +996 -0
  95. pandajedi/jedirefine/__init__.py +0 -0
  96. pandajedi/jedisetup/AtlasTaskSetupper.py +309 -0
  97. pandajedi/jedisetup/GenTaskSetupper.py +16 -0
  98. pandajedi/jedisetup/SimpleTaskSetupper.py +152 -0
  99. pandajedi/jedisetup/TaskSetupperBase.py +15 -0
  100. pandajedi/jedisetup/__init__.py +0 -0
  101. pandajedi/jeditest/SchemaChecker.py +41 -0
  102. pandajedi/jeditest/addContWoSoTask.py +54 -0
  103. pandajedi/jeditest/addDataCarouselRequest.py +47 -0
  104. pandajedi/jeditest/addEventServiceTask.py +101 -0
  105. pandajedi/jeditest/addHpoTask.py +81 -0
  106. pandajedi/jeditest/addIDDSStageInRequest.py +56 -0
  107. pandajedi/jeditest/addNonAtlasTask.py +71 -0
  108. pandajedi/jeditest/addNonAtlasTaskEnc.py +64 -0
  109. pandajedi/jeditest/addTestTask.py +124 -0
  110. pandajedi/jeditest/addTestTaskParamToDEFT.py +70 -0
  111. pandajedi/jeditest/addTestTaskWithMerger.py +97 -0
  112. pandajedi/jeditest/brokerTest.py +78 -0
  113. pandajedi/jeditest/cancelDataCarouselRequest.py +35 -0
  114. pandajedi/jeditest/contentsFeederTest.py +28 -0
  115. pandajedi/jeditest/contentsFeederTestWithTask.py +18 -0
  116. pandajedi/jeditest/ddmTest.py +4 -0
  117. pandajedi/jeditest/jobGenForOneTask.py +38 -0
  118. pandajedi/jeditest/jobGeneratorTest.py +43 -0
  119. pandajedi/jeditest/jobSplitterTest.py +104 -0
  120. pandajedi/jeditest/jobThrottlerTest.py +22 -0
  121. pandajedi/jeditest/msgProcessorTest.py +9 -0
  122. pandajedi/jeditest/postProcessorTest.py +18 -0
  123. pandajedi/jeditest/resubmitDataCarouselRequest.py +35 -0
  124. pandajedi/jeditest/resubmitTaskParam.py +20 -0
  125. pandajedi/jeditest/taskBrokerTest.py +22 -0
  126. pandajedi/jeditest/taskBrokerTestWithTask.py +38 -0
  127. pandajedi/jeditest/taskBufferTest.py +5 -0
  128. pandajedi/jeditest/taskCommandoTest.py +28 -0
  129. pandajedi/jeditest/taskRefinerTest.py +30 -0
  130. pandajedi/jeditest/testOneTaskToRefine.py +49 -0
  131. pandajedi/jeditest/testOneTaskToTaskBroker.py +42 -0
  132. pandajedi/jeditest/testPandaDDMMap.py +62 -0
  133. pandajedi/jeditest/updateDataCarouselRequestParams.py +50 -0
  134. pandajedi/jeditest/watchDogTest.py +25 -0
  135. pandajedi/jeditest/workQueueTest.py +22 -0
  136. pandajedi/jedithrottle/AtlasAnalJobThrottler.py +19 -0
  137. pandajedi/jedithrottle/AtlasProdJobThrottler.py +18 -0
  138. pandajedi/jedithrottle/GenJobThrottler.py +26 -0
  139. pandajedi/jedithrottle/JobThrottlerBase.py +496 -0
  140. pandajedi/jedithrottle/__init__.py +0 -0
  141. pandaserver/__init__.py +0 -0
  142. pandaserver/api/__init__.py +0 -0
  143. pandaserver/api/v1/__init__.py +0 -0
  144. pandaserver/api/v1/common.py +339 -0
  145. pandaserver/api/v1/credential_management_api.py +372 -0
  146. pandaserver/api/v1/data_carousel_api.py +264 -0
  147. pandaserver/api/v1/event_api.py +269 -0
  148. pandaserver/api/v1/file_server_api.py +942 -0
  149. pandaserver/api/v1/harvester_api.py +445 -0
  150. pandaserver/api/v1/http_client.py +166 -0
  151. pandaserver/api/v1/idds_api.py +180 -0
  152. pandaserver/api/v1/job_api.py +463 -0
  153. pandaserver/api/v1/metaconfig_api.py +122 -0
  154. pandaserver/api/v1/pilot_api.py +895 -0
  155. pandaserver/api/v1/statistics_api.py +207 -0
  156. pandaserver/api/v1/system_api.py +186 -0
  157. pandaserver/api/v1/task_api.py +1520 -0
  158. pandaserver/api/v1/tests/__init__.py +0 -0
  159. pandaserver/api/v1/tests/credential_management_api_tests.py +116 -0
  160. pandaserver/api/v1/tests/data_carousel_api_tests.py +82 -0
  161. pandaserver/api/v1/tests/harvester_api_tests.py +188 -0
  162. pandaserver/api/v1/tests/idds_api_tests.py +45 -0
  163. pandaserver/api/v1/tests/job_api_tests.py +112 -0
  164. pandaserver/api/v1/tests/pilot_api_tests.py +154 -0
  165. pandaserver/api/v1/tests/statistics_api_tests.py +104 -0
  166. pandaserver/api/v1/tests/system_api_tests.py +58 -0
  167. pandaserver/api/v1/tests/task_api_tests.py +590 -0
  168. pandaserver/api/v1/version.py +2 -0
  169. pandaserver/api/v1/workflow_api.py +136 -0
  170. pandaserver/brokerage/SiteMapper.py +406 -0
  171. pandaserver/brokerage/__init__.py +0 -0
  172. pandaserver/brokerage/broker.py +272 -0
  173. pandaserver/config/__init__.py +0 -0
  174. pandaserver/config/config_utils.py +15 -0
  175. pandaserver/config/daemon_config.py +29 -0
  176. pandaserver/config/mcp_config.py +38 -0
  177. pandaserver/config/panda_config.py +233 -0
  178. pandaserver/configurator/Carbon.py +65 -0
  179. pandaserver/configurator/Configurator.py +908 -0
  180. pandaserver/configurator/__init__.py +0 -0
  181. pandaserver/configurator/aux.py +73 -0
  182. pandaserver/daemons/__init__.py +0 -0
  183. pandaserver/daemons/master.py +110 -0
  184. pandaserver/daemons/master_systemd.py +79 -0
  185. pandaserver/daemons/scripts/__init__.py +0 -0
  186. pandaserver/daemons/scripts/add_main.py +264 -0
  187. pandaserver/daemons/scripts/add_sub.py +221 -0
  188. pandaserver/daemons/scripts/cache_pilots.py +47 -0
  189. pandaserver/daemons/scripts/cache_schedconfig.py +286 -0
  190. pandaserver/daemons/scripts/carbon.py +50 -0
  191. pandaserver/daemons/scripts/configurator.py +94 -0
  192. pandaserver/daemons/scripts/copyArchive.py +1387 -0
  193. pandaserver/daemons/scripts/datasetManager.py +1154 -0
  194. pandaserver/daemons/scripts/dummy_test.py +25 -0
  195. pandaserver/daemons/scripts/evpPD2P.py +144 -0
  196. pandaserver/daemons/scripts/hs_scrapers.py +264 -0
  197. pandaserver/daemons/scripts/metric_collector.py +927 -0
  198. pandaserver/daemons/scripts/panda_activeusers_query.py +80 -0
  199. pandaserver/daemons/scripts/pilotStreaming.py +109 -0
  200. pandaserver/daemons/scripts/process_workflow_files_daemon.py +166 -0
  201. pandaserver/daemons/scripts/recover_lost_files_daemon.py +177 -0
  202. pandaserver/daemons/scripts/task_evaluator.py +405 -0
  203. pandaserver/daemons/scripts/tmpwatch.py +70 -0
  204. pandaserver/daemons/scripts/worker_synchronization.py +97 -0
  205. pandaserver/daemons/utils.py +753 -0
  206. pandaserver/dataservice/DataServiceUtils.py +323 -0
  207. pandaserver/dataservice/ErrorCode.py +25 -0
  208. pandaserver/dataservice/RecoverLostFilesCore.py +322 -0
  209. pandaserver/dataservice/__init__.py +0 -0
  210. pandaserver/dataservice/activator.py +79 -0
  211. pandaserver/dataservice/adder_atlas_plugin.py +1106 -0
  212. pandaserver/dataservice/adder_dummy_plugin.py +31 -0
  213. pandaserver/dataservice/adder_gen.py +954 -0
  214. pandaserver/dataservice/adder_plugin_base.py +27 -0
  215. pandaserver/dataservice/adder_result.py +75 -0
  216. pandaserver/dataservice/adder_simple_plugin.py +160 -0
  217. pandaserver/dataservice/closer.py +247 -0
  218. pandaserver/dataservice/closer_atlas_plugin.py +90 -0
  219. pandaserver/dataservice/ddm.py +1381 -0
  220. pandaserver/dataservice/ddm_handler.py +95 -0
  221. pandaserver/dataservice/dyn_data_distributer.py +824 -0
  222. pandaserver/dataservice/event_lookup_client_ei.py +77 -0
  223. pandaserver/dataservice/event_picker.py +268 -0
  224. pandaserver/dataservice/finisher.py +194 -0
  225. pandaserver/dataservice/setupper.py +225 -0
  226. pandaserver/dataservice/setupper_atlas_plugin.py +1851 -0
  227. pandaserver/dataservice/setupper_dummy_plugin.py +47 -0
  228. pandaserver/dataservice/setupper_plugin_base.py +67 -0
  229. pandaserver/jobdispatcher/DispatcherUtils.py +35 -0
  230. pandaserver/jobdispatcher/ErrorCode.py +19 -0
  231. pandaserver/jobdispatcher/JobDispatcher.py +1625 -0
  232. pandaserver/jobdispatcher/Protocol.py +443 -0
  233. pandaserver/jobdispatcher/Watcher.py +186 -0
  234. pandaserver/jobdispatcher/__init__.py +0 -0
  235. pandaserver/pandamcp/__init__.py +0 -0
  236. pandaserver/pandamcp/mcp_main.py +56 -0
  237. pandaserver/pandamcp/mcp_test_client.py +95 -0
  238. pandaserver/pandamcp/mcp_utils.py +74 -0
  239. pandaserver/proxycache/__init__.py +0 -0
  240. pandaserver/proxycache/panda_proxy_cache.py +240 -0
  241. pandaserver/proxycache/token_cache.py +141 -0
  242. pandaserver/server/.gacl +6 -0
  243. pandaserver/server/panda.py +539 -0
  244. pandaserver/srvcore/CoreUtils.py +572 -0
  245. pandaserver/srvcore/MailUtils.py +106 -0
  246. pandaserver/srvcore/__init__.py +0 -0
  247. pandaserver/srvcore/allowed_methods.py +100 -0
  248. pandaserver/srvcore/oidc_utils.py +152 -0
  249. pandaserver/srvcore/panda_request.py +196 -0
  250. pandaserver/srvcore/srv_msg_utils.py +42 -0
  251. pandaserver/taskbuffer/ConBridge.py +513 -0
  252. pandaserver/taskbuffer/DBProxyPool.py +95 -0
  253. pandaserver/taskbuffer/DataCarousel.py +3053 -0
  254. pandaserver/taskbuffer/DatasetSpec.py +137 -0
  255. pandaserver/taskbuffer/DdmSpec.py +201 -0
  256. pandaserver/taskbuffer/ErrorCode.py +87 -0
  257. pandaserver/taskbuffer/EventServiceUtils.py +396 -0
  258. pandaserver/taskbuffer/FileSpec.py +290 -0
  259. pandaserver/taskbuffer/GlobalShares.py +244 -0
  260. pandaserver/taskbuffer/HarvesterMetricsSpec.py +92 -0
  261. pandaserver/taskbuffer/Initializer.py +82 -0
  262. pandaserver/taskbuffer/InputChunk.py +1080 -0
  263. pandaserver/taskbuffer/JediCacheSpec.py +57 -0
  264. pandaserver/taskbuffer/JediDatasetSpec.py +588 -0
  265. pandaserver/taskbuffer/JediFileSpec.py +242 -0
  266. pandaserver/taskbuffer/JediTaskSpec.py +1687 -0
  267. pandaserver/taskbuffer/JobSpec.py +1006 -0
  268. pandaserver/taskbuffer/JobUtils.py +232 -0
  269. pandaserver/taskbuffer/NucleusSpec.py +116 -0
  270. pandaserver/taskbuffer/OraDBProxy.py +174 -0
  271. pandaserver/taskbuffer/PanDAMsgProcessor.py +8 -0
  272. pandaserver/taskbuffer/PandaDBSchemaInfo.py +18 -0
  273. pandaserver/taskbuffer/ParseJobXML.py +350 -0
  274. pandaserver/taskbuffer/PickleFileSpec.py +18 -0
  275. pandaserver/taskbuffer/PickleJobSpec.py +25 -0
  276. pandaserver/taskbuffer/PrioUtil.py +40 -0
  277. pandaserver/taskbuffer/ProcessGroups.py +111 -0
  278. pandaserver/taskbuffer/ResourceSpec.py +175 -0
  279. pandaserver/taskbuffer/SQLDumper.py +37 -0
  280. pandaserver/taskbuffer/SQLManager.py +60 -0
  281. pandaserver/taskbuffer/SiteSpec.py +304 -0
  282. pandaserver/taskbuffer/SupErrors.py +10 -0
  283. pandaserver/taskbuffer/TaskBuffer.py +2882 -0
  284. pandaserver/taskbuffer/TaskBufferInterface.py +163 -0
  285. pandaserver/taskbuffer/Utils.py +848 -0
  286. pandaserver/taskbuffer/WorkQueue.py +227 -0
  287. pandaserver/taskbuffer/WorkQueueMapper.py +203 -0
  288. pandaserver/taskbuffer/WorkerSpec.py +143 -0
  289. pandaserver/taskbuffer/WrappedCursor.py +487 -0
  290. pandaserver/taskbuffer/WrappedPickle.py +88 -0
  291. pandaserver/taskbuffer/WrappedPostgresConn.py +24 -0
  292. pandaserver/taskbuffer/__init__.py +0 -0
  293. pandaserver/taskbuffer/db_proxy_mods/OraDBProxy_structure.png +0 -0
  294. pandaserver/taskbuffer/db_proxy_mods/__init__.py +7 -0
  295. pandaserver/taskbuffer/db_proxy_mods/base_module.py +841 -0
  296. pandaserver/taskbuffer/db_proxy_mods/data_carousel_module.py +772 -0
  297. pandaserver/taskbuffer/db_proxy_mods/entity_module.py +3804 -0
  298. pandaserver/taskbuffer/db_proxy_mods/job_complex_module.py +5661 -0
  299. pandaserver/taskbuffer/db_proxy_mods/job_standalone_module.py +2640 -0
  300. pandaserver/taskbuffer/db_proxy_mods/metrics_module.py +874 -0
  301. pandaserver/taskbuffer/db_proxy_mods/misc_standalone_module.py +4272 -0
  302. pandaserver/taskbuffer/db_proxy_mods/task_complex_module.py +6172 -0
  303. pandaserver/taskbuffer/db_proxy_mods/task_event_module.py +4953 -0
  304. pandaserver/taskbuffer/db_proxy_mods/task_standalone_module.py +4999 -0
  305. pandaserver/taskbuffer/db_proxy_mods/task_utils_module.py +2063 -0
  306. pandaserver/taskbuffer/db_proxy_mods/worker_module.py +1944 -0
  307. pandaserver/taskbuffer/db_proxy_mods/workflow_module.py +832 -0
  308. pandaserver/taskbuffer/retryModule.py +552 -0
  309. pandaserver/taskbuffer/task_split_rules.py +308 -0
  310. pandaserver/taskbuffer/workflow_processor.py +249 -0
  311. pandaserver/taskbuffer/wrapped_oracle_conn.py +18 -0
  312. pandaserver/test/SchemaChecker.py +40 -0
  313. pandaserver/test/__init__.py +0 -0
  314. pandaserver/test/banUser.py +43 -0
  315. pandaserver/test/boostPrio.py +19 -0
  316. pandaserver/test/boostUser.py +35 -0
  317. pandaserver/test/callbackDDM.py +11 -0
  318. pandaserver/test/daod_on_demand.py +95 -0
  319. pandaserver/test/finishJob.py +184 -0
  320. pandaserver/test/finishTaskJEDI.py +11 -0
  321. pandaserver/test/getJobs.py +53 -0
  322. pandaserver/test/killJob.py +79 -0
  323. pandaserver/test/killJobLowPrio.py +99 -0
  324. pandaserver/test/killJobsInTask.py +56 -0
  325. pandaserver/test/killTask.py +80 -0
  326. pandaserver/test/killTaskJEDI.py +11 -0
  327. pandaserver/test/killUser.py +83 -0
  328. pandaserver/test/lsst/README.txt +7 -0
  329. pandaserver/test/lsst/lsstSubmit.py +139 -0
  330. pandaserver/test/lsst/lsstSubmitMERGEtest.py +141 -0
  331. pandaserver/test/lsst/lsstSubmitPhosim332.py +53 -0
  332. pandaserver/test/lsst/prepare-client-tarball-from-bigpanda-server.sh +41 -0
  333. pandaserver/test/reassignJobs.py +17 -0
  334. pandaserver/test/reassignSite.py +82 -0
  335. pandaserver/test/reassignTask.py +117 -0
  336. pandaserver/test/reassignWaiting.py +39 -0
  337. pandaserver/test/recoverLostFiles.py +7 -0
  338. pandaserver/test/reloadInputDS.py +51 -0
  339. pandaserver/test/sendCommandToJob.py +26 -0
  340. pandaserver/test/setDebugMode.py +38 -0
  341. pandaserver/test/setPriority.py +28 -0
  342. pandaserver/test/testEvgen.py +60 -0
  343. pandaserver/test/testEvgen17.py +58 -0
  344. pandaserver/test/testG4sim.py +81 -0
  345. pandaserver/test/testG4sim17.py +90 -0
  346. pandaserver/test/testGlobalShares.py +131 -0
  347. pandaserver/test/testReco.py +103 -0
  348. pandaserver/test/testSimulReco14.py +98 -0
  349. pandaserver/test/testSiteMap.py +26 -0
  350. pandaserver/test/testUpdateWorkerPilotStatus.py +9 -0
  351. pandaserver/userinterface/Client.py +1686 -0
  352. pandaserver/userinterface/UserIF.py +1799 -0
  353. pandaserver/userinterface/__init__.py +0 -0
  354. pandaserver/workflow/__init__.py +0 -0
  355. pandaserver/workflow/data_handler_plugins/base_data_handler.py +48 -0
  356. pandaserver/workflow/data_handler_plugins/ddm_collection_data_handler.py +100 -0
  357. pandaserver/workflow/data_handler_plugins/panda_task_data_handler.py +140 -0
  358. pandaserver/workflow/pcwl_test.py +122 -0
  359. pandaserver/workflow/pcwl_utils.py +384 -0
  360. pandaserver/workflow/psnakemake_container.json +68 -0
  361. pandaserver/workflow/psnakemake_task.json +62 -0
  362. pandaserver/workflow/psnakemake_test.py +60 -0
  363. pandaserver/workflow/snakeparser/__init__.py +3 -0
  364. pandaserver/workflow/snakeparser/extensions.py +74 -0
  365. pandaserver/workflow/snakeparser/log.py +53 -0
  366. pandaserver/workflow/snakeparser/names.py +3 -0
  367. pandaserver/workflow/snakeparser/parser.py +332 -0
  368. pandaserver/workflow/snakeparser/utils.py +29 -0
  369. pandaserver/workflow/step_handler_plugins/base_step_handler.py +85 -0
  370. pandaserver/workflow/step_handler_plugins/panda_task_step_handler.py +280 -0
  371. pandaserver/workflow/workflow_base.py +531 -0
  372. pandaserver/workflow/workflow_core.py +1974 -0
  373. pandaserver/workflow/workflow_core_smoketest.py +388 -0
  374. pandaserver/workflow/workflow_parser.py +222 -0
  375. pandaserver/workflow/workflow_utils.py +1047 -0
@@ -0,0 +1,207 @@
1
+ from typing import Any, Dict
2
+
3
+ from pandacommon.pandalogger.LogWrapper import LogWrapper
4
+ from pandacommon.pandalogger.PandaLogger import PandaLogger
5
+
6
+ from pandaserver.api.v1.common import generate_response, request_validation
7
+ from pandaserver.srvcore.panda_request import PandaRequest
8
+ from pandaserver.taskbuffer.TaskBuffer import TaskBuffer
9
+
10
+ _logger = PandaLogger().getLogger("api_statistics")
11
+
12
+ global_task_buffer = None
13
+
14
+ MAX_TIME_WINDOW = 60 * 24 * 7 # 7 days
15
+
16
+
17
+ def init_task_buffer(task_buffer: TaskBuffer) -> None:
18
+ """
19
+ Initialize the task buffer. This method needs to be called before any other method in this module.
20
+ """
21
+ global global_task_buffer
22
+ global_task_buffer = task_buffer
23
+
24
+
25
+ @request_validation(_logger, secure=False, request_method="GET")
26
+ def job_stats_by_cloud(req: PandaRequest, type: str = "production") -> Dict[str, Any]:
27
+ """
28
+ Job statistics by cloud.
29
+
30
+ Get the job statistics by cloud, which includes the active jobs and jobs in final states modified in the last 12 hours. You have to filter the statistics by type, which can be either "production" or "analysis". Used by panglia monitoring. Requires a secure connection.
31
+
32
+ API details:
33
+ HTTP Method: GET
34
+ Path: /v1/statistics/job_stats_by_cloud
35
+
36
+ Args:
37
+ req(PandaRequest): internally generated request object
38
+ type(str): can be "analysis" or "production". Defaults to "production" when not provided.
39
+
40
+ Returns:
41
+ dict: The system response `{"success": success, "message": message, "data": data}`. When successful, the data field contains the job statistics by cloud. When unsuccessful, the message field contains the error message.
42
+ """
43
+ tmp_logger = LogWrapper(_logger, f"job_stats_by_cloud < type={type} >")
44
+
45
+ tmp_logger.debug("Start")
46
+
47
+ if type not in ["production", "analysis"]:
48
+ tmp_logger.error("Invalid type parameter")
49
+ return generate_response(False, 'Parameter "type" needs to be either "production" or "analysis" ', {})
50
+
51
+ data = global_task_buffer.getJobStatisticsForExtIF(type)
52
+ success = data != {}
53
+ message = "" if success else "Database failure getting the job statistics"
54
+ tmp_logger.debug(f"Done. {message}")
55
+
56
+ return generate_response(success, message, data)
57
+
58
+
59
+ @request_validation(_logger, secure=False, request_method="GET")
60
+ def production_job_stats_by_cloud_and_processing_type(req: PandaRequest) -> Dict[str, Any]:
61
+ """
62
+ Production job statistics by cloud and processing type.
63
+
64
+ Get the production job statistics by cloud and processing type, which includes the active jobs and jobs in final states modified in the last 12 hours. Used by panglia monitoring. Requires a secure connection.
65
+
66
+ API details:
67
+ HTTP Method: GET
68
+ Path: /v1/statistics/production_job_stats_by_cloud_and_processing_type
69
+
70
+ Args:
71
+ req(PandaRequest): internally generated request object
72
+
73
+ Returns:
74
+ dict: The system response `{"success": success, "message": message, "data": data}`. When successful, the data field contains the job statistics by cloud. When unsuccessful, the message field contains the error message.
75
+ """
76
+
77
+ tmp_logger = LogWrapper(_logger, "production_job_stats_by_cloud_and_processing_type")
78
+
79
+ tmp_logger.debug("Start")
80
+ data = global_task_buffer.getJobStatisticsForBamboo()
81
+ success = data != {}
82
+ message = "" if success else "Database failure getting the job statistics"
83
+ tmp_logger.debug(f"Done. {message}")
84
+
85
+ return generate_response(success, message, data)
86
+
87
+
88
+ @request_validation(_logger, secure=False, request_method="GET")
89
+ def active_job_stats_by_site(req: PandaRequest) -> Dict[str, Any]:
90
+ """
91
+ Active job statistics by site
92
+
93
+ Get the active (not in a final state) job statistics by site. Used by Harvester. Requires a secure connection.
94
+
95
+ API details:
96
+ HTTP Method: GET
97
+ Path: /v1/statistics/active_job_stats_by_site
98
+
99
+ Args:
100
+ req(PandaRequest): internally generated request object
101
+
102
+ Returns:
103
+ dict: The system response `{"success": success, "message": message, "data": data}`. When successful, the data field contains the job statistics by cloud. When unsuccessful, the message field contains the error message.
104
+ """
105
+ tmp_logger = LogWrapper(_logger, "active_job_stats_by_site")
106
+
107
+ tmp_logger.debug("Start")
108
+ data = global_task_buffer.getJobStatistics()
109
+ success = data != {}
110
+ message = "" if success else "Database failure getting the job statistics"
111
+ tmp_logger.debug(f"Done. {message}")
112
+
113
+ return generate_response(success, message, data)
114
+
115
+
116
+ @request_validation(_logger, secure=False, request_method="GET")
117
+ def active_job_detailed_stats_by_site(req: PandaRequest) -> Dict[str, Any]:
118
+ """
119
+ Active job detailed statistics by site, resource_type and prodsourcelabel
120
+
121
+ Get the active (not in a final state) job statistics by site, resource_type and prodsourcelabel. Used by Harvester.
122
+
123
+ API details:
124
+ HTTP Method: GET
125
+ Path: /v1/statistics/active_job_detailed_stats_by_site
126
+
127
+ Args:
128
+ req(PandaRequest): internally generated request object
129
+
130
+ Returns:
131
+ dict: The system response `{"success": success, "message": message, "data": data}`. When successful, the data field contains the job statistics by site, resource_type and prodsourcelabel. When unsuccessful, the message field contains the error message.
132
+ """
133
+ tmp_logger = LogWrapper(_logger, "active_job_detailed_stats_by_site")
134
+
135
+ tmp_logger.debug("Start")
136
+ data = global_task_buffer.getDetailedJobStatistics()
137
+ success = data != {}
138
+ message = "" if success else "Database failure getting the job statistics with resource_type and prodsourcelabel"
139
+ tmp_logger.debug(f"Done. {message}")
140
+
141
+ return generate_response(success, message, data)
142
+
143
+
144
+ @request_validation(_logger, secure=False, request_method="GET")
145
+ def job_stats_by_site_and_resource_type(req: PandaRequest, time_window: int = None) -> Dict[str, Any]:
146
+ """
147
+ Job statistics by site and resource type
148
+
149
+ Get the job statistics by computing site (PanDA queue) and resource type (SCORE, MCORE, ...). This includes the active jobs and jobs in final states modified in the specified time window (default of 12 hours). Requires a secure connection.
150
+
151
+ API details:
152
+ HTTP Method: GET
153
+ Path: /v1/statistics/job_stats_by_site_and_resource_type
154
+
155
+ Args:
156
+ req(PandaRequest): internally generated request object
157
+ time_window(int, optional): time window in minutes for the statistics (affects only archived jobs)
158
+
159
+ Returns:
160
+ dict: The system response `{"success": success, "message": message, "data": data}`. When successful, the data field contains the job statistics by cloud. When unsuccessful, the message field contains the error message.
161
+ """
162
+ tmp_logger = LogWrapper(_logger, f"job_stats_by_site_and_resource_type < time_window={time_window} >")
163
+
164
+ tmp_logger.debug("Start")
165
+ if time_window is not None and (not isinstance(time_window, int) or time_window < 0 or time_window > MAX_TIME_WINDOW):
166
+ tmp_logger.error("Invalid time_window parameter")
167
+ return generate_response(False, 'Parameter "time_window" needs to be a positive integer smaller than 10080 min (7 days)', {})
168
+
169
+ data = global_task_buffer.getJobStatisticsPerSiteResource(time_window)
170
+ success = data != {}
171
+ message = "" if success else "Database failure getting the job statistics"
172
+ tmp_logger.debug(f"Done. {message}")
173
+
174
+ return generate_response(success, message, data)
175
+
176
+
177
+ @request_validation(_logger, secure=False, request_method="GET")
178
+ def job_stats_by_site_share_and_resource_type(req: PandaRequest, time_window: int = None) -> Dict[str, Any]:
179
+ """
180
+ Job statistics by site, global share and resource type
181
+
182
+ Get the job statistics by computing site (PanDA queue), global share and resource type (SCORE, MCORE, ...). This includes the active jobs and jobs in final states modified in the specified time window (default of 12 hours). Requires a secure connection.
183
+
184
+ API details:
185
+ HTTP Method: GET
186
+ Path: /v1/statistics/job_stats_by_site_share_and_resource_type
187
+
188
+ Args:
189
+ req(PandaRequest): internally generated request object
190
+ time_window(int): time window in minutes for the statistics (affects only archived jobs)
191
+
192
+ Returns:
193
+ dict: The system response `{"success": success, "message": message, "data": data}`. When successful, the data field contains the job statistics by cloud. When unsuccessful, the message field contains the error message.
194
+ """
195
+ tmp_logger = LogWrapper(_logger, f"job_stats_by_site_share_and_resource_type < time_window={time_window} >")
196
+
197
+ tmp_logger.debug("Start")
198
+ if time_window is not None and (not isinstance(time_window, int) or time_window < 0 or time_window > MAX_TIME_WINDOW):
199
+ tmp_logger.error("Invalid time_window parameter")
200
+ return generate_response(False, 'Parameter "time_window" needs to be a positive integer smaller than 10080 min (7 days)', {})
201
+
202
+ data = global_task_buffer.get_job_statistics_per_site_label_resource(time_window)
203
+ success = data != {}
204
+ message = "" if success else "Database failure getting the job statistics"
205
+ tmp_logger.debug(f"Done. {message}")
206
+
207
+ return generate_response(success, message, data)
@@ -0,0 +1,186 @@
1
+ from typing import Dict
2
+
3
+ from pandacommon.pandalogger.LogWrapper import LogWrapper
4
+ from pandacommon.pandalogger.PandaLogger import PandaLogger
5
+
6
+ from pandaserver.api.v1.common import (
7
+ extract_primary_production_working_group,
8
+ extract_production_working_groups,
9
+ generate_response,
10
+ get_dn,
11
+ get_email_address,
12
+ get_fqan,
13
+ has_production_role,
14
+ request_validation,
15
+ )
16
+ from pandaserver.config import panda_config
17
+ from pandaserver.srvcore.CoreUtils import clean_user_id
18
+ from pandaserver.srvcore.panda_request import PandaRequest
19
+
20
+ _logger = PandaLogger().getLogger("api_system")
21
+
22
+
23
+ @request_validation(_logger, secure=True, request_method="GET")
24
+ def get_attributes(req: PandaRequest, **kwargs: dict) -> Dict:
25
+ """
26
+ Get attributes
27
+
28
+ Gets all parameters and environment variables.
29
+
30
+ API details:
31
+ HTTP Method: GET
32
+ Path: /v1/system/get_attributes
33
+
34
+ Args:
35
+ req(PandaRequest): internally generated request object containing the env variables
36
+ **kwargs(dict): arbitrary keyword parameters that will be printed out
37
+
38
+ Returns:
39
+ dict: The system response `{"success": success, "message": message, "data": data}`.
40
+ When successful, the message field contains a string with all the attributes.
41
+ """
42
+ tmp_logger = LogWrapper(_logger, "get_attributes")
43
+ tmp_logger.debug("Start")
44
+
45
+ # Add the parameters
46
+ parameter_dictionary = {key: str(value) for key, value in sorted(kwargs.items())}
47
+ parameter_section = "===== param =====\n" + "\n".join(f"{key} = {value}" for key, value in parameter_dictionary.items())
48
+
49
+ # Add the environment variables
50
+ environment_dictionary = {key: str(req.subprocess_env[key]) for key in sorted(req.subprocess_env)}
51
+ environment_section = "\n====== env ======\n" + "\n".join(f"{key} : {value}" for key, value in environment_dictionary.items())
52
+
53
+ # Combine sections
54
+ text_representation = parameter_section + "\n" + environment_section + "\n"
55
+
56
+ # Combine data in dictionary form
57
+ combined_data = {"parameters": parameter_dictionary, "environment": environment_dictionary}
58
+ tmp_logger.debug("Done")
59
+ return generate_response(True, text_representation, combined_data)
60
+
61
+
62
+ @request_validation(_logger, secure=True, request_method="GET")
63
+ def get_voms_attributes(req: PandaRequest) -> Dict:
64
+ """
65
+ Get VOMS attributes
66
+
67
+ Gets the VOMS attributes (i.e. the ones starting with GRST) in sorted order. Requires a secure connection.
68
+
69
+ API details:
70
+ HTTP Method: GET
71
+ Path: /v1/system/get_voms_attributes
72
+
73
+ Args:
74
+ req(PandaRequest): internally generated request object containing the env variables
75
+
76
+ Returns:
77
+ dict: The system response with text representation and dictionary of attributes.
78
+ Example: `{"success": True, "message": "<formatted string>", "data": {"key": "value"}}`
79
+ """
80
+ tmp_logger = LogWrapper(_logger, "get_voms_attributes")
81
+ tmp_logger.debug("Start")
82
+
83
+ # Iterate over all the environment variables, keep only the ones related to GRST credentials (GRST: Grid Security Technology)
84
+ attributes = {}
85
+ for tmp_key, tmp_value in req.subprocess_env.items():
86
+ if tmp_key.startswith("GRST_CRED_"):
87
+ attributes[tmp_key] = tmp_value
88
+
89
+ # Create a sorted text representation
90
+ text_representation = "\n".join(f"{key} : {value}" for key, value in sorted(attributes.items()))
91
+
92
+ tmp_logger.debug("Done")
93
+ return generate_response(True, text_representation, attributes)
94
+
95
+
96
+ @request_validation(_logger, secure=True, request_method="GET")
97
+ def get_user_attributes(req: PandaRequest) -> Dict:
98
+ """
99
+ Get user attributes
100
+
101
+ Gets user attributes as seen by PanDA for debug purposes. Requires a secure connection.
102
+
103
+ API details:
104
+ HTTP Method: GET
105
+ Path: /v1/system/get_user_attributes
106
+
107
+ Args:
108
+ req(PandaRequest): internally generated request object containing the env variables
109
+
110
+ Returns:
111
+ dict: The system response `{"success": success, "message": message, "data": data}`.
112
+ When successful, the message field contains a string with the user attributes,
113
+ and the data field contains the dictionary representation.
114
+ """
115
+ tmp_logger = LogWrapper(_logger, "get_user_attributes")
116
+ tmp_logger.debug("Start")
117
+
118
+ # Raw user DN
119
+ user_raw = req.subprocess_env["SSL_CLIENT_S_DN"]
120
+
121
+ # Bare user DN
122
+ user_bare = get_dn(req)
123
+
124
+ # Clean user DN
125
+ user_clean = clean_user_id(user_raw)
126
+
127
+ # FQANs
128
+ fqans = get_fqan(req)
129
+
130
+ # Email address
131
+ email_address = get_email_address(user_clean, tmp_logger)
132
+
133
+ # Has production role
134
+ is_production_user = has_production_role(req)
135
+
136
+ # Production working groups
137
+ production_working_groups = extract_production_working_groups(fqans)
138
+
139
+ # Primary production working group
140
+ primary_working_group = extract_primary_production_working_group(fqans)
141
+
142
+ # Combine sections
143
+ text_representation = (
144
+ f"User DN (raw): {user_raw}\nUser DN (bare): {user_bare}\nUser DN (clean): {user_clean}\n"
145
+ f"Email address: {email_address}\n"
146
+ f"FQANs: {fqans}\nProduction user: {is_production_user}\n"
147
+ f"Production working groups: {production_working_groups}\nPrimary production working group: {primary_working_group}\n"
148
+ )
149
+ dictionary_representation = {
150
+ "user_dn_raw": user_raw,
151
+ "user_dn_clean": user_clean,
152
+ "fqans": fqans,
153
+ "is_production_user": is_production_user,
154
+ "production_working_groups": production_working_groups,
155
+ "primary_working_group": primary_working_group,
156
+ }
157
+
158
+ tmp_logger.debug(text_representation)
159
+
160
+ tmp_logger.debug("Done")
161
+ return generate_response(True, text_representation, dictionary_representation)
162
+
163
+
164
+ @request_validation(_logger, secure=False, request_method="GET")
165
+ def is_alive(req: PandaRequest) -> Dict:
166
+ """
167
+ Is alive
168
+
169
+ Check if the server is alive. Basic function for the health check used in SLS monitoring.
170
+
171
+ API details:
172
+ HTTP Method: GET
173
+ Path: /v1/system/is_alive
174
+
175
+ Args:
176
+ req(PandaRequest): internally generated request object containing the env variables
177
+
178
+ Returns:
179
+ dict: The system response with the name of the endpoint
180
+ Example: `{"success": True}`
181
+ """
182
+ tmp_logger = LogWrapper(_logger, "is_alive")
183
+ tmp_logger.debug("Start")
184
+ tmp_logger.debug("Done")
185
+
186
+ return generate_response(True)