rucio 32.8.6__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.

Potentially problematic release.


This version of rucio might be problematic. Click here for more details.

Files changed (481) hide show
  1. rucio/__init__.py +18 -0
  2. rucio/alembicrevision.py +16 -0
  3. rucio/api/__init__.py +14 -0
  4. rucio/api/account.py +266 -0
  5. rucio/api/account_limit.py +287 -0
  6. rucio/api/authentication.py +302 -0
  7. rucio/api/config.py +218 -0
  8. rucio/api/credential.py +60 -0
  9. rucio/api/did.py +726 -0
  10. rucio/api/dirac.py +71 -0
  11. rucio/api/exporter.py +60 -0
  12. rucio/api/heartbeat.py +62 -0
  13. rucio/api/identity.py +160 -0
  14. rucio/api/importer.py +46 -0
  15. rucio/api/lifetime_exception.py +95 -0
  16. rucio/api/lock.py +131 -0
  17. rucio/api/meta.py +85 -0
  18. rucio/api/permission.py +72 -0
  19. rucio/api/quarantined_replica.py +69 -0
  20. rucio/api/replica.py +528 -0
  21. rucio/api/request.py +220 -0
  22. rucio/api/rse.py +601 -0
  23. rucio/api/rule.py +335 -0
  24. rucio/api/scope.py +89 -0
  25. rucio/api/subscription.py +255 -0
  26. rucio/api/temporary_did.py +49 -0
  27. rucio/api/vo.py +112 -0
  28. rucio/client/__init__.py +16 -0
  29. rucio/client/accountclient.py +413 -0
  30. rucio/client/accountlimitclient.py +155 -0
  31. rucio/client/baseclient.py +929 -0
  32. rucio/client/client.py +77 -0
  33. rucio/client/configclient.py +113 -0
  34. rucio/client/credentialclient.py +54 -0
  35. rucio/client/didclient.py +691 -0
  36. rucio/client/diracclient.py +48 -0
  37. rucio/client/downloadclient.py +1674 -0
  38. rucio/client/exportclient.py +44 -0
  39. rucio/client/fileclient.py +51 -0
  40. rucio/client/importclient.py +42 -0
  41. rucio/client/lifetimeclient.py +74 -0
  42. rucio/client/lockclient.py +99 -0
  43. rucio/client/metaclient.py +137 -0
  44. rucio/client/pingclient.py +45 -0
  45. rucio/client/replicaclient.py +444 -0
  46. rucio/client/requestclient.py +109 -0
  47. rucio/client/rseclient.py +664 -0
  48. rucio/client/ruleclient.py +287 -0
  49. rucio/client/scopeclient.py +88 -0
  50. rucio/client/subscriptionclient.py +161 -0
  51. rucio/client/touchclient.py +78 -0
  52. rucio/client/uploadclient.py +871 -0
  53. rucio/common/__init__.py +14 -0
  54. rucio/common/cache.py +74 -0
  55. rucio/common/config.py +796 -0
  56. rucio/common/constants.py +92 -0
  57. rucio/common/constraints.py +18 -0
  58. rucio/common/didtype.py +187 -0
  59. rucio/common/dumper/__init__.py +306 -0
  60. rucio/common/dumper/consistency.py +449 -0
  61. rucio/common/dumper/data_models.py +325 -0
  62. rucio/common/dumper/path_parsing.py +65 -0
  63. rucio/common/exception.py +1092 -0
  64. rucio/common/extra.py +37 -0
  65. rucio/common/logging.py +404 -0
  66. rucio/common/pcache.py +1387 -0
  67. rucio/common/policy.py +84 -0
  68. rucio/common/schema/__init__.py +143 -0
  69. rucio/common/schema/atlas.py +411 -0
  70. rucio/common/schema/belleii.py +406 -0
  71. rucio/common/schema/cms.py +478 -0
  72. rucio/common/schema/domatpc.py +399 -0
  73. rucio/common/schema/escape.py +424 -0
  74. rucio/common/schema/generic.py +431 -0
  75. rucio/common/schema/generic_multi_vo.py +410 -0
  76. rucio/common/schema/icecube.py +404 -0
  77. rucio/common/schema/lsst.py +423 -0
  78. rucio/common/stomp_utils.py +160 -0
  79. rucio/common/stopwatch.py +56 -0
  80. rucio/common/test_rucio_server.py +148 -0
  81. rucio/common/types.py +158 -0
  82. rucio/common/utils.py +1946 -0
  83. rucio/core/__init__.py +14 -0
  84. rucio/core/account.py +426 -0
  85. rucio/core/account_counter.py +171 -0
  86. rucio/core/account_limit.py +357 -0
  87. rucio/core/authentication.py +563 -0
  88. rucio/core/config.py +386 -0
  89. rucio/core/credential.py +218 -0
  90. rucio/core/did.py +3102 -0
  91. rucio/core/did_meta_plugins/__init__.py +250 -0
  92. rucio/core/did_meta_plugins/did_column_meta.py +326 -0
  93. rucio/core/did_meta_plugins/did_meta_plugin_interface.py +116 -0
  94. rucio/core/did_meta_plugins/filter_engine.py +573 -0
  95. rucio/core/did_meta_plugins/json_meta.py +215 -0
  96. rucio/core/did_meta_plugins/mongo_meta.py +199 -0
  97. rucio/core/did_meta_plugins/postgres_meta.py +317 -0
  98. rucio/core/dirac.py +208 -0
  99. rucio/core/distance.py +164 -0
  100. rucio/core/exporter.py +59 -0
  101. rucio/core/heartbeat.py +263 -0
  102. rucio/core/identity.py +290 -0
  103. rucio/core/importer.py +248 -0
  104. rucio/core/lifetime_exception.py +377 -0
  105. rucio/core/lock.py +474 -0
  106. rucio/core/message.py +241 -0
  107. rucio/core/meta.py +190 -0
  108. rucio/core/monitor.py +441 -0
  109. rucio/core/naming_convention.py +154 -0
  110. rucio/core/nongrid_trace.py +124 -0
  111. rucio/core/oidc.py +1339 -0
  112. rucio/core/permission/__init__.py +107 -0
  113. rucio/core/permission/atlas.py +1333 -0
  114. rucio/core/permission/belleii.py +1076 -0
  115. rucio/core/permission/cms.py +1166 -0
  116. rucio/core/permission/escape.py +1076 -0
  117. rucio/core/permission/generic.py +1128 -0
  118. rucio/core/permission/generic_multi_vo.py +1148 -0
  119. rucio/core/quarantined_replica.py +190 -0
  120. rucio/core/replica.py +3627 -0
  121. rucio/core/replica_sorter.py +368 -0
  122. rucio/core/request.py +2241 -0
  123. rucio/core/rse.py +1835 -0
  124. rucio/core/rse_counter.py +155 -0
  125. rucio/core/rse_expression_parser.py +460 -0
  126. rucio/core/rse_selector.py +277 -0
  127. rucio/core/rule.py +3419 -0
  128. rucio/core/rule_grouping.py +1473 -0
  129. rucio/core/scope.py +152 -0
  130. rucio/core/subscription.py +316 -0
  131. rucio/core/temporary_did.py +188 -0
  132. rucio/core/topology.py +448 -0
  133. rucio/core/trace.py +361 -0
  134. rucio/core/transfer.py +1233 -0
  135. rucio/core/vo.py +151 -0
  136. rucio/core/volatile_replica.py +123 -0
  137. rucio/daemons/__init__.py +14 -0
  138. rucio/daemons/abacus/__init__.py +14 -0
  139. rucio/daemons/abacus/account.py +106 -0
  140. rucio/daemons/abacus/collection_replica.py +113 -0
  141. rucio/daemons/abacus/rse.py +107 -0
  142. rucio/daemons/atropos/__init__.py +14 -0
  143. rucio/daemons/atropos/atropos.py +243 -0
  144. rucio/daemons/auditor/__init__.py +261 -0
  145. rucio/daemons/auditor/hdfs.py +86 -0
  146. rucio/daemons/auditor/srmdumps.py +284 -0
  147. rucio/daemons/automatix/__init__.py +14 -0
  148. rucio/daemons/automatix/automatix.py +281 -0
  149. rucio/daemons/badreplicas/__init__.py +14 -0
  150. rucio/daemons/badreplicas/minos.py +311 -0
  151. rucio/daemons/badreplicas/minos_temporary_expiration.py +173 -0
  152. rucio/daemons/badreplicas/necromancer.py +200 -0
  153. rucio/daemons/bb8/__init__.py +14 -0
  154. rucio/daemons/bb8/bb8.py +356 -0
  155. rucio/daemons/bb8/common.py +762 -0
  156. rucio/daemons/bb8/nuclei_background_rebalance.py +147 -0
  157. rucio/daemons/bb8/t2_background_rebalance.py +146 -0
  158. rucio/daemons/c3po/__init__.py +14 -0
  159. rucio/daemons/c3po/algorithms/__init__.py +14 -0
  160. rucio/daemons/c3po/algorithms/simple.py +131 -0
  161. rucio/daemons/c3po/algorithms/t2_free_space.py +125 -0
  162. rucio/daemons/c3po/algorithms/t2_free_space_only_pop.py +127 -0
  163. rucio/daemons/c3po/algorithms/t2_free_space_only_pop_with_network.py +279 -0
  164. rucio/daemons/c3po/c3po.py +342 -0
  165. rucio/daemons/c3po/collectors/__init__.py +14 -0
  166. rucio/daemons/c3po/collectors/agis.py +108 -0
  167. rucio/daemons/c3po/collectors/free_space.py +62 -0
  168. rucio/daemons/c3po/collectors/jedi_did.py +48 -0
  169. rucio/daemons/c3po/collectors/mock_did.py +46 -0
  170. rucio/daemons/c3po/collectors/network_metrics.py +63 -0
  171. rucio/daemons/c3po/collectors/workload.py +110 -0
  172. rucio/daemons/c3po/utils/__init__.py +14 -0
  173. rucio/daemons/c3po/utils/dataset_cache.py +40 -0
  174. rucio/daemons/c3po/utils/expiring_dataset_cache.py +45 -0
  175. rucio/daemons/c3po/utils/expiring_list.py +63 -0
  176. rucio/daemons/c3po/utils/popularity.py +82 -0
  177. rucio/daemons/c3po/utils/timeseries.py +76 -0
  178. rucio/daemons/cache/__init__.py +14 -0
  179. rucio/daemons/cache/consumer.py +191 -0
  180. rucio/daemons/common.py +391 -0
  181. rucio/daemons/conveyor/__init__.py +14 -0
  182. rucio/daemons/conveyor/common.py +530 -0
  183. rucio/daemons/conveyor/finisher.py +492 -0
  184. rucio/daemons/conveyor/poller.py +372 -0
  185. rucio/daemons/conveyor/preparer.py +198 -0
  186. rucio/daemons/conveyor/receiver.py +206 -0
  187. rucio/daemons/conveyor/stager.py +127 -0
  188. rucio/daemons/conveyor/submitter.py +379 -0
  189. rucio/daemons/conveyor/throttler.py +468 -0
  190. rucio/daemons/follower/__init__.py +14 -0
  191. rucio/daemons/follower/follower.py +97 -0
  192. rucio/daemons/hermes/__init__.py +14 -0
  193. rucio/daemons/hermes/hermes.py +738 -0
  194. rucio/daemons/judge/__init__.py +14 -0
  195. rucio/daemons/judge/cleaner.py +149 -0
  196. rucio/daemons/judge/evaluator.py +172 -0
  197. rucio/daemons/judge/injector.py +154 -0
  198. rucio/daemons/judge/repairer.py +144 -0
  199. rucio/daemons/oauthmanager/__init__.py +14 -0
  200. rucio/daemons/oauthmanager/oauthmanager.py +199 -0
  201. rucio/daemons/reaper/__init__.py +14 -0
  202. rucio/daemons/reaper/dark_reaper.py +272 -0
  203. rucio/daemons/reaper/light_reaper.py +255 -0
  204. rucio/daemons/reaper/reaper.py +701 -0
  205. rucio/daemons/replicarecoverer/__init__.py +14 -0
  206. rucio/daemons/replicarecoverer/suspicious_replica_recoverer.py +487 -0
  207. rucio/daemons/storage/__init__.py +14 -0
  208. rucio/daemons/storage/consistency/__init__.py +14 -0
  209. rucio/daemons/storage/consistency/actions.py +753 -0
  210. rucio/daemons/tracer/__init__.py +14 -0
  211. rucio/daemons/tracer/kronos.py +513 -0
  212. rucio/daemons/transmogrifier/__init__.py +14 -0
  213. rucio/daemons/transmogrifier/transmogrifier.py +753 -0
  214. rucio/daemons/undertaker/__init__.py +14 -0
  215. rucio/daemons/undertaker/undertaker.py +137 -0
  216. rucio/db/__init__.py +14 -0
  217. rucio/db/sqla/__init__.py +38 -0
  218. rucio/db/sqla/constants.py +192 -0
  219. rucio/db/sqla/migrate_repo/__init__.py +14 -0
  220. rucio/db/sqla/migrate_repo/env.py +111 -0
  221. rucio/db/sqla/migrate_repo/versions/01eaf73ab656_add_new_rule_notification_state_progress.py +71 -0
  222. rucio/db/sqla/migrate_repo/versions/0437a40dbfd1_add_eol_at_in_rules.py +50 -0
  223. rucio/db/sqla/migrate_repo/versions/0f1adb7a599a_create_transfer_hops_table.py +61 -0
  224. rucio/db/sqla/migrate_repo/versions/102efcf145f4_added_stuck_at_column_to_rules.py +46 -0
  225. rucio/db/sqla/migrate_repo/versions/13d4f70c66a9_introduce_transfer_limits.py +93 -0
  226. rucio/db/sqla/migrate_repo/versions/140fef722e91_cleanup_distances_table.py +78 -0
  227. rucio/db/sqla/migrate_repo/versions/14ec5aeb64cf_add_request_external_host.py +46 -0
  228. rucio/db/sqla/migrate_repo/versions/156fb5b5a14_add_request_type_to_requests_idx.py +53 -0
  229. rucio/db/sqla/migrate_repo/versions/1677d4d803c8_split_rse_availability_into_multiple.py +69 -0
  230. rucio/db/sqla/migrate_repo/versions/16a0aca82e12_create_index_on_table_replicas_path.py +42 -0
  231. rucio/db/sqla/migrate_repo/versions/1803333ac20f_adding_provenance_and_phys_group.py +46 -0
  232. rucio/db/sqla/migrate_repo/versions/1a29d6a9504c_add_didtype_chck_to_requests.py +61 -0
  233. rucio/db/sqla/migrate_repo/versions/1a80adff031a_create_index_on_rules_hist_recent.py +42 -0
  234. rucio/db/sqla/migrate_repo/versions/1c45d9730ca6_increase_identity_length.py +141 -0
  235. rucio/db/sqla/migrate_repo/versions/1d1215494e95_add_quarantined_replicas_table.py +75 -0
  236. rucio/db/sqla/migrate_repo/versions/1d96f484df21_asynchronous_rules_and_rule_approval.py +75 -0
  237. rucio/db/sqla/migrate_repo/versions/1f46c5f240ac_add_bytes_column_to_bad_replicas.py +46 -0
  238. rucio/db/sqla/migrate_repo/versions/1fc15ab60d43_add_message_history_table.py +51 -0
  239. rucio/db/sqla/migrate_repo/versions/2190e703eb6e_move_rse_settings_to_rse_attributes.py +135 -0
  240. rucio/db/sqla/migrate_repo/versions/21d6b9dc9961_add_mismatch_scheme_state_to_requests.py +65 -0
  241. rucio/db/sqla/migrate_repo/versions/22cf51430c78_add_availability_column_to_table_rses.py +42 -0
  242. rucio/db/sqla/migrate_repo/versions/22d887e4ec0a_create_sources_table.py +66 -0
  243. rucio/db/sqla/migrate_repo/versions/25821a8a45a3_remove_unique_constraint_on_requests.py +54 -0
  244. rucio/db/sqla/migrate_repo/versions/25fc855625cf_added_unique_constraint_to_rules.py +43 -0
  245. rucio/db/sqla/migrate_repo/versions/269fee20dee9_add_repair_cnt_to_locks.py +46 -0
  246. rucio/db/sqla/migrate_repo/versions/271a46ea6244_add_ignore_availability_column_to_rules.py +47 -0
  247. rucio/db/sqla/migrate_repo/versions/277b5fbb41d3_switch_heartbeats_executable.py +54 -0
  248. rucio/db/sqla/migrate_repo/versions/27e3a68927fb_remove_replicas_tombstone_and_replicas_.py +39 -0
  249. rucio/db/sqla/migrate_repo/versions/2854cd9e168_added_rule_id_column.py +48 -0
  250. rucio/db/sqla/migrate_repo/versions/295289b5a800_processed_by_and__at_in_requests.py +47 -0
  251. rucio/db/sqla/migrate_repo/versions/2962ece31cf4_add_nbaccesses_column_in_the_did_table.py +48 -0
  252. rucio/db/sqla/migrate_repo/versions/2af3291ec4c_added_replicas_history_table.py +59 -0
  253. rucio/db/sqla/migrate_repo/versions/2b69addda658_add_columns_for_third_party_copy_read_.py +47 -0
  254. rucio/db/sqla/migrate_repo/versions/2b8e7bcb4783_add_config_table.py +72 -0
  255. rucio/db/sqla/migrate_repo/versions/2ba5229cb54c_add_submitted_at_to_requests_table.py +46 -0
  256. rucio/db/sqla/migrate_repo/versions/2cbee484dcf9_added_column_volume_to_rse_transfer_.py +45 -0
  257. rucio/db/sqla/migrate_repo/versions/2edee4a83846_add_source_to_requests_and_requests_.py +48 -0
  258. rucio/db/sqla/migrate_repo/versions/2eef46be23d4_change_tokens_pk.py +48 -0
  259. rucio/db/sqla/migrate_repo/versions/2f648fc909f3_index_in_rule_history_on_scope_name.py +42 -0
  260. rucio/db/sqla/migrate_repo/versions/3082b8cef557_add_naming_convention_table_and_closed_.py +69 -0
  261. rucio/db/sqla/migrate_repo/versions/30fa38b6434e_add_index_on_service_column_in_the_message_table.py +46 -0
  262. rucio/db/sqla/migrate_repo/versions/3152492b110b_added_staging_area_column.py +78 -0
  263. rucio/db/sqla/migrate_repo/versions/32c7d2783f7e_create_bad_replicas_table.py +62 -0
  264. rucio/db/sqla/migrate_repo/versions/3345511706b8_replicas_table_pk_definition_is_in_.py +74 -0
  265. rucio/db/sqla/migrate_repo/versions/35ef10d1e11b_change_index_on_table_requests.py +44 -0
  266. rucio/db/sqla/migrate_repo/versions/379a19b5332d_create_rse_limits_table.py +67 -0
  267. rucio/db/sqla/migrate_repo/versions/384b96aa0f60_created_rule_history_tables.py +134 -0
  268. rucio/db/sqla/migrate_repo/versions/3ac1660a1a72_extend_distance_table.py +58 -0
  269. rucio/db/sqla/migrate_repo/versions/3ad36e2268b0_create_collection_replicas_updates_table.py +79 -0
  270. rucio/db/sqla/migrate_repo/versions/3c9df354071b_extend_waiting_request_state.py +61 -0
  271. rucio/db/sqla/migrate_repo/versions/3d9813fab443_add_a_new_state_lost_in_badfilesstatus.py +45 -0
  272. rucio/db/sqla/migrate_repo/versions/40ad39ce3160_add_transferred_at_to_requests_table.py +46 -0
  273. rucio/db/sqla/migrate_repo/versions/4207be2fd914_add_notification_column_to_rules.py +65 -0
  274. rucio/db/sqla/migrate_repo/versions/42db2617c364_create_index_on_requests_external_id.py +42 -0
  275. rucio/db/sqla/migrate_repo/versions/436827b13f82_added_column_activity_to_table_requests.py +46 -0
  276. rucio/db/sqla/migrate_repo/versions/44278720f774_update_requests_typ_sta_upd_idx_index.py +46 -0
  277. rucio/db/sqla/migrate_repo/versions/45378a1e76a8_create_collection_replica_table.py +80 -0
  278. rucio/db/sqla/migrate_repo/versions/469d262be19_removing_created_at_index.py +43 -0
  279. rucio/db/sqla/migrate_repo/versions/4783c1f49cb4_create_distance_table.py +61 -0
  280. rucio/db/sqla/migrate_repo/versions/49a21b4d4357_create_index_on_table_tokens.py +47 -0
  281. rucio/db/sqla/migrate_repo/versions/4a2cbedda8b9_add_source_replica_expression_column_to_.py +46 -0
  282. rucio/db/sqla/migrate_repo/versions/4a7182d9578b_added_bytes_length_accessed_at_columns.py +52 -0
  283. rucio/db/sqla/migrate_repo/versions/4bab9edd01fc_create_index_on_requests_rule_id.py +42 -0
  284. rucio/db/sqla/migrate_repo/versions/4c3a4acfe006_new_attr_account_table.py +65 -0
  285. rucio/db/sqla/migrate_repo/versions/4cf0a2e127d4_adding_transient_metadata.py +46 -0
  286. rucio/db/sqla/migrate_repo/versions/50280c53117c_add_qos_class_to_rse.py +47 -0
  287. rucio/db/sqla/migrate_repo/versions/52153819589c_add_rse_id_to_replicas_table.py +45 -0
  288. rucio/db/sqla/migrate_repo/versions/52fd9f4916fa_added_activity_to_rules.py +46 -0
  289. rucio/db/sqla/migrate_repo/versions/53b479c3cb0f_fix_did_meta_table_missing_updated_at_.py +48 -0
  290. rucio/db/sqla/migrate_repo/versions/5673b4b6e843_add_wfms_metadata_to_rule_tables.py +50 -0
  291. rucio/db/sqla/migrate_repo/versions/575767d9f89_added_source_history_table.py +59 -0
  292. rucio/db/sqla/migrate_repo/versions/58bff7008037_add_started_at_to_requests.py +48 -0
  293. rucio/db/sqla/migrate_repo/versions/58c8b78301ab_rename_callback_to_message.py +108 -0
  294. rucio/db/sqla/migrate_repo/versions/5f139f77382a_added_child_rule_id_column.py +57 -0
  295. rucio/db/sqla/migrate_repo/versions/688ef1840840_adding_did_meta_table.py +51 -0
  296. rucio/db/sqla/migrate_repo/versions/6e572a9bfbf3_add_new_split_container_column_to_rules.py +50 -0
  297. rucio/db/sqla/migrate_repo/versions/70587619328_add_comment_column_for_subscriptions.py +46 -0
  298. rucio/db/sqla/migrate_repo/versions/739064d31565_remove_history_table_pks.py +42 -0
  299. rucio/db/sqla/migrate_repo/versions/7541902bf173_add_didsfollowed_and_followevents_table.py +93 -0
  300. rucio/db/sqla/migrate_repo/versions/7ec22226cdbf_new_replica_state_for_temporary_.py +73 -0
  301. rucio/db/sqla/migrate_repo/versions/810a41685bc1_added_columns_rse_transfer_limits.py +52 -0
  302. rucio/db/sqla/migrate_repo/versions/83f991c63a93_correct_rse_expression_length.py +45 -0
  303. rucio/db/sqla/migrate_repo/versions/8523998e2e76_increase_size_of_extended_attributes_.py +46 -0
  304. rucio/db/sqla/migrate_repo/versions/8ea9122275b1_adding_missing_function_based_indices.py +54 -0
  305. rucio/db/sqla/migrate_repo/versions/90f47792bb76_add_clob_payload_to_messages.py +48 -0
  306. rucio/db/sqla/migrate_repo/versions/914b8f02df38_new_table_for_lifetime_model_exceptions.py +70 -0
  307. rucio/db/sqla/migrate_repo/versions/94a5961ddbf2_add_estimator_columns.py +48 -0
  308. rucio/db/sqla/migrate_repo/versions/9a1b149a2044_add_saml_identity_type.py +95 -0
  309. rucio/db/sqla/migrate_repo/versions/9a45bc4ea66d_add_vp_table.py +55 -0
  310. rucio/db/sqla/migrate_repo/versions/9eb936a81eb1_true_is_true.py +74 -0
  311. rucio/db/sqla/migrate_repo/versions/a118956323f8_added_vo_table_and_vo_col_to_rse.py +78 -0
  312. rucio/db/sqla/migrate_repo/versions/a193a275255c_add_status_column_in_messages.py +49 -0
  313. rucio/db/sqla/migrate_repo/versions/a5f6f6e928a7_1_7_0.py +124 -0
  314. rucio/db/sqla/migrate_repo/versions/a616581ee47_added_columns_to_table_requests.py +60 -0
  315. rucio/db/sqla/migrate_repo/versions/a6eb23955c28_state_idx_non_functional.py +53 -0
  316. rucio/db/sqla/migrate_repo/versions/a74275a1ad30_added_global_quota_table.py +56 -0
  317. rucio/db/sqla/migrate_repo/versions/a93e4e47bda_heartbeats.py +67 -0
  318. rucio/db/sqla/migrate_repo/versions/ae2a56fcc89_added_comment_column_to_rules.py +50 -0
  319. rucio/db/sqla/migrate_repo/versions/b4293a99f344_added_column_identity_to_table_tokens.py +46 -0
  320. rucio/db/sqla/migrate_repo/versions/b7d287de34fd_removal_of_replicastate_source.py +92 -0
  321. rucio/db/sqla/migrate_repo/versions/b818052fa670_add_index_to_quarantined_replicas.py +42 -0
  322. rucio/db/sqla/migrate_repo/versions/b8caac94d7f0_add_comments_column_for_subscriptions_.py +46 -0
  323. rucio/db/sqla/migrate_repo/versions/b96a1c7e1cc4_new_bad_pfns_table_and_bad_replicas_.py +147 -0
  324. rucio/db/sqla/migrate_repo/versions/bb695f45c04_extend_request_state.py +78 -0
  325. rucio/db/sqla/migrate_repo/versions/bc68e9946deb_add_staging_timestamps_to_request.py +53 -0
  326. rucio/db/sqla/migrate_repo/versions/bf3baa1c1474_correct_pk_and_idx_for_history_tables.py +74 -0
  327. rucio/db/sqla/migrate_repo/versions/c0937668555f_add_qos_policy_map_table.py +56 -0
  328. rucio/db/sqla/migrate_repo/versions/c129ccdb2d5_add_lumiblocknr_to_dids.py +46 -0
  329. rucio/db/sqla/migrate_repo/versions/ccdbcd48206e_add_did_type_column_index_on_did_meta_.py +68 -0
  330. rucio/db/sqla/migrate_repo/versions/cebad904c4dd_new_payload_column_for_heartbeats.py +48 -0
  331. rucio/db/sqla/migrate_repo/versions/d1189a09c6e0_oauth2_0_and_jwt_feature_support_adding_.py +149 -0
  332. rucio/db/sqla/migrate_repo/versions/d23453595260_extend_request_state_for_preparer.py +106 -0
  333. rucio/db/sqla/migrate_repo/versions/d6dceb1de2d_added_purge_column_to_rules.py +47 -0
  334. rucio/db/sqla/migrate_repo/versions/d6e2c3b2cf26_remove_third_party_copy_column_from_rse.py +45 -0
  335. rucio/db/sqla/migrate_repo/versions/d91002c5841_new_account_limits_table.py +105 -0
  336. rucio/db/sqla/migrate_repo/versions/e138c364ebd0_extending_columns_for_filter_and_.py +52 -0
  337. rucio/db/sqla/migrate_repo/versions/e59300c8b179_support_for_archive.py +106 -0
  338. rucio/db/sqla/migrate_repo/versions/f1b14a8c2ac1_postgres_use_check_constraints.py +30 -0
  339. rucio/db/sqla/migrate_repo/versions/f41ffe206f37_oracle_global_temporary_tables.py +75 -0
  340. rucio/db/sqla/migrate_repo/versions/f85a2962b021_adding_transfertool_column_to_requests_.py +49 -0
  341. rucio/db/sqla/migrate_repo/versions/fa7a7d78b602_increase_refresh_token_size.py +45 -0
  342. rucio/db/sqla/migrate_repo/versions/fb28a95fe288_add_replicas_rse_id_tombstone_idx.py +38 -0
  343. rucio/db/sqla/migrate_repo/versions/fe1a65b176c9_set_third_party_copy_read_and_write_.py +44 -0
  344. rucio/db/sqla/migrate_repo/versions/fe8ea2fa9788_added_third_party_copy_column_to_rse_.py +46 -0
  345. rucio/db/sqla/models.py +1834 -0
  346. rucio/db/sqla/sautils.py +48 -0
  347. rucio/db/sqla/session.py +470 -0
  348. rucio/db/sqla/types.py +207 -0
  349. rucio/db/sqla/util.py +521 -0
  350. rucio/rse/__init__.py +97 -0
  351. rucio/rse/protocols/__init__.py +14 -0
  352. rucio/rse/protocols/cache.py +123 -0
  353. rucio/rse/protocols/dummy.py +112 -0
  354. rucio/rse/protocols/gfal.py +701 -0
  355. rucio/rse/protocols/globus.py +243 -0
  356. rucio/rse/protocols/gsiftp.py +93 -0
  357. rucio/rse/protocols/http_cache.py +83 -0
  358. rucio/rse/protocols/mock.py +124 -0
  359. rucio/rse/protocols/ngarc.py +210 -0
  360. rucio/rse/protocols/posix.py +251 -0
  361. rucio/rse/protocols/protocol.py +530 -0
  362. rucio/rse/protocols/rclone.py +365 -0
  363. rucio/rse/protocols/rfio.py +137 -0
  364. rucio/rse/protocols/srm.py +339 -0
  365. rucio/rse/protocols/ssh.py +414 -0
  366. rucio/rse/protocols/storm.py +207 -0
  367. rucio/rse/protocols/webdav.py +547 -0
  368. rucio/rse/protocols/xrootd.py +295 -0
  369. rucio/rse/rsemanager.py +752 -0
  370. rucio/tests/__init__.py +14 -0
  371. rucio/tests/common.py +244 -0
  372. rucio/tests/common_server.py +132 -0
  373. rucio/transfertool/__init__.py +14 -0
  374. rucio/transfertool/fts3.py +1484 -0
  375. rucio/transfertool/globus.py +200 -0
  376. rucio/transfertool/globus_library.py +182 -0
  377. rucio/transfertool/mock.py +81 -0
  378. rucio/transfertool/transfertool.py +212 -0
  379. rucio/vcsversion.py +11 -0
  380. rucio/version.py +46 -0
  381. rucio/web/__init__.py +14 -0
  382. rucio/web/rest/__init__.py +14 -0
  383. rucio/web/rest/flaskapi/__init__.py +14 -0
  384. rucio/web/rest/flaskapi/authenticated_bp.py +28 -0
  385. rucio/web/rest/flaskapi/v1/__init__.py +14 -0
  386. rucio/web/rest/flaskapi/v1/accountlimits.py +234 -0
  387. rucio/web/rest/flaskapi/v1/accounts.py +1088 -0
  388. rucio/web/rest/flaskapi/v1/archives.py +100 -0
  389. rucio/web/rest/flaskapi/v1/auth.py +1642 -0
  390. rucio/web/rest/flaskapi/v1/common.py +385 -0
  391. rucio/web/rest/flaskapi/v1/config.py +305 -0
  392. rucio/web/rest/flaskapi/v1/credentials.py +213 -0
  393. rucio/web/rest/flaskapi/v1/dids.py +2204 -0
  394. rucio/web/rest/flaskapi/v1/dirac.py +116 -0
  395. rucio/web/rest/flaskapi/v1/export.py +77 -0
  396. rucio/web/rest/flaskapi/v1/heartbeats.py +129 -0
  397. rucio/web/rest/flaskapi/v1/identities.py +263 -0
  398. rucio/web/rest/flaskapi/v1/import.py +133 -0
  399. rucio/web/rest/flaskapi/v1/lifetime_exceptions.py +315 -0
  400. rucio/web/rest/flaskapi/v1/locks.py +360 -0
  401. rucio/web/rest/flaskapi/v1/main.py +83 -0
  402. rucio/web/rest/flaskapi/v1/meta.py +226 -0
  403. rucio/web/rest/flaskapi/v1/metrics.py +37 -0
  404. rucio/web/rest/flaskapi/v1/nongrid_traces.py +97 -0
  405. rucio/web/rest/flaskapi/v1/ping.py +89 -0
  406. rucio/web/rest/flaskapi/v1/redirect.py +366 -0
  407. rucio/web/rest/flaskapi/v1/replicas.py +1866 -0
  408. rucio/web/rest/flaskapi/v1/requests.py +841 -0
  409. rucio/web/rest/flaskapi/v1/rses.py +2204 -0
  410. rucio/web/rest/flaskapi/v1/rules.py +824 -0
  411. rucio/web/rest/flaskapi/v1/scopes.py +161 -0
  412. rucio/web/rest/flaskapi/v1/subscriptions.py +646 -0
  413. rucio/web/rest/flaskapi/v1/templates/auth_crash.html +80 -0
  414. rucio/web/rest/flaskapi/v1/templates/auth_granted.html +82 -0
  415. rucio/web/rest/flaskapi/v1/tmp_dids.py +115 -0
  416. rucio/web/rest/flaskapi/v1/traces.py +100 -0
  417. rucio/web/rest/flaskapi/v1/vos.py +280 -0
  418. rucio/web/rest/main.py +19 -0
  419. rucio/web/rest/metrics.py +28 -0
  420. rucio-32.8.6.data/data/rucio/etc/alembic.ini.template +71 -0
  421. rucio-32.8.6.data/data/rucio/etc/alembic_offline.ini.template +74 -0
  422. rucio-32.8.6.data/data/rucio/etc/globus-config.yml.template +5 -0
  423. rucio-32.8.6.data/data/rucio/etc/ldap.cfg.template +30 -0
  424. rucio-32.8.6.data/data/rucio/etc/mail_templates/rule_approval_request.tmpl +38 -0
  425. rucio-32.8.6.data/data/rucio/etc/mail_templates/rule_approved_admin.tmpl +4 -0
  426. rucio-32.8.6.data/data/rucio/etc/mail_templates/rule_approved_user.tmpl +17 -0
  427. rucio-32.8.6.data/data/rucio/etc/mail_templates/rule_denied_admin.tmpl +6 -0
  428. rucio-32.8.6.data/data/rucio/etc/mail_templates/rule_denied_user.tmpl +17 -0
  429. rucio-32.8.6.data/data/rucio/etc/mail_templates/rule_ok_notification.tmpl +19 -0
  430. rucio-32.8.6.data/data/rucio/etc/rse-accounts.cfg.template +25 -0
  431. rucio-32.8.6.data/data/rucio/etc/rucio.cfg.atlas.client.template +42 -0
  432. rucio-32.8.6.data/data/rucio/etc/rucio.cfg.template +257 -0
  433. rucio-32.8.6.data/data/rucio/etc/rucio_multi_vo.cfg.template +234 -0
  434. rucio-32.8.6.data/data/rucio/requirements.txt +55 -0
  435. rucio-32.8.6.data/data/rucio/tools/bootstrap.py +34 -0
  436. rucio-32.8.6.data/data/rucio/tools/merge_rucio_configs.py +147 -0
  437. rucio-32.8.6.data/data/rucio/tools/reset_database.py +40 -0
  438. rucio-32.8.6.data/scripts/rucio +2540 -0
  439. rucio-32.8.6.data/scripts/rucio-abacus-account +75 -0
  440. rucio-32.8.6.data/scripts/rucio-abacus-collection-replica +47 -0
  441. rucio-32.8.6.data/scripts/rucio-abacus-rse +79 -0
  442. rucio-32.8.6.data/scripts/rucio-admin +2434 -0
  443. rucio-32.8.6.data/scripts/rucio-atropos +61 -0
  444. rucio-32.8.6.data/scripts/rucio-auditor +199 -0
  445. rucio-32.8.6.data/scripts/rucio-automatix +51 -0
  446. rucio-32.8.6.data/scripts/rucio-bb8 +58 -0
  447. rucio-32.8.6.data/scripts/rucio-c3po +86 -0
  448. rucio-32.8.6.data/scripts/rucio-cache-client +135 -0
  449. rucio-32.8.6.data/scripts/rucio-cache-consumer +43 -0
  450. rucio-32.8.6.data/scripts/rucio-conveyor-finisher +59 -0
  451. rucio-32.8.6.data/scripts/rucio-conveyor-poller +67 -0
  452. rucio-32.8.6.data/scripts/rucio-conveyor-preparer +38 -0
  453. rucio-32.8.6.data/scripts/rucio-conveyor-receiver +44 -0
  454. rucio-32.8.6.data/scripts/rucio-conveyor-stager +77 -0
  455. rucio-32.8.6.data/scripts/rucio-conveyor-submitter +140 -0
  456. rucio-32.8.6.data/scripts/rucio-conveyor-throttler +105 -0
  457. rucio-32.8.6.data/scripts/rucio-dark-reaper +54 -0
  458. rucio-32.8.6.data/scripts/rucio-dumper +159 -0
  459. rucio-32.8.6.data/scripts/rucio-follower +45 -0
  460. rucio-32.8.6.data/scripts/rucio-hermes +55 -0
  461. rucio-32.8.6.data/scripts/rucio-judge-cleaner +90 -0
  462. rucio-32.8.6.data/scripts/rucio-judge-evaluator +138 -0
  463. rucio-32.8.6.data/scripts/rucio-judge-injector +45 -0
  464. rucio-32.8.6.data/scripts/rucio-judge-repairer +45 -0
  465. rucio-32.8.6.data/scripts/rucio-kronos +45 -0
  466. rucio-32.8.6.data/scripts/rucio-light-reaper +53 -0
  467. rucio-32.8.6.data/scripts/rucio-minos +54 -0
  468. rucio-32.8.6.data/scripts/rucio-minos-temporary-expiration +51 -0
  469. rucio-32.8.6.data/scripts/rucio-necromancer +121 -0
  470. rucio-32.8.6.data/scripts/rucio-oauth-manager +64 -0
  471. rucio-32.8.6.data/scripts/rucio-reaper +84 -0
  472. rucio-32.8.6.data/scripts/rucio-replica-recoverer +249 -0
  473. rucio-32.8.6.data/scripts/rucio-storage-consistency-actions +75 -0
  474. rucio-32.8.6.data/scripts/rucio-transmogrifier +78 -0
  475. rucio-32.8.6.data/scripts/rucio-undertaker +77 -0
  476. rucio-32.8.6.dist-info/METADATA +83 -0
  477. rucio-32.8.6.dist-info/RECORD +481 -0
  478. rucio-32.8.6.dist-info/WHEEL +5 -0
  479. rucio-32.8.6.dist-info/licenses/AUTHORS.rst +94 -0
  480. rucio-32.8.6.dist-info/licenses/LICENSE +201 -0
  481. rucio-32.8.6.dist-info/top_level.txt +1 -0
@@ -0,0 +1,200 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright European Organization for Nuclear Research (CERN) since 2012
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ import logging
17
+
18
+ from rucio.common.utils import chunks
19
+ from rucio.db.sqla.constants import RequestState
20
+ from rucio.transfertool.transfertool import Transfertool, TransferToolBuilder, TransferStatusReport
21
+ from .globus_library import bulk_submit_xfer, submit_xfer, bulk_check_xfers
22
+
23
+
24
+ def bulk_group_transfers(transfer_paths, policy='single', group_bulk=200):
25
+ """
26
+ Group transfers in bulk based on certain criterias
27
+
28
+ :param transfer_paths: List of (potentially multihop) transfer paths to group. Each path is a list of single-hop transfers.
29
+ :param policy: Policy to use to group.
30
+ :param group_bulk: Bulk sizes.
31
+ :return: List of transfer groups
32
+ """
33
+ if policy == 'single':
34
+ group_bulk = 1
35
+
36
+ grouped_jobs = []
37
+ for chunk in chunks(transfer_paths, group_bulk):
38
+ # Globus doesn't support multihop. Get the first hop only.
39
+ transfers = [transfer_path[0] for transfer_path in chunk]
40
+
41
+ grouped_jobs.append({
42
+ 'transfers': transfers,
43
+ # Job params are not used by globus transfertool, but are needed for further common fts/globus code
44
+ 'job_params': {}
45
+ })
46
+
47
+ return grouped_jobs
48
+
49
+
50
+ class GlobusTransferStatusReport(TransferStatusReport):
51
+
52
+ supported_db_fields = [
53
+ 'state',
54
+ 'external_id',
55
+ ]
56
+
57
+ def __init__(self, request_id, external_id, globus_response):
58
+ super().__init__(request_id)
59
+
60
+ if globus_response == 'FAILED':
61
+ new_state = RequestState.FAILED
62
+ elif globus_response == 'SUCCEEDED':
63
+ new_state = RequestState.DONE
64
+ else:
65
+ new_state = RequestState.SUBMITTED
66
+
67
+ self.state = new_state
68
+ self.external_id = None
69
+ if new_state in [RequestState.FAILED, RequestState.DONE]:
70
+ self.external_id = external_id
71
+
72
+ def initialize(self, session, logger=logging.log):
73
+ pass
74
+
75
+ def get_monitor_msg_fields(self, session, logger=logging.log):
76
+ return {'protocol': 'globus'}
77
+
78
+
79
+ class GlobusTransferTool(Transfertool):
80
+ """
81
+ Globus implementation of Transfertool abstract base class
82
+ """
83
+
84
+ external_name = 'globus'
85
+ required_rse_attrs = ('globus_endpoint_id', )
86
+
87
+ def __init__(self, external_host, logger=logging.log, group_bulk=200, group_policy='single'):
88
+ """
89
+ Initializes the transfertool
90
+
91
+ :param external_host: The external host where the transfertool API is running
92
+ """
93
+ if not external_host:
94
+ external_host = 'Globus Online Transfertool'
95
+ super().__init__(external_host, logger)
96
+ self.group_bulk = group_bulk
97
+ self.group_policy = group_policy
98
+ # TODO: initialize vars from config file here
99
+
100
+ @classmethod
101
+ def submission_builder_for_path(cls, transfer_path, logger=logging.log):
102
+ hop = transfer_path[0]
103
+ if not cls.can_perform_transfer(hop.src.rse, hop.dst.rse):
104
+ logger(logging.WARNING, "Source or destination globus_endpoint_id not set. Skipping {}".format(hop))
105
+ return [], None
106
+
107
+ return [hop], TransferToolBuilder(cls, external_host='Globus Online Transfertool')
108
+
109
+ def group_into_submit_jobs(self, transfer_paths):
110
+ jobs = bulk_group_transfers(transfer_paths, policy=self.group_policy, group_bulk=self.group_bulk)
111
+ return jobs
112
+
113
+ def submit_one(self, files, timeout=None):
114
+ """
115
+ Submit transfers to globus API
116
+
117
+ :param files: List of dictionaries describing the file transfers.
118
+ :param job_params: Dictionary containing key/value pairs, for all transfers.
119
+ :param timeout: Timeout in seconds.
120
+ :returns: Globus transfer identifier.
121
+ """
122
+
123
+ source_path = files[0]['sources'][0]
124
+ self.logger(logging.INFO, 'source_path: %s' % source_path)
125
+
126
+ source_endpoint_id = files[0]['metadata']['source_globus_endpoint_id']
127
+
128
+ # TODO: use prefix from rse_protocol to properly construct destination url
129
+ # parse and assemble dest_path for Globus endpoint
130
+ dest_path = files[0]['destinations'][0]
131
+ self.logger(logging.INFO, 'dest_path: %s' % dest_path)
132
+
133
+ # TODO: rucio.common.utils.construct_url logic adds unnecessary '/other' into file path
134
+ # s = dest_path.split('/') # s.remove('other') # dest_path = '/'.join(s)
135
+
136
+ destination_endpoint_id = files[0]['metadata']['dest_globus_endpoint_id']
137
+ job_label = files[0]['metadata']['request_id']
138
+
139
+ task_id = submit_xfer(source_endpoint_id, destination_endpoint_id, source_path, dest_path, job_label, recursive=False, logger=self.logger)
140
+
141
+ return task_id
142
+
143
+ def submit(self, transfers, job_params, timeout=None):
144
+ """
145
+ Submit a bulk transfer to globus API
146
+
147
+ :param transfers: List of dictionaries describing the file transfers.
148
+ :param job_params: Not used by Globus Transfsertool
149
+ :param timeout: Timeout in seconds.
150
+ :returns: Globus transfer identifier.
151
+ """
152
+
153
+ # TODO: support passing a recursive parameter to Globus
154
+ submitjob = [
155
+ {
156
+ # Some dict elements are not needed by globus transfertool, but are accessed by further common fts/globus code
157
+ 'sources': [s[1] for s in transfer.legacy_sources],
158
+ 'destinations': [transfer.dest_url],
159
+ 'metadata': {
160
+ 'src_rse': transfer.src.rse.name,
161
+ 'dst_rse': transfer.dst.rse.name,
162
+ 'scope': str(transfer.rws.scope),
163
+ 'name': transfer.rws.name,
164
+ 'source_globus_endpoint_id': transfer.src.rse.attributes['globus_endpoint_id'],
165
+ 'dest_globus_endpoint_id': transfer.dst.rse.attributes['globus_endpoint_id'],
166
+ 'filesize': transfer.rws.byte_count,
167
+ },
168
+ }
169
+ for transfer in transfers
170
+ ]
171
+ self.logger(logging.DEBUG, '... Starting globus xfer ...')
172
+ self.logger(logging.DEBUG, 'job_files: %s' % submitjob)
173
+ task_id = bulk_submit_xfer(submitjob, recursive=False, logger=self.logger)
174
+
175
+ return task_id
176
+
177
+ def bulk_query(self, requests_by_eid, timeout=None):
178
+ """
179
+ Query the status of a bulk of transfers in globus API
180
+
181
+ :param requests_by_eid: dictionary {external_id1: {request_id1: request1, ...}, ...}
182
+ :returns: Transfer status information as a dictionary.
183
+ """
184
+
185
+ job_responses = bulk_check_xfers(requests_by_eid, logger=self.logger)
186
+
187
+ response = {}
188
+ for transfer_id, requests in requests_by_eid.items():
189
+ for request_id in requests:
190
+ response.setdefault(transfer_id, {})[request_id] = GlobusTransferStatusReport(request_id, transfer_id, job_responses[transfer_id])
191
+ return response
192
+
193
+ def bulk_update(self, resps, request_ids):
194
+ pass
195
+
196
+ def cancel(self):
197
+ pass
198
+
199
+ def update_priority(self):
200
+ pass
@@ -0,0 +1,182 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright European Organization for Nuclear Research (CERN) since 2012
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ import datetime
17
+ import logging
18
+ import os
19
+
20
+ from rucio.common.config import config_get, config_get_int, get_config_dirs
21
+ from rucio.common.extra import import_extras
22
+ from rucio.core.monitor import MetricManager
23
+
24
+ EXTRA_MODULES = import_extras(['globus_sdk'])
25
+
26
+ if EXTRA_MODULES['globus_sdk']:
27
+ from globus_sdk import NativeAppAuthClient, RefreshTokenAuthorizer, TransferClient, TransferData, DeleteData # pylint: disable=import-error
28
+ import yaml # pylint: disable=import-error
29
+
30
+ METRICS = MetricManager(module=__name__)
31
+
32
+ GLOBUS_AUTH_APP = config_get('conveyor', 'globus_auth_app', False, None)
33
+
34
+
35
+ def load_config(cfg_file='globus-config.yml', logger=logging.log):
36
+ config = None
37
+ config_dir = get_config_dirs()[0]
38
+ if os.path.isfile(os.path.join(config_dir, cfg_file)):
39
+ config = os.path.join(config_dir, cfg_file)
40
+ else:
41
+ logger(logging.ERROR, 'Could not find globus config file')
42
+ raise Exception
43
+ return yaml.safe_load(open(config).read())
44
+
45
+
46
+ def get_transfer_client(logger=logging.log):
47
+ cfg = load_config(logger=logger)
48
+ # cfg = yaml.safe_load(open("/opt/rucio/lib/rucio/transfertool/config.yml"))
49
+ client_id = cfg['globus']['apps'][GLOBUS_AUTH_APP]['client_id']
50
+ auth_client = NativeAppAuthClient(client_id)
51
+ refresh_token = cfg['globus']['apps'][GLOBUS_AUTH_APP]['refresh_token']
52
+ logger(logging.INFO, 'authorizing token...')
53
+ authorizer = RefreshTokenAuthorizer(refresh_token=refresh_token, auth_client=auth_client)
54
+ logger(logging.INFO, 'initializing TransferClient...')
55
+ tc = TransferClient(authorizer=authorizer)
56
+ return tc
57
+
58
+
59
+ def auto_activate_endpoint(tc, ep_id, logger=logging.log):
60
+ r = tc.endpoint_autoactivate(ep_id, if_expires_in=3600)
61
+ if r['code'] == 'AutoActivationFailed':
62
+ logger(logging.CRITICAL, 'Endpoint({}) Not Active! Error! Source message: {}'.format(ep_id, r['message']))
63
+ # sys.exit(1) # TODO: don't want to exit; hook into graceful exit
64
+ elif r['code'] == 'AutoActivated.CachedCredential':
65
+ logger(logging.INFO, 'Endpoint({}) autoactivated using a cached credential.'.format(ep_id))
66
+ elif r['code'] == 'AutoActivated.GlobusOnlineCredential':
67
+ logger(logging.INFO, ('Endpoint({}) autoactivated using a built-in Globus credential.').format(ep_id))
68
+ elif r['code'] == 'AlreadyActivated':
69
+ logger(logging.INFO, 'Endpoint({}) already active until at least {}'.format(ep_id, 3600))
70
+ return r['code']
71
+
72
+
73
+ def submit_xfer(source_endpoint_id, destination_endpoint_id, source_path, dest_path, job_label, recursive=False, logger=logging.log):
74
+ tc = get_transfer_client(logger=logger)
75
+ # as both endpoints are expected to be Globus Server endpoints, send auto-activate commands for both globus endpoints
76
+ auto_activate_endpoint(tc, source_endpoint_id, logger=logger)
77
+ auto_activate_endpoint(tc, destination_endpoint_id, logger=logger)
78
+
79
+ # from Globus... sync_level=checksum means that before files are transferred, Globus will compute checksums on the source and
80
+ # destination files, and only transfer files that have different checksums are transferred. verify_checksum=True means that after
81
+ # a file is transferred, Globus will compute checksums on the source and destination files to verify that the file was transferred
82
+ # correctly. If the checksums do not match, it will redo the transfer of that file.
83
+ # tdata = TransferData(tc, source_endpoint_id, destination_endpoint_id, label=job_label, sync_level="checksum", verify_checksum=True)
84
+ tdata = TransferData(tc, source_endpoint_id, destination_endpoint_id, label=job_label,
85
+ sync_level="checksum", notify_on_succeeded=False, notify_on_failed=False)
86
+ tdata.add_item(source_path, dest_path, recursive=recursive)
87
+
88
+ # logging.info('submitting transfer...')
89
+ transfer_result = tc.submit_transfer(tdata)
90
+ # logging.info("task_id =", transfer_result["task_id"])
91
+
92
+ return transfer_result["task_id"]
93
+
94
+
95
+ def bulk_submit_xfer(submitjob, recursive=False, logger=logging.log):
96
+ cfg = load_config(logger=logger)
97
+ client_id = cfg['globus']['apps'][GLOBUS_AUTH_APP]['client_id']
98
+ auth_client = NativeAppAuthClient(client_id)
99
+ refresh_token = cfg['globus']['apps'][GLOBUS_AUTH_APP]['refresh_token']
100
+ source_endpoint_id = submitjob[0].get('metadata').get('source_globus_endpoint_id')
101
+ destination_endpoint_id = submitjob[0].get('metadata').get('dest_globus_endpoint_id')
102
+ authorizer = RefreshTokenAuthorizer(refresh_token=refresh_token, auth_client=auth_client)
103
+ tc = TransferClient(authorizer=authorizer)
104
+
105
+ # make job_label for task a timestamp
106
+ now = datetime.datetime.utcnow()
107
+ job_label = now.strftime('%Y%m%d%H%M%s')
108
+
109
+ # retrieve globus_task_deadline value to enforce time window to complete transfers
110
+ # default is 2880 minutes or 48 hours
111
+ globus_task_deadline = config_get_int('conveyor', 'globus_task_deadline', False, 2880)
112
+ deadline = now + datetime.timedelta(minutes=globus_task_deadline)
113
+
114
+ # from Globus... sync_level=checksum means that before files are transferred, Globus will compute checksums on the source
115
+ # and destination files, and only transfer files that have different checksums are transferred. verify_checksum=True means
116
+ # that after a file is transferred, Globus will compute checksums on the source and destination files to verify that the
117
+ # file was transferred correctly. If the checksums do not match, it will redo the transfer of that file.
118
+ tdata = TransferData(tc, source_endpoint_id, destination_endpoint_id, label=job_label, sync_level="checksum", deadline=str(deadline))
119
+
120
+ for file in submitjob:
121
+ source_path = file.get('sources')[0]
122
+ dest_path = file.get('destinations')[0]
123
+ filesize = file['metadata']['filesize']
124
+ # TODO: support passing a recursive parameter to Globus
125
+ # md5 = file['metadata']['md5']
126
+ # tdata.add_item(source_path, dest_path, recursive=False, external_checksum=md5)
127
+ tdata.add_item(source_path, dest_path, recursive=False)
128
+ METRICS.counter('submit.filesize').inc(filesize)
129
+
130
+ # logging.info('submitting transfer...')
131
+ transfer_result = tc.submit_transfer(tdata)
132
+ logger(logging.INFO, "transfer_result: %s" % transfer_result)
133
+
134
+ return transfer_result["task_id"]
135
+
136
+
137
+ def check_xfer(task_id, logger=logging.log):
138
+ tc = get_transfer_client(logger=logger)
139
+ transfer = tc.get_task(task_id)
140
+ status = str(transfer["status"])
141
+ return status
142
+
143
+
144
+ def bulk_check_xfers(task_ids, logger=logging.log):
145
+ tc = get_transfer_client(logger=logger)
146
+
147
+ logger(logging.DEBUG, 'task_ids: %s' % task_ids)
148
+
149
+ responses = {}
150
+
151
+ for task_id in task_ids:
152
+ transfer = tc.get_task(str(task_id))
153
+ logger(logging.DEBUG, 'transfer: %s' % transfer)
154
+ status = str(transfer["status"])
155
+ if status == 'SUCCEEDED':
156
+ METRICS.counter('bytes_transferred').inc(transfer['bytes_transferred'])
157
+ METRICS.counter('effective_bytes_per_second').inc(transfer['effective_bytes_per_second'])
158
+ responses[str(task_id)] = status
159
+
160
+ logger(logging.DEBUG, 'responses: %s' % responses)
161
+
162
+ return responses
163
+
164
+
165
+ def send_delete_task(endpoint_id=None, path=None, logger=logging.log):
166
+ tc = get_transfer_client(logger=logger)
167
+ ddata = DeleteData(tc, endpoint_id, recursive=True)
168
+ ddata.add_item(path)
169
+ delete_result = tc.submit_delete(ddata)
170
+
171
+ return delete_result
172
+
173
+
174
+ def send_bulk_delete_task(endpoint_id=None, pfns=None, logger=logging.log):
175
+ tc = get_transfer_client(logger=logger)
176
+ ddata = DeleteData(tc, endpoint_id, recursive=True)
177
+ for pfn in pfns:
178
+ logger(logging.DEBUG, 'pfn: %s' % pfn)
179
+ ddata.add_item(pfn)
180
+ bulk_delete_result = tc.submit_delete(ddata)
181
+
182
+ return bulk_delete_result
@@ -0,0 +1,81 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright European Organization for Nuclear Research (CERN) since 2012
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ import itertools
17
+ import logging
18
+ import uuid
19
+ from typing import TYPE_CHECKING, Any, Optional, Sequence
20
+
21
+ from rucio.db.sqla.constants import RequestState
22
+ from rucio.transfertool.transfertool import Transfertool, TransferToolBuilder, TransferStatusReport
23
+
24
+ if TYPE_CHECKING:
25
+ from rucio.db.sqla.session import Session
26
+
27
+
28
+ class MockTransferStatusReport(TransferStatusReport):
29
+
30
+ supported_db_fields = [
31
+ 'state',
32
+ 'external_id'
33
+ ]
34
+
35
+ def __init__(self, request_id: str, external_id: str):
36
+ super().__init__(request_id)
37
+ self.state = RequestState.DONE
38
+ self.external_id = external_id
39
+
40
+ def initialize(self, session: "Session", logger=logging.log):
41
+ pass
42
+
43
+ def get_monitor_msg_fields(self, session: "Session", logger=logging.log):
44
+ return {}
45
+
46
+
47
+ class MockTransfertool(Transfertool):
48
+ """
49
+ Mock implementation of a Rucio transfertool
50
+
51
+ This is not actually used anywhere at the moment
52
+ """
53
+
54
+ external_name = 'mock'
55
+ required_rse_attrs = ()
56
+
57
+ def __init__(self, external_host: str, logger=logging.log):
58
+ super(MockTransfertool, self).__init__(external_host, logger)
59
+
60
+ @classmethod
61
+ def submission_builder_for_path(cls, transfer_path, logger=logging.log):
62
+ return transfer_path, TransferToolBuilder(cls, external_host='Mock Transfertool')
63
+
64
+ def group_into_submit_jobs(self, transfers):
65
+ return [{'transfers': list(itertools.chain.from_iterable(transfers)), 'job_params': {}}]
66
+
67
+ def submit(self, files, job_params, timeout=None):
68
+ return str(uuid.uuid1())
69
+
70
+ def bulk_query(self, requests_by_eid: dict[str, dict[str, dict[str, Any]]], timeout: Optional[float] = None):
71
+ response = {}
72
+ for transfer_id, requests in requests_by_eid.items():
73
+ for request_id in requests:
74
+ response.setdefault(transfer_id, {})[request_id] = MockTransferStatusReport(request_id, transfer_id)
75
+ return response
76
+
77
+ def cancel(self, transfer_ids: Sequence[str], timeout: Optional[float] = None):
78
+ return True
79
+
80
+ def update_priority(self, transfer_id: str, priority: int, timeout: Optional[float] = None):
81
+ return True
@@ -0,0 +1,212 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright European Organization for Nuclear Research (CERN) since 2012
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ import logging
17
+ from abc import ABCMeta, abstractmethod
18
+ from typing import TYPE_CHECKING
19
+
20
+ from rucio.core.request import get_request
21
+
22
+ if TYPE_CHECKING:
23
+ from rucio.core.rse import RseData
24
+
25
+
26
+ class TransferToolBuilder(object):
27
+ """
28
+ Builder for Transfertool objects.
29
+ Stores the parameters needed to create the Transfertool object of the given type/class.
30
+
31
+ Implements __hash__ and __eq__ to allow using it as key in dictionaries and group transfers
32
+ by common transfertool.
33
+ """
34
+ def __init__(self, transfertool_class, **kwargs):
35
+ self.transfertool_class = transfertool_class
36
+ self.fixed_kwargs = frozenset(kwargs.items())
37
+
38
+ def __str__(self):
39
+ return self.transfertool_class.__name__
40
+
41
+ def __hash__(self):
42
+ return hash(frozenset(self.__dict__.items()))
43
+
44
+ def __eq__(self, other):
45
+ return self.__class__ == other.__class__ and self.__dict__ == other.__dict__
46
+
47
+ def make_transfertool(self, **additional_kwargs):
48
+ all_kwargs = dict(self.fixed_kwargs)
49
+ all_kwargs.update(additional_kwargs)
50
+ return self.transfertool_class(**all_kwargs)
51
+
52
+
53
+ class TransferStatusReport(object, metaclass=ABCMeta):
54
+ """
55
+ Allows to compute the changes which have to be applied to the database
56
+ to reflect the current status reported by the external transfertool into
57
+ the database.
58
+ """
59
+
60
+ supported_db_fields = [
61
+ 'state',
62
+ ]
63
+
64
+ def __init__(self, request_id, request=None):
65
+ self.request_id = request_id
66
+ self.__request = request # Optional: DB request. If provided, saves us a database call to fetch it by request_id
67
+ self.__initialized = False
68
+
69
+ # Supported db fields bellow
70
+ self.state = None
71
+
72
+ @abstractmethod
73
+ def initialize(self, session, logger=logging.log):
74
+ """
75
+ Initialize all fields from self.supported_update_fields
76
+ """
77
+ pass
78
+
79
+ @abstractmethod
80
+ def get_monitor_msg_fields(self, session, logger=logging.log):
81
+ """
82
+ Return the fields which will be included in the message sent to hermes.
83
+ """
84
+ pass
85
+
86
+ def ensure_initialized(self, session, logger=logging.log):
87
+ if not self.__initialized:
88
+ self.initialize(session, logger)
89
+ self.__initialized = True
90
+
91
+ def request(self, session):
92
+ """
93
+ Fetch the request by request_id if needed.
94
+ """
95
+ if not self.__request:
96
+ self.__request = get_request(self.request_id, session=session)
97
+ return self.__request
98
+
99
+ def get_db_fields_to_update(self, session, logger=logging.log):
100
+ """
101
+ Returns the fields which have to be updated in the request
102
+ """
103
+ self.ensure_initialized(session, logger)
104
+
105
+ updates = {}
106
+ for field in self.supported_db_fields:
107
+ field_value = getattr(self, field)
108
+ if field_value:
109
+ updates[field] = field_value
110
+ return updates
111
+
112
+
113
+ class Transfertool(object, metaclass=ABCMeta):
114
+ """
115
+ Interface definition of the Rucio transfertool
116
+ """
117
+
118
+ external_name = ''
119
+ required_rse_attrs = ('globus_endpoint_id', )
120
+
121
+ def __init__(self, external_host, logger=logging.log):
122
+ """
123
+ Initializes the transfertool
124
+
125
+ :param external_host: The external host where the transfertool API is running
126
+ """
127
+
128
+ self.external_host = external_host
129
+ self.logger = logger
130
+
131
+ def __str__(self):
132
+ return self.external_host if self.external_host is not None else self.__class__.__name__
133
+
134
+ @classmethod
135
+ def can_perform_transfer(cls, source_rse: "RseData", dest_rse: "RseData"):
136
+ """
137
+ Return True if this transfertool is able to perform a transfer between the given source and destination rses
138
+ """
139
+ if (
140
+ all(source_rse.attributes.get(attribute) is not None for attribute in cls.required_rse_attrs)
141
+ and all(dest_rse.attributes.get(attribute) is not None for attribute in cls.required_rse_attrs)
142
+ ):
143
+ return True
144
+ return False
145
+
146
+ @classmethod
147
+ def submission_builder_for_path(cls, transfer_path, logger=logging.log):
148
+ """
149
+ Analyze the transfer path. If this transfertool class can submit the given transfers, return
150
+ a TransferToolBuilder instance capable to build transfertool objects configured for this
151
+ particular submission.
152
+ :param transfer_path: List of DirectTransferDefinitions
153
+ :param logger: logger instance
154
+ :return: a tuple: a sub-path starting at the first node from transfer_path, and a TransfertoolBuilder instance
155
+ capable to submit this sub-path. Returns ([], None) if submission is impossible.
156
+ """
157
+ pass
158
+
159
+ @abstractmethod
160
+ def group_into_submit_jobs(self, transfer_paths):
161
+ """
162
+ Takes an iterable over transfer paths, and create groups which can be submitted in one call to submit()
163
+
164
+ :param transfer_paths: Iterable over (potentially multihop) transfer paths.
165
+ :return: list of dicts of the form {"transfers": <transfer list>, "job_params": <data blob>}
166
+ """
167
+ pass
168
+
169
+ @abstractmethod
170
+ def submit(self, transfers, job_params, timeout=None):
171
+ """
172
+ Submit transfers to the transfertool.
173
+
174
+ :param transfers: List of dictionaries describing the file transfers.
175
+ :param job_params: Dictionary containing key/value pairs, for all transfers.
176
+ :param timeout: Timeout in seconds.
177
+ :returns: Transfertool internal identifiers.
178
+ """
179
+ pass
180
+
181
+ @abstractmethod
182
+ def bulk_query(self, requests_by_eid, timeout=None) -> dict[str, dict[str, TransferStatusReport]]:
183
+ """
184
+ Query the status of a bulk of transfers in FTS3 via JSON.
185
+
186
+ :param requests_by_eid: dictionary {external_id1: {request_id1: request1, ...}, ...} of request to be queried
187
+ :returns: Transfer status information as a dictionary.
188
+ """
189
+ pass
190
+
191
+ @abstractmethod
192
+ def cancel(self, transfer_ids, timeout=None):
193
+ """
194
+ Cancel transfers that have been submitted to the transfertool.
195
+
196
+ :param transfer_ids: Transfertool internal transfer identifiers as list of strings.
197
+ :param timeout: Timeout in seconds.
198
+ :returns: True if cancellation was successful.
199
+ """
200
+ pass
201
+
202
+ @abstractmethod
203
+ def update_priority(self, transfer_id, priority, timeout=None):
204
+ """
205
+ Update the priority of a transfer that has been submitted to the transfertool.
206
+
207
+ :param transfer_id: Transfertool internal transfer identifier as a string.
208
+ :param priority: Job priority as an integer from 1 to 5.
209
+ :param timeout: Timeout in seconds.
210
+ :returns: True if update was successful.
211
+ """
212
+ pass
rucio/vcsversion.py ADDED
@@ -0,0 +1,11 @@
1
+
2
+ '''
3
+ This file is automatically generated; Do not edit it. :)
4
+ '''
5
+ VERSION_INFO = {
6
+ 'final': True,
7
+ 'version': '32.8.6',
8
+ 'branch_nick': 'release-32-LTS',
9
+ 'revision_id': 'ce0d5e6a899547293697ca2d6b5f6d40467c9d8e',
10
+ 'revno': 12667
11
+ }