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,513 @@
1
+ """
2
+ ConBridge allows having database interactions in separate processes and killing them independently when interactions are stalled.
3
+ This avoids clogged httpd processes due to stalled database accesses.
4
+ """
5
+
6
+ import os
7
+ import pickle
8
+ import random
9
+ import signal
10
+ import socket
11
+ import sys
12
+ import threading
13
+ import time
14
+ import traceback
15
+ import types
16
+
17
+ from pandacommon.pandalogger.PandaLogger import PandaLogger
18
+
19
+ from pandaserver.config import panda_config
20
+ from pandaserver.taskbuffer import OraDBProxy as DBProxy
21
+ from pandaserver.taskbuffer.DatasetSpec import DatasetSpec
22
+ from pandaserver.taskbuffer.FileSpec import FileSpec
23
+ from pandaserver.taskbuffer.JobSpec import JobSpec
24
+
25
+ # logger
26
+ _logger = PandaLogger().getLogger("ConBridge")
27
+
28
+
29
+ # exception for normal termination
30
+ class HarmlessEx(Exception):
31
+ pass
32
+
33
+
34
+ # terminate child process by itself when master has gone
35
+ class Terminator(threading.Thread):
36
+ # constructor
37
+ def __init__(self, consock):
38
+ threading.Thread.__init__(self)
39
+ self.consock = consock
40
+
41
+ # main
42
+ def run(self):
43
+ # watching control socket
44
+ try:
45
+ rcvSize = self.consock.recv(1)
46
+ except Exception:
47
+ pass
48
+ # get PID
49
+ pid = os.getpid()
50
+ _logger.debug(f"child {pid} received termination")
51
+ # kill
52
+ try:
53
+ os.kill(pid, signal.SIGTERM)
54
+ except Exception:
55
+ pass
56
+ try:
57
+ os.kill(pid, signal.SIGKILL)
58
+ except Exception:
59
+ pass
60
+
61
+
62
+ # connection bridge with timeout
63
+ class ConBridge(object):
64
+ # constructor
65
+ def __init__(self):
66
+ self.child_pid = 0
67
+ self.isMaster = False
68
+ self.mysock = None
69
+ self.consock = None
70
+ self.proxy = None
71
+ self.pid = os.getpid()
72
+ # timeout
73
+ if hasattr(panda_config, "dbtimeout"):
74
+ self.timeout = int(panda_config.dbtimeout)
75
+ else:
76
+ self.timeout = 600
77
+ # verbose
78
+ if hasattr(panda_config, "dbbridgeverbose"):
79
+ self.verbose = panda_config.dbbridgeverbose
80
+ else:
81
+ self.verbose = False
82
+
83
+ # destructor
84
+ def __del__(self):
85
+ # kill old child process
86
+ self.bridge_killChild()
87
+
88
+ # connect
89
+ def connect(
90
+ self,
91
+ dbhost=panda_config.dbhost,
92
+ dbpasswd=panda_config.dbpasswd,
93
+ dbuser=panda_config.dbuser,
94
+ dbname=panda_config.dbname,
95
+ dbtimeout=None,
96
+ reconnect=False,
97
+ ):
98
+ # kill old child process
99
+ self.bridge_killChild()
100
+ _logger.debug(f"master {self.pid} connecting")
101
+ # reset child PID and sockets
102
+ self.child_pid = 0
103
+ self.mysock = None
104
+ self.consock = None
105
+ # create socket
106
+ datpair = socket.socketpair()
107
+ conpair = socket.socketpair()
108
+ # fork
109
+ self.child_pid = os.fork()
110
+ if self.child_pid == 0:
111
+ # child
112
+ self.isMaster = False
113
+ self.pid = os.getpid()
114
+ # keep socket
115
+ self.mysock = datpair[1]
116
+ self.consock = conpair[1]
117
+ datpair[0].close()
118
+ conpair[0].close()
119
+ # connect to database
120
+ _logger.debug(f"child {self.pid} connecting to database")
121
+ self.proxy = DBProxy.DBProxy()
122
+ if not self.proxy.connect(dbhost=dbhost, dbpasswd=dbpasswd, dbtimeout=60):
123
+ _logger.error(f"child {self.pid} failed to connect")
124
+ # send error
125
+ self.bridge_sendError((RuntimeError, f"child {self.pid} connection failed"))
126
+ # exit
127
+ self.bridge_childExit()
128
+ # send OK just for ACK
129
+ _logger.debug(f"child {self.pid} connection is ready")
130
+ self.bridge_sendResponse(None)
131
+ # start terminator
132
+ Terminator(self.consock).start()
133
+ # go main loop
134
+ _logger.debug(f"child {self.pid} going into the main loop")
135
+ self.bridge_run()
136
+ # exit
137
+ self.bridge_childExit(0)
138
+ else:
139
+ # master
140
+ self.isMaster = True
141
+ # keep socket
142
+ self.mysock = datpair[0]
143
+ self.consock = conpair[0]
144
+ datpair[1].close()
145
+ conpair[1].close()
146
+ try:
147
+ # get ACK
148
+ _logger.debug(f"master {self.pid} waiting ack from child={self.child_pid}")
149
+ self.bridge_getResponse()
150
+ _logger.debug(f"master {self.pid} got ready from child={self.child_pid}")
151
+ return True
152
+ except Exception as e:
153
+ _logger.error(f"master {self.pid} failed to setup child={self.child_pid} : {str(e)} {traceback.format_exc()}")
154
+ # kill child
155
+ self.bridge_killChild()
156
+ return False
157
+
158
+ #######################
159
+ # communication methods
160
+
161
+ # send packet
162
+ def bridge_send(self, val):
163
+ try:
164
+ # set timeout
165
+ if self.isMaster:
166
+ self.mysock.settimeout(self.timeout)
167
+ # serialize
168
+ tmpStr = pickle.dumps(val, protocol=0)
169
+ # send size
170
+ sizeStr = "%50s" % len(tmpStr)
171
+ self.mysock.sendall(sizeStr.encode())
172
+ # send body
173
+ self.mysock.sendall(tmpStr)
174
+ # set timeout back
175
+ if self.isMaster:
176
+ self.mysock.settimeout(None)
177
+ except Exception as e:
178
+ if self.isMaster:
179
+ roleType = "master"
180
+ else:
181
+ roleType = "child "
182
+ _logger.error(f"{roleType} {self.pid} send error : val={str(val)[:1024]} - {str(e)} {traceback.format_exc()}")
183
+ # terminate child
184
+ if not self.isMaster:
185
+ self.bridge_childExit()
186
+ raise e
187
+
188
+ # receive packet
189
+ def bridge_recv(self):
190
+ try:
191
+ # set timeout
192
+ if self.isMaster:
193
+ self.mysock.settimeout(self.timeout)
194
+ # get size
195
+ strSize = None
196
+ headSize = 50
197
+ while strSize is None or len(strSize) < headSize:
198
+ if strSize is None:
199
+ tmpSize = headSize
200
+ else:
201
+ tmpSize = headSize - len(strSize)
202
+ tmpStr = self.mysock.recv(tmpSize)
203
+ if len(tmpStr) == 0:
204
+ if self.isMaster:
205
+ raise socket.error("empty packet")
206
+ else:
207
+ # master closed socket
208
+ raise HarmlessEx("empty packet")
209
+ if strSize is None:
210
+ strSize = tmpStr
211
+ else:
212
+ strSize += tmpStr
213
+ if strSize is None:
214
+ strSize = ""
215
+ else:
216
+ strSize = strSize.decode()
217
+ # get body
218
+ strBody = None
219
+ bodySize = int(strSize)
220
+ while strBody is None or len(strBody) < bodySize:
221
+ if strBody is None:
222
+ tmpSize = bodySize
223
+ else:
224
+ tmpSize = bodySize - len(strBody)
225
+ tmpStr = self.mysock.recv(tmpSize)
226
+ if len(tmpStr) == 0:
227
+ if self.isMaster:
228
+ raise socket.error("empty packet")
229
+ else:
230
+ # master closed socket
231
+ raise HarmlessEx("empty packet")
232
+ if strBody is None:
233
+ strBody = tmpStr
234
+ else:
235
+ strBody += tmpStr
236
+ if strBody is None:
237
+ strBody = "".encode()
238
+ # set timeout back
239
+ if self.isMaster:
240
+ self.mysock.settimeout(None)
241
+ # deserialize
242
+ retVal = pickle.loads(strBody)
243
+ return True, retVal
244
+ except Exception as e:
245
+ if self.isMaster:
246
+ roleType = "master"
247
+ else:
248
+ roleType = "child "
249
+ if isinstance(e, HarmlessEx):
250
+ _logger.debug(f"{roleType} {self.pid} recv harmless ex : {str(e)}")
251
+ else:
252
+ _logger.error(f"{roleType} {self.pid} recv error : {str(e)} {traceback.format_exc()}")
253
+ # terminate child
254
+ if not self.isMaster:
255
+ self.bridge_childExit()
256
+ raise e
257
+
258
+ #######################
259
+ # child's methods
260
+
261
+ # send error
262
+ def bridge_sendError(self, val):
263
+ # send status
264
+ self.bridge_send("NG")
265
+ # check if pickle-able
266
+ try:
267
+ pickle.dumps(val, protocol=0)
268
+ except Exception:
269
+ # use RuntimeError
270
+ val = (RuntimeError, str(val[-1]))
271
+ # send exceptions
272
+ self.bridge_send(val)
273
+
274
+ # send response
275
+ def bridge_sendResponse(self, val):
276
+ # send status
277
+ self.bridge_send("OK")
278
+ # send response
279
+ self.bridge_send(val)
280
+
281
+ # termination of child
282
+ def bridge_childExit(self, exitCode=1):
283
+ if not self.isMaster:
284
+ # close database connection
285
+ _logger.debug(f"child {self.pid} closing database connection")
286
+ if self.proxy:
287
+ self.proxy.cleanup()
288
+ # close sockets
289
+ _logger.debug(f"child {self.pid} closing sockets")
290
+ try:
291
+ self.mysock.shutdown(socket.SHUT_RDWR)
292
+ except Exception:
293
+ pass
294
+ try:
295
+ self.consock.shutdown(socket.SHUT_RDWR)
296
+ except Exception:
297
+ pass
298
+ # exit
299
+ _logger.debug(f"child {self.pid} going to exit")
300
+ os._exit(exitCode)
301
+
302
+ # child main
303
+ def bridge_run(self):
304
+ comStr = ""
305
+ while True:
306
+ try:
307
+ # get command
308
+ status, comStr = self.bridge_recv()
309
+ if not status:
310
+ raise RuntimeError("invalid command")
311
+ # get variables
312
+ status, variables = self.bridge_recv()
313
+ if not status:
314
+ raise RuntimeError("invalid variables")
315
+ except Exception:
316
+ errType, errValue = sys.exc_info()[:2]
317
+ _logger.error(f"child {self.pid} died : {errType} {errValue}")
318
+ # exit
319
+ self.bridge_childExit()
320
+ if self.verbose:
321
+ _logger.debug(f"child {self.pid} method {comStr} executing")
322
+ try:
323
+ # execute
324
+ method = getattr(self.proxy, comStr)
325
+ res = method(*variables[0], **variables[1])
326
+ # FIXME : modify response since oracledb types cannot be picked
327
+ if comStr in ["querySQLS"]:
328
+ newRes = [True] + list(res[1:])
329
+ res = newRes
330
+ if self.verbose:
331
+ _logger.debug(f"child {self.pid} method {comStr} completed")
332
+ # return
333
+ self.bridge_sendResponse((res, variables[0], variables[1]))
334
+ except Exception:
335
+ errType, errValue = sys.exc_info()[:2]
336
+ _logger.error(f"child {self.pid} method {comStr} failed : {errType} {errValue}")
337
+ if errType in [socket.error, socket.timeout]:
338
+ _logger.error(f"child {self.pid} died : {errType} {errValue}")
339
+ # exit
340
+ self.bridge_childExit()
341
+ # send error
342
+ self.bridge_sendError((errType, errValue))
343
+
344
+ #######################
345
+ # master's methods
346
+
347
+ # kill child
348
+ def bridge_killChild(self):
349
+ # kill old child process
350
+ if self.child_pid != 0:
351
+ # close sockets
352
+ _logger.debug(f"master {self.pid} closing sockets for child={self.child_pid}")
353
+ try:
354
+ if self.mysock is not None:
355
+ self.mysock.shutdown(socket.SHUT_RDWR)
356
+ except Exception:
357
+ pass
358
+ try:
359
+ if self.consock is not None:
360
+ self.consock.shutdown(socket.SHUT_RDWR)
361
+ except Exception:
362
+ pass
363
+ _logger.debug(f"master {self.pid} killing child={self.child_pid}")
364
+ # send SIGTERM
365
+ try:
366
+ os.kill(self.child_pid, signal.SIGTERM)
367
+ except Exception:
368
+ pass
369
+ time.sleep(2)
370
+ # send SIGKILL
371
+ try:
372
+ os.kill(self.child_pid, signal.SIGKILL)
373
+ except Exception:
374
+ pass
375
+ # wait for completion of child
376
+ _logger.debug(f"master {self.pid} waiting child={self.child_pid}")
377
+ try:
378
+ os.waitpid(self.child_pid, 0)
379
+ except Exception:
380
+ pass
381
+ # sleep to avoid burst reconnection
382
+ time.sleep(random.randint(5, 15))
383
+ _logger.debug(f"master {self.pid} killed child={self.child_pid}")
384
+
385
+ # get response
386
+ def bridge_getResponse(self):
387
+ # get status
388
+ status, strStatus = self.bridge_recv()
389
+ if not status:
390
+ raise RuntimeError(f"master {self.pid} got invalid status response from child={self.child_pid}")
391
+ if strStatus == "OK":
392
+ # return res
393
+ status, ret = self.bridge_recv()
394
+ if not status:
395
+ raise RuntimeError(f"master {self.pid} got invalid response body from child={self.child_pid}")
396
+ return ret
397
+ elif strStatus == "NG":
398
+ # raise error
399
+ status, ret = self.bridge_recv()
400
+ if not status:
401
+ raise RuntimeError(f"master {self.pid} got invalid response value from child={self.child_pid}")
402
+ raise ret[0](ret[1])
403
+ else:
404
+ raise RuntimeError(f"master {self.pid} got invalid response from child={self.child_pid} : {str(strStatus)}")
405
+
406
+ # method wrapper class
407
+ class bridge_masterMethod:
408
+ # constructor
409
+ def __init__(self, name, parent):
410
+ self.name = name
411
+ self.parent = parent
412
+ self.pid = os.getpid()
413
+
414
+ # copy changes in taskbuff objects to master
415
+ def copyTbObjChanges(self, oldPar, newPar):
416
+ # check they have the same type
417
+ if not isinstance(oldPar, type(newPar)):
418
+ return False
419
+ # copy some Specs since they are passed via ref's
420
+ if isinstance(oldPar, JobSpec) or isinstance(oldPar, FileSpec) or isinstance(oldPar, DatasetSpec):
421
+ if hasattr(oldPar, "__getstate__"):
422
+ tmpStat = newPar.__getstate__()
423
+ oldPar.__setstate__(tmpStat)
424
+ else:
425
+ tmpStat = newPar.values()
426
+ oldPar.pack(tmpStat)
427
+ return True
428
+ # copy Datasets
429
+ return False
430
+
431
+ # copy changes in objects to master
432
+ def copyChanges(self, oldPar, newPar):
433
+ if isinstance(oldPar, list):
434
+ # delete all elements first
435
+ while len(oldPar) > 0:
436
+ oldPar.pop()
437
+ # append
438
+ for tmpItem in newPar:
439
+ oldPar.append(tmpItem)
440
+ elif isinstance(oldPar, dict):
441
+ # replace
442
+ for tmpKey in newPar:
443
+ oldPar[tmpKey] = newPar[tmpKey]
444
+ else:
445
+ self.copyTbObjChanges(oldPar, newPar)
446
+
447
+ # method emulation
448
+ def __call__(self, *args, **keywords):
449
+ while True:
450
+ try:
451
+ # send command name
452
+ self.parent.bridge_send(self.name)
453
+ # send variables
454
+ self.parent.bridge_send((args, keywords))
455
+ # get response
456
+ retVal, newArgs, newKeywords = self.parent.bridge_getResponse()
457
+ # propagate child's changes in args to master
458
+ for idxArg, tmpArg in enumerate(args):
459
+ self.copyChanges(tmpArg, newArgs[idxArg])
460
+ # propagate child's changes in keywords to master
461
+ for tmpKey in keywords:
462
+ tmpArg = keywords[tmpKey]
463
+ self.copyChanges(tmpArg, newKeywords[tmpKey])
464
+ # return
465
+ return retVal
466
+ except Exception:
467
+ errType, errValue = sys.exc_info()[:2]
468
+ _logger.error(f"master {self.pid} method {self.name} failed : {errType} {errValue}")
469
+ # reconnect when socket has a problem
470
+ if errType not in [socket.error, socket.timeout]:
471
+ # kill old child process
472
+ self.parent.bridge_killChild()
473
+ _logger.error(f"master {self.pid} killed child")
474
+ # raise errType,errValue
475
+ # sleep
476
+ time.sleep(5)
477
+ # reconnect
478
+ try:
479
+ _logger.debug(f"master {self.pid} trying to reconnect")
480
+ is_ok = self.parent.connect()
481
+ if is_ok:
482
+ _logger.debug(f"master {self.pid} reconnect completed")
483
+ else:
484
+ _logger.debug(f"master {self.pid} reconnect failed. sleep")
485
+ time.sleep(120)
486
+ except Exception:
487
+ _logger.error(f"master {self.pid} connect failed. sleep")
488
+ time.sleep(120)
489
+
490
+ # get atter for cursor attributes
491
+ def __getattribute__(self, name):
492
+ if object.__getattribute__(self, "isMaster"):
493
+ try:
494
+ # return original attribute
495
+ return object.__getattribute__(self, name)
496
+ except Exception:
497
+ # append methods
498
+ if (
499
+ not name.startswith("_")
500
+ and hasattr(DBProxy.DBProxy, name)
501
+ and isinstance(
502
+ getattr(DBProxy.DBProxy, name),
503
+ (types.MethodType, types.FunctionType),
504
+ )
505
+ ):
506
+ # get DBProxy's method wrapper
507
+ method = ConBridge.bridge_masterMethod(name, self)
508
+ # set method
509
+ setattr(self, name, method)
510
+ # return
511
+ return method
512
+ # return original attribute for child
513
+ return object.__getattribute__(self, name)
@@ -0,0 +1,95 @@
1
+ """
2
+ pool for DBProxies
3
+
4
+ """
5
+
6
+ try:
7
+ from Queue import Queue
8
+ except ImportError:
9
+ from queue import Queue
10
+
11
+ import os
12
+ import random
13
+ import time
14
+ from contextlib import contextmanager
15
+ from threading import Lock
16
+
17
+ from pandacommon.pandalogger.PandaLogger import PandaLogger
18
+
19
+ from pandaserver.config import panda_config
20
+ from pandaserver.taskbuffer import OraDBProxy as DBProxy
21
+ from pandaserver.taskbuffer.ConBridge import ConBridge
22
+
23
+ # logger
24
+ _logger = PandaLogger().getLogger("DBProxyPool")
25
+
26
+
27
+ class DBProxyPool:
28
+ def __init__(self, dbhost, dbpasswd, nConnection, useTimeout=False, dbProxyClass=None):
29
+ # crate lock for callers
30
+ self.lock = Lock()
31
+ self.callers = []
32
+ # create Proxies
33
+ _logger.debug("init")
34
+ self.proxyList = Queue(nConnection)
35
+ self.connList = []
36
+ for i in range(nConnection):
37
+ _logger.debug(f"connect -> {i} ")
38
+ if dbProxyClass is not None:
39
+ proxy = dbProxyClass()
40
+ elif useTimeout and hasattr(panda_config, "usedbtimeout") and panda_config.usedbtimeout is True:
41
+ """
42
+ ConBridge allows having database interactions in separate processes and killing them independently when interactions are stalled.
43
+ This avoids clogged httpd processes due to stalled database accesses.
44
+ """
45
+ proxy = ConBridge()
46
+ else:
47
+ proxy = DBProxy.DBProxy()
48
+ self.connList.append(proxy)
49
+ iTry = 0
50
+ while True:
51
+ if proxy.connect(dbhost, dbpasswd, dbtimeout=60):
52
+ break
53
+ iTry += 1
54
+ _logger.debug(f"failed -> {i} : try {iTry}")
55
+ time.sleep(random.randint(60, 90))
56
+ self.proxyList.put(proxy)
57
+ time.sleep(1)
58
+ # get PID
59
+ self.pid = os.getpid()
60
+ _logger.debug("ready")
61
+
62
+ # return a free proxy. this method blocks until a proxy is available
63
+ def getProxy(self):
64
+ # time how long it took to get a proxy
65
+ start_time = time.time()
66
+
67
+ # get proxy
68
+ proxy = self.proxyList.get()
69
+ # wake up connection
70
+ proxy.wakeUp()
71
+
72
+ end_time = time.time()
73
+ elapsed_time = end_time - start_time
74
+ _logger.debug(f"Getting proxy took: {elapsed_time} seconds")
75
+
76
+ return proxy
77
+
78
+ # put back a proxy
79
+ def putProxy(self, proxy):
80
+ self.proxyList.put(proxy)
81
+
82
+ # context manager for getting DBProxy
83
+ @contextmanager
84
+ def get(self):
85
+ proxy = self.getProxy()
86
+ try:
87
+ yield proxy
88
+ finally:
89
+ self.putProxy(proxy)
90
+
91
+ # cleanup
92
+ def cleanup(self):
93
+ _logger.debug("cleanup start")
94
+ [c.cleanup() for c in self.connList]
95
+ _logger.debug("cleanup done")