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
File without changes
@@ -0,0 +1,309 @@
1
+ import traceback
2
+
3
+ from pandacommon.pandalogger.PandaLogger import PandaLogger
4
+
5
+ from pandajedi.jedicore.MsgWrapper import MsgWrapper
6
+ from pandaserver.dataservice import DataServiceUtils
7
+ from pandaserver.taskbuffer import EventServiceUtils, JobUtils
8
+
9
+ from .TaskSetupperBase import TaskSetupperBase
10
+
11
+ logger = PandaLogger().getLogger(__name__.split(".")[-1])
12
+
13
+
14
+ # task setup for ATLAS
15
+ class AtlasTaskSetupper(TaskSetupperBase):
16
+ # constructor
17
+ def __init__(self, taskBufferIF, ddmIF):
18
+ TaskSetupperBase.__init__(self, taskBufferIF, ddmIF)
19
+ self.user_container_lifetime = taskBufferIF.getConfigValue("user_output", "OUTPUT_CONTAINER_LIFETIME", "jedi")
20
+ if not self.user_container_lifetime:
21
+ self.user_container_lifetime = 14
22
+
23
+ # main to setup task
24
+ def doSetup(self, taskSpec, datasetToRegister, pandaJobs):
25
+ # make logger
26
+ tmpLog = MsgWrapper(logger, f"< jediTaskID={taskSpec.jediTaskID} >")
27
+ tmpLog.info(f"start label={taskSpec.prodSourceLabel} taskType={taskSpec.taskType}")
28
+
29
+ # returns
30
+ retFatal = self.SC_FATAL
31
+ retOK = self.SC_SUCCEEDED
32
+
33
+ try:
34
+ # get DDM I/F
35
+ ddmIF = self.ddmIF.getInterface(taskSpec.vo)
36
+ # register datasets
37
+ if datasetToRegister != [] or taskSpec.prodSourceLabel in ["user"]:
38
+ # prod vs anal
39
+ userSetup = False
40
+ if taskSpec.prodSourceLabel in ["user"]:
41
+ userSetup = True
42
+ # collect datasetID to register datasets/containers just in case
43
+ for tmpPandaJob in pandaJobs:
44
+ if not tmpPandaJob.produceUnMerge():
45
+ for tmpFileSpec in tmpPandaJob.Files:
46
+ if tmpFileSpec.type in ["output", "log"]:
47
+ if tmpFileSpec.datasetID not in datasetToRegister:
48
+ datasetToRegister.append(tmpFileSpec.datasetID)
49
+ tmpLog.info(f"datasetToRegister={str(datasetToRegister)}")
50
+ # get site mapper
51
+ siteMapper = self.taskBufferIF.get_site_mapper()
52
+
53
+ # loop over all datasets
54
+ avDatasetList = []
55
+ cnDatasetMap = {}
56
+ for datasetID in datasetToRegister:
57
+ # get output and log datasets
58
+ tmpLog.info(f"getting datasetSpec with datasetID={datasetID}")
59
+ tmpStat, datasetSpec = self.taskBufferIF.getDatasetWithID_JEDI(taskSpec.jediTaskID, datasetID)
60
+ if not tmpStat:
61
+ tmpLog.error("failed to get output and log datasets")
62
+ return retFatal
63
+ if datasetSpec.isPseudo():
64
+ tmpLog.info("skip pseudo dataset")
65
+ continue
66
+ # DDM backend
67
+ ddmBackEnd = taskSpec.getDdmBackEnd()
68
+ tmpLog.info(f"checking {datasetSpec.datasetName}")
69
+ # secondary nucleus
70
+ nucleusSpec = siteMapper.getNucleus(taskSpec.nucleus)
71
+ secNucleusSpecBase = None
72
+ if nucleusSpec and not taskSpec.is_intermediate_task():
73
+ secondaryNucleus = nucleusSpec.get_secondary_nucleus()
74
+ if secondaryNucleus:
75
+ secNucleusSpecBase = siteMapper.getNucleus(secondaryNucleus)
76
+ # check if dataset and container are available in DDM
77
+ for targetName in [datasetSpec.datasetName, datasetSpec.containerName]:
78
+ if targetName is None:
79
+ continue
80
+ if targetName not in avDatasetList:
81
+ # set lifetime
82
+ if targetName.startswith("panda"):
83
+ if datasetSpec.type == "trn_log" and taskSpec.prodSourceLabel == "managed":
84
+ lifetime = 365
85
+ else:
86
+ lifetime = 14
87
+ else:
88
+ lifetime = None
89
+ # check dataset/container in DDM
90
+ tmpList = ddmIF.listDatasets(targetName)
91
+ if tmpList == []:
92
+ # get location
93
+ location = None
94
+ locForRule = None
95
+ if targetName == datasetSpec.datasetName:
96
+ # dataset
97
+ if datasetSpec.site in ["", None]:
98
+ if DataServiceUtils.getDistributedDestination(datasetSpec.storageToken) is not None:
99
+ locForRule = datasetSpec.destination
100
+ elif DataServiceUtils.getDestinationSE(datasetSpec.storageToken) is not None:
101
+ location = DataServiceUtils.getDestinationSE(datasetSpec.storageToken)
102
+ else:
103
+ tmpLog.info(f"site={datasetSpec.site} token={datasetSpec.storageToken}")
104
+ location = siteMapper.getDdmEndpoint(
105
+ datasetSpec.site,
106
+ datasetSpec.storageToken,
107
+ taskSpec.prodSourceLabel,
108
+ JobUtils.translate_tasktype_to_jobtype(taskSpec.taskType),
109
+ )
110
+ if locForRule is None:
111
+ locForRule = location
112
+ # set metadata
113
+ if taskSpec.prodSourceLabel in ["managed", "test"] and targetName == datasetSpec.datasetName:
114
+ metaData = {}
115
+ metaData["task_id"] = taskSpec.jediTaskID
116
+ if taskSpec.campaign not in [None, ""]:
117
+ metaData["campaign"] = taskSpec.campaign
118
+ if datasetSpec.getTransient() is not None:
119
+ metaData["transient"] = datasetSpec.getTransient()
120
+ else:
121
+ metaData = None
122
+ # use secondary nucleus only for production output
123
+ if (
124
+ secNucleusSpecBase
125
+ and taskSpec.prodSourceLabel in ["managed", "test"]
126
+ and targetName == datasetSpec.datasetName
127
+ and datasetSpec.type == "output"
128
+ ):
129
+ secNucleusSpec = secNucleusSpecBase
130
+ else:
131
+ secNucleusSpec = None
132
+ # register dataset/container
133
+ tmpLog.info(f"registering {targetName} with location={location} backend={ddmBackEnd} lifetime={lifetime} meta={str(metaData)}")
134
+ tmpStat = ddmIF.registerNewDataset(targetName, backEnd=ddmBackEnd, location=location, lifetime=lifetime, metaData=metaData)
135
+ if not tmpStat:
136
+ tmpLog.error(f"failed to register {targetName}")
137
+ return retFatal
138
+ # procedures for user
139
+ if userSetup or DataServiceUtils.getDistributedDestination(datasetSpec.storageToken) is not None or secNucleusSpec:
140
+ # register location
141
+ tmpToRegister = False
142
+ if userSetup and targetName == datasetSpec.datasetName and datasetSpec.site not in ["", None]:
143
+ if taskSpec.workingGroup:
144
+ userName = taskSpec.workingGroup
145
+ else:
146
+ userName = taskSpec.userName
147
+ grouping = None
148
+ tmpToRegister = True
149
+ elif DataServiceUtils.getDistributedDestination(datasetSpec.storageToken) is not None:
150
+ userName = None
151
+ grouping = "NONE"
152
+ tmpToRegister = True
153
+ elif secNucleusSpec:
154
+ userName = None
155
+ grouping = None
156
+ tmpToRegister = True
157
+ locForRule = siteMapper.getDdmEndpoint(
158
+ secNucleusSpec.getOnePandaSite(),
159
+ datasetSpec.storageToken,
160
+ taskSpec.prodSourceLabel,
161
+ JobUtils.translate_tasktype_to_jobtype(taskSpec.taskType),
162
+ )
163
+
164
+ if tmpToRegister:
165
+ activity = DataServiceUtils.getActivityForOut(taskSpec.prodSourceLabel)
166
+ tmpLog.info(
167
+ "registering location={} lifetime={} days activity={} grouping={} "
168
+ "owner={}".format(locForRule, lifetime, activity, grouping, userName)
169
+ )
170
+ tmpStat = ddmIF.registerDatasetLocation(
171
+ targetName, locForRule, owner=userName, lifetime=lifetime, backEnd=ddmBackEnd, activity=activity, grouping=grouping
172
+ )
173
+ if not tmpStat:
174
+ tmpLog.error(f"failed to register location {locForRule} for {targetName}")
175
+ return retFatal
176
+ # double copy
177
+ if userSetup and datasetSpec.type == "output":
178
+ if datasetSpec.destination != datasetSpec.site:
179
+ tmpLog.info(f"skip making double copy as destination={datasetSpec.destination} is not site={datasetSpec.site}")
180
+ else:
181
+ second_copy = True
182
+ try:
183
+ if taskSpec.site:
184
+ panda_site = siteMapper.getSite(taskSpec.site)
185
+ if panda_site.catchall and "skip_2nd_copy" in panda_site.catchall:
186
+ tmpLog.info(f"skip making double copy as specified in {panda_site} catchall")
187
+ second_copy = False
188
+ except Exception:
189
+ second_copy = True
190
+
191
+ if second_copy:
192
+ locForDouble = f"(type=SCRATCHDISK)\\notforextracopy=True\\{locForRule}"
193
+ tmpMsg = "registering double copy "
194
+ tmpMsg += f'location="{locForDouble}" lifetime={lifetime}days activity={activity} for dataset={targetName}'
195
+ tmpLog.info(tmpMsg)
196
+ tmpStat = ddmIF.registerDatasetLocation(
197
+ targetName,
198
+ locForDouble,
199
+ copies=1,
200
+ owner=userName,
201
+ lifetime=lifetime,
202
+ activity=activity,
203
+ grouping="NONE",
204
+ weight="freespace",
205
+ ignore_availability=False,
206
+ )
207
+ if not tmpStat:
208
+ tmpLog.error(f"failed to register double copy location {locForDouble} for {targetName}")
209
+ return retFatal
210
+ # container-level rules for user
211
+ if userSetup and datasetSpec.type == "output" and targetName == datasetSpec.containerName:
212
+ # rule to keep the outputs where they are produced
213
+ container_location = "type=SCRATCHDISK"
214
+ tmpLog.info(f"registering container-level rule for {targetName}")
215
+ tmpStat = ddmIF.registerDatasetLocation(
216
+ targetName,
217
+ container_location,
218
+ owner=userName,
219
+ lifetime=self.user_container_lifetime,
220
+ backEnd=ddmBackEnd,
221
+ activity=activity,
222
+ grouping="DATASET",
223
+ )
224
+ if not tmpStat:
225
+ tmpLog.error(f"failed to register location {container_location} for container {targetName}")
226
+ return retFatal
227
+ # rule with 2 copies and no grouping
228
+ container_location = f"(type=SCRATCHDISK)\\notforextracopy=True"
229
+ tmpLog.info(f"registering container-level 2nd copy rule for {targetName}")
230
+ tmpStat = ddmIF.registerDatasetLocation(
231
+ targetName,
232
+ container_location,
233
+ copies=1,
234
+ owner=userName,
235
+ lifetime=self.user_container_lifetime,
236
+ activity=activity,
237
+ grouping="NONE",
238
+ weight="freespace",
239
+ ignore_availability=False,
240
+ )
241
+ if not tmpStat:
242
+ tmpLog.error(f"failed to register 2nd copy location {container_location} for container {targetName}")
243
+ return retFatal
244
+ avDatasetList.append(targetName)
245
+ else:
246
+ tmpLog.info(f"{targetName} already registered")
247
+ # check if dataset is in the container
248
+ if datasetSpec.containerName is not None and datasetSpec.containerName != datasetSpec.datasetName:
249
+ # get list of constituent datasets in the container
250
+ if datasetSpec.containerName not in cnDatasetMap:
251
+ cnDatasetMap[datasetSpec.containerName] = ddmIF.listDatasetsInContainer(datasetSpec.containerName)
252
+ # add dataset
253
+ if datasetSpec.datasetName not in cnDatasetMap[datasetSpec.containerName]:
254
+ tmpLog.info(f"adding {datasetSpec.datasetName} to {datasetSpec.containerName}")
255
+ tmpStat = ddmIF.addDatasetsToContainer(datasetSpec.containerName, [datasetSpec.datasetName], backEnd=ddmBackEnd)
256
+ if not tmpStat:
257
+ tmpLog.error(f"failed to add {datasetSpec.datasetName} to {datasetSpec.containerName}")
258
+ return retFatal
259
+ cnDatasetMap[datasetSpec.containerName].append(datasetSpec.datasetName)
260
+ else:
261
+ tmpLog.info(f"{datasetSpec.datasetName} already in {datasetSpec.containerName}")
262
+ # update dataset
263
+ datasetSpec.status = "registered"
264
+ self.taskBufferIF.updateDataset_JEDI(datasetSpec, {"jediTaskID": taskSpec.jediTaskID, "datasetID": datasetID})
265
+ # register ES datasets
266
+ if taskSpec.registerEsFiles():
267
+ targetName = EventServiceUtils.getEsDatasetName(taskSpec.jediTaskID)
268
+ location = None
269
+ metaData = {}
270
+ metaData["task_id"] = taskSpec.jediTaskID
271
+ metaData["hidden"] = True
272
+ tmpLog.info(f"registering ES dataset {targetName} with location={location} meta={str(metaData)}")
273
+ tmpStat = ddmIF.registerNewDataset(targetName, location=location, metaData=metaData, resurrect=True)
274
+ if not tmpStat:
275
+ tmpLog.error(f"failed to register ES dataset {targetName}")
276
+ return retFatal
277
+ # register rule
278
+ location = "type=DATADISK"
279
+ activity = DataServiceUtils.getActivityForOut(taskSpec.prodSourceLabel)
280
+ grouping = "NONE"
281
+ tmpLog.info(f"registering location={location} activity={activity} grouping={grouping}")
282
+ tmpStat = ddmIF.registerDatasetLocation(targetName, location, activity=activity, grouping=grouping)
283
+ if not tmpStat:
284
+ tmpLog.error(f"failed to register location {location} with {activity} for {targetName}")
285
+ return retFatal
286
+ # open datasets
287
+ if taskSpec.prodSourceLabel in ["managed", "test"]:
288
+ # get the list of output/log datasets
289
+ outDatasetList = []
290
+ for tmpPandaJob in pandaJobs:
291
+ for tmpFileSpec in tmpPandaJob.Files:
292
+ if tmpFileSpec.type in ["output", "log"]:
293
+ if tmpFileSpec.destinationDBlock not in outDatasetList:
294
+ outDatasetList.append(tmpFileSpec.destinationDBlock)
295
+ # open datasets
296
+ for outDataset in outDatasetList:
297
+ tmpLog.info(f"open {outDataset}")
298
+ ddmIF.openDataset(outDataset)
299
+ # unset lifetime
300
+ ddmIF.setDatasetMetadata(outDataset, "lifetime", None)
301
+ # return
302
+ tmpLog.info("done")
303
+ return retOK
304
+ except Exception as e:
305
+ tmpLog.error(f"doSetup failed with {str(e)}")
306
+ tb = traceback.format_exc()
307
+ taskSpec.setErrDiag(tmpLog.uploadLog(taskSpec.jediTaskID))
308
+ tmpLog.error(tb)
309
+ return retFatal
@@ -0,0 +1,16 @@
1
+ from pandacommon.pandalogger.PandaLogger import PandaLogger
2
+
3
+ from .TaskSetupperBase import TaskSetupperBase
4
+
5
+ logger = PandaLogger().getLogger(__name__.split(".")[-1])
6
+
7
+
8
+ # task setup for general purpose
9
+ class GenTaskSetupper(TaskSetupperBase):
10
+ # constructor
11
+ def __init__(self, taskBufferIF, ddmIF):
12
+ TaskSetupperBase.__init__(self, taskBufferIF, ddmIF)
13
+
14
+ # main to setup task
15
+ def doSetup(self, taskSpec, datasetToRegister, pandaJobs):
16
+ return self.SC_SUCCEEDED
@@ -0,0 +1,152 @@
1
+ import traceback
2
+
3
+ from pandacommon.pandalogger.PandaLogger import PandaLogger
4
+
5
+ from pandajedi.jedicore.MsgWrapper import MsgWrapper
6
+
7
+ from .TaskSetupperBase import TaskSetupperBase
8
+
9
+ logger = PandaLogger().getLogger(__name__.split(".")[-1])
10
+
11
+
12
+ # task setup for general purpose
13
+ class SimpleTaskSetupper(TaskSetupperBase):
14
+ # constructor
15
+ def __init__(self, taskBufferIF, ddmIF):
16
+ TaskSetupperBase.__init__(self, taskBufferIF, ddmIF)
17
+
18
+ # main to setup task
19
+ def doSetup(self, taskSpec, datasetToRegister, pandaJobs):
20
+ # make logger
21
+ tmpLog = MsgWrapper(logger, f"< jediTaskID={taskSpec.jediTaskID} >")
22
+ tmpLog.info(f"start label={taskSpec.prodSourceLabel} taskType={taskSpec.taskType}")
23
+ # returns
24
+ retFatal = self.SC_FATAL
25
+ retOK = self.SC_SUCCEEDED
26
+ try:
27
+ # get DDM I/F
28
+ ddmIF = self.ddmIF.getInterface(taskSpec.vo, taskSpec.cloud)
29
+ # skip if DDM I/F is inactive
30
+ if not ddmIF:
31
+ tmpLog.info("skip due to inactive DDM I/F")
32
+ return retOK
33
+ # collect datasetID to register datasets/containers just in case
34
+ for tmpPandaJob in pandaJobs:
35
+ if not tmpPandaJob.produceUnMerge():
36
+ for tmpFileSpec in tmpPandaJob.Files:
37
+ if tmpFileSpec.type in ["output", "log"]:
38
+ if tmpFileSpec.datasetID not in datasetToRegister:
39
+ datasetToRegister.append(tmpFileSpec.datasetID)
40
+ # register datasets
41
+ if datasetToRegister:
42
+ tmpLog.info(f"datasetToRegister={str(datasetToRegister)}")
43
+ # get site mapper
44
+ siteMapper = self.taskBufferIF.get_site_mapper()
45
+
46
+ # loop over all datasets
47
+ avDatasetList = []
48
+ cnDatasetMap = {}
49
+ ddmBackEnd = "rucio"
50
+ for datasetID in datasetToRegister:
51
+ # get output and log datasets
52
+ tmpLog.info(f"getting datasetSpec with datasetID={datasetID}")
53
+ tmpStat, datasetSpec = self.taskBufferIF.getDatasetWithID_JEDI(taskSpec.jediTaskID, datasetID)
54
+ if not tmpStat:
55
+ tmpLog.error("failed to get output and log datasets")
56
+ return retFatal
57
+ if datasetSpec.isPseudo():
58
+ tmpLog.info("skip pseudo dataset")
59
+ continue
60
+
61
+ # set lifetime
62
+ key_name = f"DATASET_LIFETIME_{datasetSpec.type}"
63
+ lifetime = self.taskBufferIF.getConfigValue("task_setup", key_name, "jedi", taskSpec.cloud)
64
+ if not lifetime:
65
+ lifetime = self.taskBufferIF.getConfigValue("task_setup", key_name, "jedi", taskSpec.vo)
66
+
67
+ tmpLog.info(f"checking {datasetSpec.datasetName}")
68
+ # check if dataset and container are available in DDM
69
+ for targetName in [datasetSpec.datasetName, datasetSpec.containerName]:
70
+ if not targetName:
71
+ continue
72
+ if targetName in avDatasetList:
73
+ tmpLog.info(f"{targetName} already registered")
74
+ continue
75
+ # check dataset/container in DDM
76
+ tmpList = ddmIF.listDatasets(targetName)
77
+ if not tmpList:
78
+ # get location
79
+ location = None
80
+ locForRule = None
81
+ if targetName == datasetSpec.datasetName:
82
+ # dataset
83
+ tmpLog.info(f"dest={datasetSpec.destination}")
84
+ if datasetSpec.destination:
85
+ if siteMapper.checkSite(datasetSpec.destination):
86
+ location = siteMapper.getSite(datasetSpec.destination).ddm_output["default"]
87
+ else:
88
+ location = datasetSpec.destination
89
+ if locForRule is None:
90
+ locForRule = location
91
+ # set metadata
92
+ if targetName == datasetSpec.datasetName:
93
+ metaData = {}
94
+ metaData["task_id"] = taskSpec.jediTaskID
95
+ if taskSpec.campaign:
96
+ metaData["campaign"] = taskSpec.campaign
97
+ else:
98
+ metaData = None
99
+ # register dataset/container
100
+ tmpLog.info(f"registering {targetName} with location={location} backend={ddmBackEnd} lifetime={lifetime} meta={str(metaData)}")
101
+ tmpStat = ddmIF.registerNewDataset(targetName, backEnd=ddmBackEnd, location=location, lifetime=lifetime, metaData=metaData)
102
+ if not tmpStat:
103
+ tmpLog.error(f"failed to register {targetName}")
104
+ return retFatal
105
+ # register location
106
+ if locForRule:
107
+ """
108
+ if taskSpec.workingGroup:
109
+ userName = taskSpec.workingGroup
110
+ else:
111
+ userName = taskSpec.userName
112
+ """
113
+ userName = None
114
+ activity = None
115
+ grouping = None
116
+ tmpLog.info(
117
+ f"registering location={locForRule} lifetime={lifetime} days activity={activity} grouping={grouping} owner={userName}"
118
+ )
119
+ tmpStat = ddmIF.registerDatasetLocation(
120
+ targetName, locForRule, owner=userName, lifetime=lifetime, backEnd=ddmBackEnd, activity=activity, grouping=grouping
121
+ )
122
+ if not tmpStat:
123
+ tmpLog.error(f"failed to register location {locForRule} for {targetName}")
124
+ return retFatal
125
+ avDatasetList.append(targetName)
126
+
127
+ # check if dataset is in the container
128
+ if datasetSpec.containerName and datasetSpec.containerName != datasetSpec.datasetName:
129
+ # get list of constituent datasets in the container
130
+ if datasetSpec.containerName not in cnDatasetMap:
131
+ cnDatasetMap[datasetSpec.containerName] = ddmIF.listDatasetsInContainer(datasetSpec.containerName)
132
+ # add dataset
133
+ if datasetSpec.datasetName not in cnDatasetMap[datasetSpec.containerName]:
134
+ tmpLog.info(f"adding {datasetSpec.datasetName} to {datasetSpec.containerName}")
135
+ tmpStat = ddmIF.addDatasetsToContainer(datasetSpec.containerName, [datasetSpec.datasetName], backEnd=ddmBackEnd)
136
+ if not tmpStat:
137
+ tmpLog.error(f"failed to add {datasetSpec.datasetName} to {datasetSpec.containerName}")
138
+ return retFatal
139
+ cnDatasetMap[datasetSpec.containerName].append(datasetSpec.datasetName)
140
+ else:
141
+ tmpLog.info(f"{datasetSpec.datasetName} already in {datasetSpec.containerName}")
142
+ # update dataset
143
+ datasetSpec.status = "registered"
144
+ self.taskBufferIF.updateDataset_JEDI(datasetSpec, {"jediTaskID": taskSpec.jediTaskID, "datasetID": datasetID})
145
+ # return
146
+ tmpLog.info("done")
147
+ return retOK
148
+ except Exception as e:
149
+ errStr = f"doSetup failed with {str(e)}"
150
+ tmpLog.error(errStr + traceback.format_exc())
151
+ taskSpec.setErrDiag(errStr)
152
+ return retFatal
@@ -0,0 +1,15 @@
1
+ from pandajedi.jedicore import Interaction
2
+
3
+
4
+ # base class for task setup
5
+ class TaskSetupperBase(object):
6
+ def __init__(self, taskBufferIF, ddmIF):
7
+ self.ddmIF = ddmIF
8
+ self.taskBufferIF = taskBufferIF
9
+ self.refresh()
10
+
11
+ def refresh(self):
12
+ self.siteMapper = self.taskBufferIF.get_site_mapper()
13
+
14
+
15
+ Interaction.installSC(TaskSetupperBase)
File without changes
@@ -0,0 +1,41 @@
1
+ """
2
+ Checking DB schema version for PanDA JEDI.
3
+ If there is an issue and the pandaEmailNotification var is
4
+ defined in panda_config, it will send an email notification.
5
+ """
6
+
7
+ from packaging import version
8
+
9
+ from pandajedi.jediconfig import jedi_config
10
+ from pandajedi.jedicore import JediDBSchemaInfo
11
+ from pandajedi.jedicore.JediDBProxy import DBProxy
12
+ from pandaserver.config import panda_config
13
+ from pandaserver.srvcore.MailUtils import MailUtils
14
+
15
+ proxyS = DBProxy()
16
+ proxyS.connect(jedi_config.db.dbhost, jedi_config.db.dbpasswd, jedi_config.db.dbuser, jedi_config.db.dbname)
17
+
18
+ sql = "select major || '.' || minor || '.' || patch from ATLAS_PANDA.pandadb_version where component = 'PanDA'"
19
+
20
+ res = proxyS.querySQL(sql)
21
+ dbVersion = res[0][0]
22
+
23
+ serverDBVersion = JediDBSchemaInfo.JediDBSchemaInfo().method()
24
+
25
+ if version.parse(dbVersion) >= version.parse(serverDBVersion):
26
+ print("DB schema check: OK")
27
+ else:
28
+ msgBody = (
29
+ "There is an issue with "
30
+ + panda_config.pserveralias
31
+ + ". PanDA DB schema installed is "
32
+ + dbVersion
33
+ + " while PanDA JEDI requires version "
34
+ + serverDBVersion
35
+ + " to be installed. Please check the official docs for instructions on how to upgrade the schema."
36
+ )
37
+ print(msgBody)
38
+ if "pandaEmailNotification" in panda_config.__dict__:
39
+ MailUtils().send(
40
+ panda_config.pandaEmailNotification, "PanDA DB Version installed is not correct for JEDI running on " + panda_config.pserveralias, msgBody
41
+ )
@@ -0,0 +1,54 @@
1
+ import sys
2
+ import uuid
3
+
4
+ from userinterface import Client
5
+
6
+ inFileList = ["file1", "file2", "file3"]
7
+
8
+ logDatasetName = f"panda.jeditest.log.{uuid.uuid4()}"
9
+
10
+ taskParamMap = {}
11
+
12
+ taskParamMap["nFilesPerJob"] = 1
13
+ taskParamMap["nFiles"] = len(inFileList)
14
+ # taskParamMap['nEventsPerInputFile'] = 10000
15
+ # taskParamMap['nEventsPerJob'] = 10000
16
+ # taskParamMap['nEvents'] = 25000
17
+ taskParamMap["noInput"] = True
18
+ taskParamMap["pfnList"] = inFileList
19
+ # taskParamMap['mergeOutput'] = True
20
+ taskParamMap["taskName"] = str(uuid.uuid4())
21
+ taskParamMap["userName"] = "someone"
22
+ taskParamMap["vo"] = "wlcg"
23
+ taskParamMap["taskPriority"] = 900
24
+ # taskParamMap['reqID'] = reqIdx
25
+ taskParamMap["architecture"] = ""
26
+ taskParamMap["transUses"] = ""
27
+ taskParamMap["transHome"] = None
28
+ taskParamMap["transPath"] = "https://atlpan.web.cern.ch/atlpan/bash-c"
29
+ taskParamMap["processingType"] = "step1"
30
+ taskParamMap["prodSourceLabel"] = "test"
31
+ taskParamMap["taskType"] = "test"
32
+ taskParamMap["workingGroup"] = "lsst"
33
+ # taskParamMap['coreCount'] = 1
34
+ # taskParamMap['walltime'] = 1
35
+ taskParamMap["cloud"] = "US"
36
+ taskParamMap["site"] = "BNL_OSG_1"
37
+
38
+ """
39
+ taskParamMap['log'] = {'dataset': logDatasetName,
40
+ 'type':'template',
41
+ 'param_type':'log',
42
+ 'token':'local',
43
+ 'destination':'local',
44
+ 'value':'{0}.${{SN}}.log.tgz'.format(logDatasetName)}
45
+ """
46
+
47
+ taskParamMap["jobParameters"] = [
48
+ {
49
+ "type": "constant",
50
+ "value": 'singularity exec docker://busybox echo "hello world with ${IN/L}"',
51
+ },
52
+ ]
53
+
54
+ print(Client.insertTaskParams(taskParamMap))
@@ -0,0 +1,47 @@
1
+ import sys
2
+
3
+ from pandajedi.jedicore.JediTaskBufferInterface import JediTaskBufferInterface
4
+ from pandajedi.jediddm.DDMInterface import DDMInterface
5
+ from pandajedi.jedirefine import RefinerUtils
6
+ from pandaserver.taskbuffer.DataCarousel import DataCarouselInterface
7
+
8
+ vo = "atlas"
9
+ jediTaskID = int(sys.argv[1])
10
+
11
+ print("set tbIF")
12
+ tbIF = JediTaskBufferInterface()
13
+ tbIF.setupInterface(max_size=1)
14
+
15
+ print("set ddmIF")
16
+ ddmIF = DDMInterface()
17
+ ddmIF.setupInterface()
18
+
19
+ print("set DCIF")
20
+ data_carousel_interface = DataCarouselInterface(tbIF, ddmIF.getInterface(vo))
21
+ if data_carousel_interface is None:
22
+ # data carousel interface is undefined
23
+ errStr = f"data carousel interface is undefined for vo={vo}"
24
+ print(errStr)
25
+ sys.exit(1)
26
+
27
+ print(f"get task params of {jediTaskID}")
28
+ taskParam = tbIF.getTaskParamsWithID_JEDI(jediTaskID)
29
+ taskParamMap = RefinerUtils.decodeJSON(taskParam)
30
+
31
+ print(f"get_input_datasets_to_prestage")
32
+ prestaging_list, ret_map = data_carousel_interface.get_input_datasets_to_prestage(jediTaskID, taskParamMap)
33
+
34
+ if not prestaging_list:
35
+ # no dataset needs pre-staging; unset inputPreStaging
36
+ print("no need to prestage")
37
+ # resume the task from staging
38
+ print(f"resume task {jediTaskID}")
39
+ tbIF.sendCommandTaskPanda(jediTaskID, "Test addDataCarouselRequest. No need to prestage. Resumed from staging", True, "resume")
40
+ else:
41
+ # submit data carousel requests for dataset to pre-stage
42
+ print("to prestage, submitting data carousel requests")
43
+ tmp_ret = data_carousel_interface.submit_data_carousel_requests(jediTaskID, prestaging_list)
44
+ if tmp_ret:
45
+ print(f"submitted data carousel requests for {jediTaskID}: {tmp_ret}")
46
+ else:
47
+ print(f"failed to submit data carousel requests")