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,232 @@
1
+ import json
2
+ import re
3
+
4
+ from pandaserver.srvcore.CoreUtils import NonJsonObjectEncoder, as_python_object
5
+ from pandaserver.taskbuffer.JobSpec import JobSpec
6
+
7
+ # list of prod source label for pilot tests
8
+ list_ptest_prod_sources = ["ptest", "rc_test", "rc_test2", "rc_alrb"]
9
+
10
+ # mapping with prodsourcelabels that belong to analysis and production
11
+ analy_sources = ["user", "panda"]
12
+ prod_sources = ["managed", "prod_test"]
13
+ neutral_sources = ["install"] + list_ptest_prod_sources
14
+
15
+ ANALY_PS = "user"
16
+ PROD_PS = "managed"
17
+
18
+ ANALY_TASKTYPE = "anal"
19
+ PROD_TASKTYPE = "prod"
20
+
21
+ MEMORY_COMPENSATION = 0.9
22
+
23
+ job_labels = [ANALY_PS, PROD_PS]
24
+
25
+ # priority of tasks to jumbo over others
26
+ priorityTasksToJumpOver = 1500
27
+
28
+
29
+ def translate_prodsourcelabel_to_jobtype(queue_type, prodsourcelabel):
30
+ if prodsourcelabel in analy_sources:
31
+ return ANALY_PS
32
+
33
+ if prodsourcelabel in prod_sources:
34
+ return PROD_PS
35
+
36
+ if prodsourcelabel in neutral_sources:
37
+ if queue_type == "unified" or queue_type == "production":
38
+ return PROD_PS
39
+ if queue_type == "analysis":
40
+ return ANALY_PS
41
+
42
+ # currently unmapped
43
+ return prodsourcelabel
44
+
45
+
46
+ def translate_tasktype_to_jobtype(task_type):
47
+ # any unrecognized tasktype will be defaulted to production
48
+ if task_type == ANALY_TASKTYPE:
49
+ return ANALY_PS
50
+ else:
51
+ return PROD_PS
52
+
53
+
54
+ # get core count
55
+ def getCoreCount(actualCoreCount, defCoreCount, jobMetrics):
56
+ coreCount = 1
57
+ try:
58
+ if actualCoreCount is not None:
59
+ coreCount = actualCoreCount
60
+ else:
61
+ tmpMatch = None
62
+ if jobMetrics is not None:
63
+ # extract coreCount
64
+ tmpMatch = re.search("coreCount=(\d+)", jobMetrics)
65
+ if tmpMatch is not None:
66
+ coreCount = int(tmpMatch.group(1))
67
+ else:
68
+ # use jobdef
69
+ if defCoreCount not in [None, 0]:
70
+ coreCount = defCoreCount
71
+ except Exception:
72
+ pass
73
+ return coreCount
74
+
75
+
76
+ # get HS06sec
77
+ def getHS06sec(startTime, endTime, corePower, coreCount, baseWalltime=0, cpuEfficiency=100):
78
+ try:
79
+ # no scaling
80
+ if cpuEfficiency == 0:
81
+ return 0
82
+ # get execution time
83
+ tmpTimeDelta = endTime - startTime
84
+ tmpVal = tmpTimeDelta.seconds + tmpTimeDelta.days * 24 * 3600
85
+ if tmpVal <= baseWalltime:
86
+ return 0
87
+ hs06sec = float(tmpVal - baseWalltime) * corePower * coreCount * float(cpuEfficiency) / 100.0
88
+ return hs06sec
89
+ except Exception:
90
+ return None
91
+
92
+
93
+ def get_job_co2(start_time, end_time, core_count, energy_emissions, watts_per_core):
94
+ energy_emissions_by_ts = {}
95
+ for entry in energy_emissions:
96
+ aux_timestamp, region, value = entry
97
+ energy_emissions_by_ts[aux_timestamp] = {"value": value}
98
+
99
+ try:
100
+ timestamps = sorted([entry[0] for entry in energy_emissions])
101
+
102
+ started = False
103
+ ended = False
104
+ i = 0
105
+
106
+ g_co2_job = 0
107
+
108
+ for timestamp in timestamps:
109
+ try:
110
+ if start_time < timestamps[i + 1] and not started:
111
+ started = True
112
+ except IndexError:
113
+ pass
114
+
115
+ if end_time < timestamp and not ended:
116
+ ended = True
117
+
118
+ if started and not ended or i == len(timestamps) - 1:
119
+ bottom = max(start_time, timestamp)
120
+ try:
121
+ top = min(end_time, timestamps[i + 1])
122
+ except IndexError:
123
+ top = end_time
124
+
125
+ g_co2_perkWh = energy_emissions_by_ts[timestamp]["value"]
126
+
127
+ duration = max((top - bottom).total_seconds(), 0)
128
+ g_co2_job = g_co2_job + (duration * g_co2_perkWh * core_count * watts_per_core / 3600 / 1000)
129
+
130
+ if ended:
131
+ break
132
+
133
+ i = i + 1
134
+
135
+ return g_co2_job
136
+
137
+ except Exception:
138
+ return None
139
+
140
+
141
+ # parse string for number of standby jobs
142
+ def parseNumStandby(catchall):
143
+ retMap = {}
144
+ if catchall is not None:
145
+ for tmpItem in catchall.split(","):
146
+ tmpMatch = re.search("^nStandby=(.+)", tmpItem)
147
+ if tmpMatch is None:
148
+ continue
149
+ for tmpSubStr in tmpMatch.group(1).split("|"):
150
+ if len(tmpSubStr.split(":")) != 3:
151
+ continue
152
+ sw_id, resource_type, num = tmpSubStr.split(":")
153
+ try:
154
+ sw_id = int(sw_id)
155
+ except Exception:
156
+ pass
157
+ if sw_id not in retMap:
158
+ retMap[sw_id] = {}
159
+ if num == "":
160
+ num = 0
161
+ else:
162
+ num = int(num)
163
+ retMap[sw_id][resource_type] = num
164
+ break
165
+ return retMap
166
+
167
+
168
+ # compensate memory count to prevent jobs with ramCount close to the HIMEM border from going to HIMEM PQs
169
+ def compensate_ram_count(ram_count):
170
+ if ram_count in ("NULL", None):
171
+ return None
172
+ ram_count = int(ram_count * MEMORY_COMPENSATION)
173
+ return ram_count
174
+
175
+
176
+ # undo the memory count compensation
177
+ def decompensate_ram_count(ram_count):
178
+ if ram_count in ("NULL", None):
179
+ return None
180
+ ram_count = int(ram_count / MEMORY_COMPENSATION)
181
+ return ram_count
182
+
183
+
184
+ # dump jobs to serialized json
185
+ def dump_jobs_json(jobs):
186
+ state_objects = []
187
+ for job_spec in jobs:
188
+ state_objects.append(job_spec.dump_to_json_serializable())
189
+ return json.dumps(state_objects, cls=NonJsonObjectEncoder)
190
+
191
+
192
+ # load serialized json to jobs
193
+ def load_jobs_json(state):
194
+ state_objects = json.loads(state, object_hook=as_python_object)
195
+ jobs = []
196
+ for job_state in state_objects:
197
+ job_spec = JobSpec()
198
+ job_spec.load_from_json_serializable(job_state)
199
+ jobs.append(job_spec)
200
+ return jobs
201
+
202
+
203
+ # get resource type for a job
204
+ def get_resource_type_job(resource_map: list, job_spec: JobSpec) -> str:
205
+ """
206
+ Get the resource type for a job based on the job's resource type and the list of resource types.
207
+ :param resource_map: The list of resource types.
208
+ :param job_spec: The job.
209
+ :return: The resource type.
210
+ """
211
+ for resource_spec in resource_map:
212
+ if resource_spec.match_job(job_spec):
213
+ return resource_spec.resource_name
214
+ return "Undefined"
215
+
216
+
217
+ # get min ram count for job
218
+ def getJobMinRamCount(taskSpec, inputChunk, siteSpec, coreCount):
219
+ minRamCount = inputChunk.getMaxRamCount()
220
+ if inputChunk.isMerging:
221
+ minRamUnit = "MB"
222
+ else:
223
+ minRamUnit = taskSpec.ramUnit
224
+ if minRamUnit in [None, "", "NULL"]:
225
+ minRamUnit = "MB"
226
+ if taskSpec.ramPerCore():
227
+ minRamCount *= coreCount
228
+ minRamCount += taskSpec.baseRamCount
229
+ minRamUnit = re.sub("PerCore.*$", "", minRamUnit)
230
+ # round up with chunks
231
+ minRamCount = compensate_ram_count(minRamCount)
232
+ return minRamCount, minRamUnit
@@ -0,0 +1,116 @@
1
+ """
2
+ nucleus specification
3
+
4
+ """
5
+
6
+ import re
7
+
8
+
9
+ class NucleusSpec(object):
10
+ # constructor
11
+ def __init__(self, name):
12
+ self.name = name
13
+ self.allPandaSites = []
14
+ self.allDdmEndPoints = {}
15
+ self.all_ddm_endpoints_in = {}
16
+ self.state = None
17
+ self.bareNucleus = None
18
+ self.secondaryNucleus = None
19
+ self.nucleus = True
20
+ self.default_ddm_endpoint_out = None
21
+
22
+ # add
23
+ def add(self, siteName, ddmSpecDict, ddmSpecDictForInput=None):
24
+ if siteName not in self.allPandaSites:
25
+ self.allPandaSites.append(siteName)
26
+ # add local endpoints
27
+ for scope in ddmSpecDict:
28
+ ddmSpec = ddmSpecDict[scope]
29
+ for localEndPoint in ddmSpec.getLocalEndPoints():
30
+ if localEndPoint not in self.allDdmEndPoints:
31
+ self.allDdmEndPoints[localEndPoint] = ddmSpec.getEndPoint(localEndPoint)
32
+ if ddmSpecDictForInput is not None:
33
+ # add endpoints
34
+ for scope in ddmSpecDictForInput:
35
+ ddmSpec = ddmSpecDictForInput[scope]
36
+ for localEndPoint in ddmSpec.getAllEndPoints():
37
+ if localEndPoint not in self.all_ddm_endpoints_in:
38
+ self.all_ddm_endpoints_in[localEndPoint] = ddmSpec.getEndPoint(localEndPoint)
39
+
40
+ # check if associated panda site
41
+ def isAssociatedPandaSite(self, siteName):
42
+ return siteName in self.allPandaSites
43
+
44
+ # check if associated DDM endpoint
45
+ def isAssociatedEndpoint(self, endPoint):
46
+ return endPoint in self.allDdmEndPoints
47
+
48
+ # check if associated endpoint for input
49
+ def is_associated_for_input(self, endpoint):
50
+ return endpoint in self.all_ddm_endpoints_in
51
+
52
+ # get associated DDM endpoint
53
+ def getEndpoint(self, endpoint):
54
+ try:
55
+ if endpoint in self.allDdmEndPoints:
56
+ return self.allDdmEndPoints[endpoint]
57
+ return self.all_ddm_endpoints_in[endpoint]
58
+ except Exception:
59
+ return None
60
+
61
+ def getAssociatedEndpoint(self, pattern):
62
+ pattern = pattern.split("/")[-1]
63
+ if pattern.startswith("dst:"):
64
+ pattern = pattern.split(":")[-1]
65
+
66
+ if pattern in self.allDdmEndPoints:
67
+ return self.allDdmEndPoints[pattern]
68
+
69
+ for endpoint_name in self.allDdmEndPoints:
70
+ if re.search(pattern, endpoint_name) is not None:
71
+ return self.allDdmEndPoints[endpoint_name]
72
+
73
+ pattern_without_vo = re.sub("ATLAS", "", pattern)
74
+
75
+ if self.allDdmEndPoints[endpoint_name]["type"] == pattern_without_vo:
76
+ return self.allDdmEndPoints[endpoint_name]
77
+
78
+ return None
79
+
80
+ # get one panda site
81
+ def getOnePandaSite(self):
82
+ if len(self.allPandaSites) > 0:
83
+ return self.allPandaSites[0]
84
+ return None
85
+
86
+ # set bare nucleus mode
87
+ def set_bare_nucleus_mode(self, mode):
88
+ self.bareNucleus = mode
89
+
90
+ # get bare nucleus mode
91
+ def get_bare_nucleus_mode(self):
92
+ return self.bareNucleus
93
+
94
+ # set secondary nucleus
95
+ def set_secondary_nucleus(self, nucleus):
96
+ self.secondaryNucleus = nucleus
97
+
98
+ # get secondary nucleus
99
+ def get_secondary_nucleus(self):
100
+ return self.secondaryNucleus
101
+
102
+ # set satellite
103
+ def set_satellite(self):
104
+ self.nucleus = False
105
+
106
+ # check if nucleus
107
+ def is_nucleus(self):
108
+ return self.nucleus
109
+
110
+ # set default endpoint for output
111
+ def set_default_endpoint_out(self, rse):
112
+ self.default_ddm_endpoint_out = rse
113
+
114
+ # get default endpoint for output
115
+ def get_default_endpoint_out(self):
116
+ return self.getEndpoint(self.default_ddm_endpoint_out)
@@ -0,0 +1,174 @@
1
+ """
2
+ proxy for database connection
3
+
4
+ """
5
+
6
+ import atexit
7
+ import logging
8
+ import warnings
9
+
10
+ from pandacommon.pandalogger.PandaLogger import PandaLogger
11
+
12
+ from pandaserver.config import panda_config
13
+ from pandaserver.taskbuffer.db_proxy_mods import (
14
+ data_carousel_module,
15
+ entity_module,
16
+ job_complex_module,
17
+ job_standalone_module,
18
+ metrics_module,
19
+ misc_standalone_module,
20
+ task_complex_module,
21
+ task_event_module,
22
+ task_standalone_module,
23
+ task_utils_module,
24
+ worker_module,
25
+ workflow_module,
26
+ )
27
+ from pandaserver.taskbuffer.WrappedCursor import WrappedCursor
28
+
29
+ try:
30
+ import idds.common.constants
31
+ import idds.common.utils
32
+ from idds.client.client import Client as iDDS_Client
33
+ except ImportError:
34
+ pass
35
+
36
+ if panda_config.backend == "oracle":
37
+ import oracledb
38
+
39
+ from . import wrapped_oracle_conn
40
+
41
+ oracledb.init_oracle_client()
42
+
43
+ elif panda_config.backend == "postgres":
44
+ import psycopg2 as psycopg
45
+
46
+ from . import WrappedPostgresConn
47
+
48
+ else:
49
+ import MySQLdb
50
+
51
+ warnings.filterwarnings("ignore")
52
+
53
+ # logger
54
+ _logger = PandaLogger().getLogger("DBProxy")
55
+ _loggerFiltered = PandaLogger().getLogger("DBProxyFiltered")
56
+
57
+ # add handlers
58
+ for handler in _loggerFiltered.handlers:
59
+ handler.setLevel(logging.INFO)
60
+ _logger.addHandler(handler)
61
+ _loggerFiltered.removeHandler(handler)
62
+
63
+
64
+ # proxy
65
+ class DBProxy(
66
+ entity_module.EntityModule,
67
+ metrics_module.MetricsModule,
68
+ worker_module.WorkerModule,
69
+ data_carousel_module.DataCarouselModule,
70
+ task_event_module.TaskEventModule,
71
+ job_complex_module.JobComplexModule,
72
+ job_standalone_module.JobStandaloneModule,
73
+ misc_standalone_module.MiscStandaloneModule,
74
+ task_complex_module.TaskComplexModule,
75
+ task_standalone_module.TaskStandaloneModule,
76
+ task_utils_module.TaskUtilsModule,
77
+ workflow_module.WorkflowModule,
78
+ ):
79
+ # constructor
80
+ def __init__(self, useOtherError=False):
81
+ # init modules
82
+ super().__init__(_logger)
83
+ # connection object
84
+ self.conn = None
85
+ # cursor object
86
+ self.cur = None
87
+
88
+ # use special error codes for reconnection in querySQL
89
+ self.useOtherError = useOtherError
90
+
91
+ # set composite modules. use self to share a single database connection
92
+ self.add_composite_module("entity", self)
93
+ self.add_composite_module("metrics", self)
94
+ self.add_composite_module("worker", self)
95
+ self.add_composite_module("task_event", self)
96
+ self.add_composite_module("task_utils", self)
97
+ self.add_composite_module("job_complex", self)
98
+
99
+ # connect to DB
100
+ def connect(
101
+ self,
102
+ dbhost=panda_config.dbhost,
103
+ dbpasswd=panda_config.dbpasswd,
104
+ dbuser=panda_config.dbuser,
105
+ dbname=panda_config.dbname,
106
+ dbtimeout=panda_config.dbtimeout,
107
+ reconnect=False,
108
+ dbport=panda_config.dbport,
109
+ ):
110
+ _logger.debug(f"connect : re={reconnect}")
111
+ # keep parameters for reconnect
112
+ if not reconnect:
113
+ self.dbhost = dbhost
114
+ self.dbpasswd = dbpasswd
115
+ self.dbuser = dbuser
116
+ self.dbname = dbname
117
+ self.dbtimeout = dbtimeout
118
+ self.dbport = dbport
119
+ # close old connection
120
+ if reconnect:
121
+ _logger.debug("closing old connection")
122
+ try:
123
+ self.conn.close()
124
+ except Exception:
125
+ _logger.debug("failed to close old connection")
126
+ # connect
127
+ try:
128
+ if self.backend == "oracle":
129
+ conn = oracledb.connect(dsn=self.dbhost, user=self.dbuser, password=self.dbpasswd)
130
+
131
+ def OutputTypeHandler(cursor, name, defaultType, size, precision, scale):
132
+ if defaultType == oracledb.CLOB:
133
+ return cursor.var(oracledb.LONG_STRING, arraysize=cursor.arraysize)
134
+
135
+ conn.outputtypehandler = OutputTypeHandler
136
+ self.conn = wrapped_oracle_conn.WrappedOracleConn(conn)
137
+
138
+ elif self.backend == "postgres":
139
+ dsn = {"dbname": self.dbname, "user": self.dbuser, "keepalives_idle": 30, "keepalives_interval": 30, "keepalives": 1}
140
+ if self.dbpasswd:
141
+ dsn["password"] = self.dbpasswd
142
+ if self.dbhost:
143
+ dsn["host"] = self.dbhost
144
+ if self.dbport:
145
+ dsn["port"] = self.dbport
146
+ conn = psycopg.connect(**dsn)
147
+ self.conn = WrappedPostgresConn.WrappedPostgresConn(conn)
148
+ else:
149
+ self.conn = MySQLdb.connect(
150
+ host=self.dbhost,
151
+ db=self.dbname,
152
+ port=self.dbport,
153
+ connect_timeout=self.dbtimeout,
154
+ user=self.dbuser,
155
+ passwd=self.dbpasswd,
156
+ charset="utf8",
157
+ )
158
+ self.cur = WrappedCursor(self.conn)
159
+ try:
160
+ # use SQL dumper
161
+ if panda_config.dump_sql:
162
+ from pandaserver.taskbuffer.SQLDumper import SQLDumper
163
+
164
+ self.cur = SQLDumper(self.cur)
165
+ except Exception:
166
+ pass
167
+ self.hostname = self.cur.initialize()
168
+ if not reconnect:
169
+ atexit.register(self.close_connection)
170
+ _logger.debug(f"connect : re={reconnect} ready")
171
+ return True
172
+ except Exception as e:
173
+ _logger.error(f"connect : {str(e)}")
174
+ return False
@@ -0,0 +1,8 @@
1
+ from pandacommon.pandalogger import logger_utils
2
+ from pandacommon.pandamsgbkr import msg_processor
3
+ from pandaserver.config import panda_config
4
+
5
+
6
+ # Main message processing agent
7
+ class MsgProcAgent(msg_processor.MsgProcAgentBase):
8
+ pass
@@ -0,0 +1,18 @@
1
+ """
2
+ Minimum schema version required for the panda-server to work properly.
3
+ Please always keep this version number up to date.
4
+ """
5
+
6
+ from pandacommon.pandalogger.PandaLogger import PandaLogger
7
+
8
+ # logger
9
+ _logger = PandaLogger().getLogger("DBSchema")
10
+
11
+
12
+ class PandaDBSchemaInfo:
13
+ schema_version = None
14
+
15
+ def method(self):
16
+ schema_version = "0.1.1"
17
+ _logger.debug(f"PanDA schema version required for Server is : {schema_version}")
18
+ return schema_version