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,227 @@
1
+ """
2
+ work queue specification
3
+
4
+ """
5
+
6
+ import re
7
+
8
+ from pandaserver.taskbuffer.GlobalShares import Share
9
+
10
+ RESOURCE = "Resource"
11
+ ACTIVE_FUNCTIONS = [RESOURCE]
12
+
13
+
14
+ class WorkQueue(object):
15
+ # attributes
16
+ _attributes = (
17
+ "queue_id",
18
+ "queue_name",
19
+ "queue_type",
20
+ "VO",
21
+ "queue_share",
22
+ "queue_order",
23
+ "criteria",
24
+ "variables",
25
+ "partitionID",
26
+ "stretchable",
27
+ "status",
28
+ "queue_function",
29
+ )
30
+
31
+ # parameters for selection criteria
32
+ _paramsForSelection = ("prodSourceLabel", "workingGroup", "processingType", "coreCount", "site", "eventService", "splitRule", "campaign")
33
+
34
+ # correspondence with Global Shares attributes and parameters
35
+ _attributes_gs_conversion_dic = {"name": "queue_name", "value": "queue_share", "prodsourcelabel": "queue_type", "queue_id": "queue_id", "vo": "VO"}
36
+
37
+ _params_gs_conversion_dic = {
38
+ "prodsourcelabel": "prodSourceLabel",
39
+ "workinggroup": "workingGroup",
40
+ "campaign": "campaign",
41
+ "processingtype": "processingType",
42
+ }
43
+
44
+ def __init__(self):
45
+ """
46
+ Constructor
47
+ """
48
+ # install attributes
49
+ for attr in self._attributes:
50
+ setattr(self, attr, None)
51
+
52
+ # global share is by default false
53
+ self.is_global_share = False
54
+ # throttled is set to True by default. Some Global Shares will overwrite it to False
55
+ self.throttled = True
56
+
57
+ def __str__(self):
58
+ """
59
+ String representation of a workqueue
60
+ :return: string with the representation of the work queue
61
+ """
62
+ return str(self.queue_name)
63
+
64
+ def dump(self):
65
+ """
66
+ Creates a human-friendly string with the work queue information
67
+ :return: string representation of the work queue
68
+ """
69
+ dump_str = f"id:{self.queue_id} order:{self.queue_order} name:{self.queue_name} share:{self.queue_share} "
70
+
71
+ # normal queue
72
+ if self.is_global_share:
73
+ dump_str += f"gs_name:{self.queue_name} (global share)"
74
+ else:
75
+ dump_str += f"criteria:{self.criteria} var:{str(self.variables)} eval:{self.evalString}"
76
+
77
+ return dump_str
78
+
79
+ def getID(self):
80
+ """
81
+ get ID
82
+ :return: returns a list with the ID of the work queue
83
+ """
84
+ return self.queue_id
85
+
86
+ def pack(self, values):
87
+ """
88
+ Packs tuple into the object
89
+ :param values: list with the values in the order declared in the attributes section
90
+ :return: nothing
91
+ """
92
+ for i, attr in enumerate(self._attributes):
93
+ val = values[i]
94
+ setattr(self, attr, val)
95
+
96
+ # disallow negative share
97
+ if self.queue_share is not None and self.queue_share < 0:
98
+ self.queue_share = 0
99
+
100
+ # convert variables string to a map of bind-variables
101
+ tmp_map = {}
102
+ try:
103
+ for item in self.variables.split(","):
104
+ # look for key: value
105
+ item = item.strip()
106
+ items = item.split(":")
107
+ if len(items) != 2:
108
+ continue
109
+ # add
110
+ tmp_map[f":{items[0]}"] = items[1]
111
+ except Exception:
112
+ pass
113
+ # assign map
114
+ self.variables = tmp_map
115
+ # make a python statement for eval
116
+ if self.criteria in ["", None]:
117
+ # catch all
118
+ self.evalString = "True"
119
+ else:
120
+ tmp_eval_str = self.criteria
121
+ # replace IN/OR/AND to in/or/and
122
+ tmp_eval_str = re.sub(" IN ", " in ", tmp_eval_str, re.I)
123
+ tmp_eval_str = re.sub(" OR ", " or ", tmp_eval_str, re.I)
124
+ tmp_eval_str = re.sub(" AND ", " and ", tmp_eval_str, re.I)
125
+ # replace = to ==
126
+ tmp_eval_str = tmp_eval_str.replace("=", "==")
127
+ # replace LIKE
128
+ tmp_eval_str = re.sub("(?P<var>[^ \(]+)\s+LIKE\s+(?P<pat>[^ \(]+)", "re.search(\g<pat>,\g<var>,re.I) is not None", tmp_eval_str, re.I)
129
+ # NULL
130
+ tmp_eval_str = re.sub(" IS NULL", "==None", tmp_eval_str)
131
+ tmp_eval_str = re.sub(" IS NOT NULL", "!=None", tmp_eval_str)
132
+ # replace NOT to not
133
+ tmp_eval_str = re.sub(" NOT ", " not ", tmp_eval_str, re.I)
134
+ # fomat cases
135
+ for tmp_param in self._paramsForSelection:
136
+ tmp_eval_str = re.sub(tmp_param, tmp_param, tmp_eval_str, re.I)
137
+ # replace bind-variables
138
+ for tmp_key, tmp_val in self.variables.items():
139
+ if "%" in tmp_val:
140
+ # wildcard
141
+ tmp_val = tmp_val.replace("%", ".*")
142
+ tmp_val = f"'^{tmp_val}$'"
143
+ else:
144
+ # normal variable
145
+ tmp_val = f"'{tmp_val}'"
146
+ tmp_eval_str = tmp_eval_str.replace(tmp_key, tmp_val)
147
+ # assign
148
+ self.evalString = tmp_eval_str
149
+
150
+ def pack_gs(self, gshare):
151
+ """
152
+ Packs tuple into the object
153
+ :param gshare: global share
154
+ :return: nothing
155
+ """
156
+
157
+ # the object becomes a global share wq
158
+ self.is_global_share = True
159
+ try:
160
+ tmp_map = {}
161
+ for i, attr in enumerate(gshare._attributes):
162
+ # global share attributes can be mapped to a wq attribute(1), to a wq param(2), or to none of both
163
+ # 1. if the gs attribute is mapped to a wq attribute, do a get and a set
164
+ if attr in self._attributes_gs_conversion_dic:
165
+ attr_wq = self._attributes_gs_conversion_dic[attr]
166
+ val = getattr(gshare, attr)
167
+ setattr(self, attr_wq, val)
168
+ # 2. if the gs attribute is mapped to a wq param, add it to the bind variables dictionary
169
+ # Probably we don't need this, we just care about matching the gs name
170
+ if attr in self._params_gs_conversion_dic:
171
+ param_wq = self._params_gs_conversion_dic[attr]
172
+ val = getattr(gshare, attr)
173
+ tmp_map[f":{param_wq}"] = val
174
+
175
+ # 3. Special case for throttled. This is defined additionally, since it's not present in WQs
176
+ if attr == "throttled" and gshare.throttled == "N":
177
+ self.throttled = False
178
+
179
+ self.variables = tmp_map
180
+ except Exception:
181
+ pass
182
+
183
+ # evaluate in python
184
+ def evaluate(self, param_map):
185
+ # only active queues are evaluated
186
+ if self.isActive():
187
+ # normal queue
188
+ # expand parameters to local namespace
189
+ for tmp_param_key, tmp_param_val in param_map.items():
190
+ if isinstance(tmp_param_val, str):
191
+ # add quotes for string
192
+ exec(f'{tmp_param_key}="{tmp_param_val}"', globals())
193
+ else:
194
+ exec(f"{tmp_param_key}={tmp_param_val}", globals())
195
+ # add default parameters if missing
196
+ for tmp_param in self._paramsForSelection:
197
+ if tmp_param not in param_map:
198
+ exec(f"{tmp_param}=None", globals())
199
+ # evaluate
200
+ exec(f"ret_var = {self.evalString}", globals())
201
+ return self, ret_var
202
+
203
+ # return False
204
+ return self, False
205
+
206
+ # check if active
207
+ def isActive(self):
208
+ if self.status != "inactive": # and self.queue_function in ACTIVE_FUNCTIONS:
209
+ return True
210
+ return False
211
+
212
+ # check if its eligible after global share alignment
213
+ def isAligned(self):
214
+ if self.queue_function == RESOURCE or self.is_global_share:
215
+ return True
216
+ return False
217
+
218
+ # return column names for INSERT
219
+ def column_names(cls):
220
+ ret = ""
221
+ for attr in cls._attributes:
222
+ if ret != "":
223
+ ret += ","
224
+ ret += attr
225
+ return ret
226
+
227
+ column_names = classmethod(column_names)
@@ -0,0 +1,203 @@
1
+ """
2
+ mapper to map task/job to a work queue
3
+
4
+ """
5
+
6
+ import re
7
+
8
+ from .WorkQueue import WorkQueue
9
+
10
+
11
+ class WorkQueueMapper:
12
+ # constructor
13
+ def __init__(self):
14
+ # Initialize maps
15
+ self.work_queue_map = {}
16
+ self.work_queue_global_dic_by_name = {}
17
+ self.work_queue_global_dic_by_id = {}
18
+
19
+ def getSqlQuery(self):
20
+ """
21
+ Generates the SQL to get all work queues
22
+ """
23
+ sql = f"SELECT {WorkQueue.column_names()} FROM ATLAS_PANDA.JEDI_Work_Queue"
24
+
25
+ return sql
26
+
27
+ def makeMap(self, work_queues, global_leave_shares):
28
+ """
29
+ Creates the mapping with work queues and global shares
30
+ :param work_queues: work queues
31
+ :param global_leave_shares: global leave shares
32
+ :return
33
+ """
34
+
35
+ # 1. add all workqueues to the map
36
+ for wq in work_queues:
37
+ # pack
38
+ work_queue = WorkQueue()
39
+ work_queue.pack(wq)
40
+
41
+ # skip inactive queues
42
+ if not work_queue.isActive():
43
+ continue
44
+
45
+ # add VO
46
+ if work_queue.VO not in self.work_queue_map:
47
+ self.work_queue_map[work_queue.VO] = {}
48
+
49
+ # add type
50
+ if work_queue.queue_type not in self.work_queue_map[work_queue.VO]:
51
+ self.work_queue_map[work_queue.VO][work_queue.queue_type] = []
52
+
53
+ self.work_queue_map[work_queue.VO][work_queue.queue_type].append(work_queue)
54
+ self.work_queue_global_dic_by_name[work_queue.queue_name] = work_queue
55
+ self.work_queue_global_dic_by_id[work_queue.queue_id] = work_queue
56
+
57
+ # sort the queue list by order
58
+ for vo in self.work_queue_map:
59
+ for type in self.work_queue_map[vo]:
60
+ # make ordered map
61
+ ordered_map = {}
62
+ queue_map = self.work_queue_map[vo][type]
63
+ for wq in queue_map:
64
+ if wq.queue_order not in ordered_map:
65
+ ordered_map[wq.queue_order] = []
66
+ # append
67
+ ordered_map[wq.queue_order].append(wq)
68
+ # make sorted list
69
+ ordered_list = list(ordered_map.keys())
70
+ ordered_list.sort(key=lambda x: (x is None, x))
71
+ new_list = []
72
+ for order_val in ordered_list:
73
+ new_list += ordered_map[order_val]
74
+ # set new list
75
+ self.work_queue_map[vo][type] = new_list
76
+
77
+ # 2. add all the global shares
78
+ for gs in global_leave_shares:
79
+ work_queue_gs = WorkQueue()
80
+ work_queue_gs.pack_gs(gs)
81
+
82
+ if work_queue_gs.VO is None:
83
+ vo = "atlas"
84
+ else:
85
+ vo = work_queue_gs.VO
86
+
87
+ if vo not in self.work_queue_map:
88
+ self.work_queue_map[vo] = {}
89
+
90
+ if work_queue_gs.queue_type not in self.work_queue_map[vo]:
91
+ self.work_queue_map[vo][work_queue_gs.queue_type] = []
92
+
93
+ self.work_queue_map[vo][work_queue_gs.queue_type].append(work_queue_gs)
94
+ self.work_queue_global_dic_by_name[work_queue_gs.queue_name] = work_queue_gs
95
+ self.work_queue_global_dic_by_id[work_queue_gs.queue_id] = work_queue_gs
96
+
97
+ # return
98
+ return
99
+
100
+ def dump(self):
101
+ """
102
+ Creates a human-friendly string showing the work queue mappings
103
+ :return: string representation of the work queue mappings
104
+ """
105
+ dump_str = "WorkQueue mapping\n"
106
+ for VO in self.work_queue_map:
107
+ dump_str += f" VO={VO}\n"
108
+ for type in self.work_queue_map[VO]:
109
+ dump_str += f" type={type}\n"
110
+ for workQueue in self.work_queue_map[VO][type]:
111
+ dump_str += f" {workQueue.dump()}\n"
112
+ # return
113
+ return dump_str
114
+
115
+ def getQueueWithSelParams(self, vo, type, **param_map):
116
+ """
117
+ Used for tagging of work queues in task refiner. Get a work queue based on the selection parameters
118
+ :param vo: vo
119
+ :param type: type (in practice equivalent to prodsourcelabel)
120
+ :param param_map: parameter selection map
121
+ :return: work queue object and explanation in case no queue was found
122
+ """
123
+ ret_str = ""
124
+ if vo not in self.work_queue_map:
125
+ ret_str = f"queues for vo={vo} are undefined"
126
+ elif type not in self.work_queue_map[vo]:
127
+ # check type
128
+ ret_str = f"queues for type={type} are undefined in vo={vo}"
129
+ else:
130
+ for wq in self.work_queue_map[vo][type]:
131
+ # don't return global share IDs for work queues
132
+ if wq.is_global_share:
133
+ continue
134
+
135
+ # evaluate
136
+ try:
137
+ ret_queue, result = wq.evaluate(param_map)
138
+ if result:
139
+ return ret_queue, ret_str
140
+ except Exception:
141
+ ret_str += f"{wq.queue_name},"
142
+
143
+ ret_str = ret_str[:-1]
144
+ if ret_str != "":
145
+ new_ret_str = f"eval with VO={vo} "
146
+ for tmp_param_key, tmp_param_val in param_map.items():
147
+ new_ret_str += "{0}={1} failed for {0}".format(tmp_param_key, tmp_param_val, ret_str)
148
+ ret_str = new_ret_str
149
+
150
+ # no queue matched to selection parameters
151
+ return None, ret_str
152
+
153
+ def getQueueByName(self, vo, type, queue_name):
154
+ """
155
+ # get queue by name
156
+ :param queue_name: name of the queue
157
+ :param vo: vo
158
+ :param type: type
159
+ :return: queue object or None if not found
160
+ """
161
+ if vo in self.work_queue_map and type in self.work_queue_map[vo]:
162
+ for wq in self.work_queue_map[vo][type]:
163
+ if wq.queue_name == queue_name:
164
+ return wq
165
+ return None
166
+
167
+ # get queue with ID
168
+ def getQueueWithIDGshare(self, queue_id, gshare_name):
169
+ # 1. Check for a Resource queue
170
+ if queue_id in self.work_queue_global_dic_by_id and self.work_queue_global_dic_by_id[queue_id].queue_function == "Resource":
171
+ return self.work_queue_global_dic_by_id[queue_id]
172
+
173
+ # 2. If it wasn't a resource queue, return the global share work queue
174
+ if gshare_name in self.work_queue_global_dic_by_name:
175
+ return self.work_queue_global_dic_by_name[gshare_name]
176
+
177
+ # not found
178
+ return None
179
+
180
+ # get queue list with VO and type
181
+ def getAlignedQueueList(self, vo, queue_type):
182
+ """
183
+ NOTE: Returns ONLY resource queues and global shares (old non-resource queues are skipped)
184
+ """
185
+ ret_list = []
186
+
187
+ if vo in self.work_queue_map:
188
+ # if queue type was specified
189
+ if queue_type not in ["", None, "any"]:
190
+ for map_queue_type in self.work_queue_map[vo]:
191
+ if re.match(map_queue_type, queue_type):
192
+ for tmp_wq in self.work_queue_map[vo][map_queue_type]:
193
+ if tmp_wq.isAligned():
194
+ ret_list.append(tmp_wq)
195
+
196
+ # include all queue types
197
+ else:
198
+ for tmp_type, tmp_wq_list in self.work_queue_map[vo].items():
199
+ for tmp_wq in tmp_wq_list:
200
+ if tmp_wq.isAligned():
201
+ ret_list.append(tmp_wq)
202
+
203
+ return ret_list
@@ -0,0 +1,143 @@
1
+ """
2
+ worker specification
3
+
4
+ """
5
+
6
+ import datetime
7
+
8
+
9
+ class WorkerSpec(object):
10
+ # attributes
11
+ _attributes = (
12
+ "harvesterID",
13
+ "workerID",
14
+ "batchID",
15
+ "queueName",
16
+ "status",
17
+ "computingSite",
18
+ "nCore",
19
+ "nodeID",
20
+ "submitTime",
21
+ "startTime",
22
+ "endTime",
23
+ "lastUpdate",
24
+ "stdOut",
25
+ "stdErr",
26
+ "batchLog",
27
+ "jdl",
28
+ "resourceType",
29
+ "nativeExitCode",
30
+ "nativeStatus",
31
+ "diagMessage",
32
+ "nJobs",
33
+ "computingElement",
34
+ "submissionHost",
35
+ "harvesterHost",
36
+ "errorCode",
37
+ "jobType",
38
+ "minRamCount",
39
+ )
40
+ # slots
41
+ __slots__ = _attributes + ("_changedAttrs",)
42
+ # attributes which have 0 by default
43
+ _zeroAttrs = ()
44
+ # catchall resouce type
45
+ RT_catchall = "ANY"
46
+
47
+ # constructor
48
+ def __init__(self):
49
+ # install attributes
50
+ for attr in self._attributes:
51
+ object.__setattr__(self, attr, None)
52
+ # map of changed attributes
53
+ object.__setattr__(self, "_changedAttrs", {})
54
+
55
+ # override __setattr__ to collect the changed attributes
56
+ def __setattr__(self, name, value):
57
+ oldVal = getattr(self, name)
58
+ # convert string to datetime
59
+ if isinstance(value, str) and value.startswith("datetime/"):
60
+ value = datetime.datetime.strptime(value.split("/")[-1], "%Y-%m-%d %H:%M:%S.%f")
61
+ object.__setattr__(self, name, value)
62
+ # collect changed attributes
63
+ if oldVal != value:
64
+ self._changedAttrs[name] = value
65
+
66
+ # reset changed attribute list
67
+ def resetChangedList(self):
68
+ self._oldPandaID = self.PandaID
69
+ object.__setattr__(self, "_changedAttrs", {})
70
+
71
+ # return map of values
72
+ def valuesMap(self, onlyChanged=False):
73
+ ret = {}
74
+ for attr in self._attributes:
75
+ if onlyChanged and attr not in self._changedAttrs:
76
+ continue
77
+ val = getattr(self, attr)
78
+ if val is None:
79
+ if attr in self._zeroAttrs:
80
+ val = 0
81
+ ret[f":{attr}"] = val
82
+ return ret
83
+
84
+ # pack tuple into FileSpec
85
+ def pack(self, values):
86
+ for i in range(len(self._attributes)):
87
+ attr = self._attributes[i]
88
+ val = values[i]
89
+ object.__setattr__(self, attr, val)
90
+
91
+ # return column names for INSERT
92
+ def columnNames(cls, prefix=None):
93
+ ret = ""
94
+ for attr in cls._attributes:
95
+ if prefix is not None:
96
+ ret += f"{prefix}."
97
+ ret += f"{attr},"
98
+ ret = ret[:-1]
99
+ return ret
100
+
101
+ columnNames = classmethod(columnNames)
102
+
103
+ # return expression of bind variables for INSERT
104
+ def bindValuesExpression(cls):
105
+ from pandaserver.config import panda_config
106
+
107
+ ret = "VALUES("
108
+ for attr in cls._attributes:
109
+ ret += f":{attr},"
110
+ ret = ret[:-1]
111
+ ret += ")"
112
+ return ret
113
+
114
+ bindValuesExpression = classmethod(bindValuesExpression)
115
+
116
+ # return an expression of bind variables for UPDATE to update only changed attributes
117
+ def bindUpdateChangesExpression(self):
118
+ ret = ""
119
+ for attr in self._attributes:
120
+ if attr not in self._changedAttrs:
121
+ continue
122
+ ret += "{0}=:{0},".format(attr)
123
+ ret = ret[:-1]
124
+ return ret
125
+
126
+ # return state values to be pickled
127
+ def __getstate__(self):
128
+ state = []
129
+ for attr in self._attributes:
130
+ val = getattr(self, attr)
131
+ state.append(val)
132
+ state.append(self._changedAttrs)
133
+ return state
134
+
135
+ # restore state from the unpickled state values
136
+ def __setstate__(self, state):
137
+ i = 0
138
+ for attr in self._attributes:
139
+ if i >= len(state) - 1:
140
+ break
141
+ object.__setattr__(self, attr, state[i])
142
+ i += 1
143
+ object.__setattr__(self, "_changedAttrs", state[-1])