rucio 32.8.6__py3-none-any.whl → 35.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.

Potentially problematic release.


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

Files changed (502) hide show
  1. rucio/__init__.py +0 -1
  2. rucio/alembicrevision.py +1 -2
  3. rucio/client/__init__.py +0 -1
  4. rucio/client/accountclient.py +45 -25
  5. rucio/client/accountlimitclient.py +37 -9
  6. rucio/client/baseclient.py +199 -154
  7. rucio/client/client.py +2 -3
  8. rucio/client/configclient.py +19 -6
  9. rucio/client/credentialclient.py +9 -4
  10. rucio/client/didclient.py +238 -63
  11. rucio/client/diracclient.py +13 -5
  12. rucio/client/downloadclient.py +162 -51
  13. rucio/client/exportclient.py +4 -4
  14. rucio/client/fileclient.py +3 -4
  15. rucio/client/importclient.py +4 -4
  16. rucio/client/lifetimeclient.py +21 -5
  17. rucio/client/lockclient.py +18 -8
  18. rucio/client/{metaclient.py → metaconventionsclient.py} +18 -15
  19. rucio/client/pingclient.py +0 -1
  20. rucio/client/replicaclient.py +15 -5
  21. rucio/client/requestclient.py +35 -19
  22. rucio/client/rseclient.py +133 -51
  23. rucio/client/ruleclient.py +29 -22
  24. rucio/client/scopeclient.py +8 -6
  25. rucio/client/subscriptionclient.py +47 -35
  26. rucio/client/touchclient.py +8 -4
  27. rucio/client/uploadclient.py +166 -82
  28. rucio/common/__init__.py +0 -1
  29. rucio/common/cache.py +4 -4
  30. rucio/common/config.py +52 -47
  31. rucio/common/constants.py +69 -2
  32. rucio/common/constraints.py +0 -1
  33. rucio/common/didtype.py +24 -22
  34. rucio/common/dumper/__init__.py +70 -41
  35. rucio/common/dumper/consistency.py +26 -22
  36. rucio/common/dumper/data_models.py +16 -23
  37. rucio/common/dumper/path_parsing.py +0 -1
  38. rucio/common/exception.py +281 -222
  39. rucio/common/extra.py +0 -1
  40. rucio/common/logging.py +54 -38
  41. rucio/common/pcache.py +122 -101
  42. rucio/common/plugins.py +153 -0
  43. rucio/common/policy.py +4 -4
  44. rucio/common/schema/__init__.py +17 -10
  45. rucio/common/schema/atlas.py +7 -5
  46. rucio/common/schema/belleii.py +7 -5
  47. rucio/common/schema/domatpc.py +7 -5
  48. rucio/common/schema/escape.py +7 -5
  49. rucio/common/schema/generic.py +8 -6
  50. rucio/common/schema/generic_multi_vo.py +7 -5
  51. rucio/common/schema/icecube.py +7 -5
  52. rucio/common/stomp_utils.py +0 -1
  53. rucio/common/stopwatch.py +0 -1
  54. rucio/common/test_rucio_server.py +2 -2
  55. rucio/common/types.py +262 -17
  56. rucio/common/utils.py +743 -451
  57. rucio/core/__init__.py +0 -1
  58. rucio/core/account.py +99 -29
  59. rucio/core/account_counter.py +89 -24
  60. rucio/core/account_limit.py +90 -24
  61. rucio/core/authentication.py +86 -29
  62. rucio/core/config.py +108 -38
  63. rucio/core/credential.py +14 -7
  64. rucio/core/did.py +680 -782
  65. rucio/core/did_meta_plugins/__init__.py +8 -6
  66. rucio/core/did_meta_plugins/did_column_meta.py +17 -12
  67. rucio/core/did_meta_plugins/did_meta_plugin_interface.py +60 -11
  68. rucio/core/did_meta_plugins/filter_engine.py +90 -50
  69. rucio/core/did_meta_plugins/json_meta.py +41 -16
  70. rucio/core/did_meta_plugins/mongo_meta.py +25 -8
  71. rucio/core/did_meta_plugins/postgres_meta.py +3 -4
  72. rucio/core/dirac.py +46 -17
  73. rucio/core/distance.py +66 -43
  74. rucio/core/exporter.py +5 -5
  75. rucio/core/heartbeat.py +181 -81
  76. rucio/core/identity.py +22 -12
  77. rucio/core/importer.py +23 -12
  78. rucio/core/lifetime_exception.py +32 -32
  79. rucio/core/lock.py +244 -142
  80. rucio/core/message.py +79 -38
  81. rucio/core/{meta.py → meta_conventions.py} +57 -44
  82. rucio/core/monitor.py +19 -13
  83. rucio/core/naming_convention.py +68 -27
  84. rucio/core/nongrid_trace.py +17 -5
  85. rucio/core/oidc.py +151 -29
  86. rucio/core/permission/__init__.py +18 -6
  87. rucio/core/permission/atlas.py +50 -35
  88. rucio/core/permission/belleii.py +6 -5
  89. rucio/core/permission/escape.py +8 -6
  90. rucio/core/permission/generic.py +82 -80
  91. rucio/core/permission/generic_multi_vo.py +9 -7
  92. rucio/core/quarantined_replica.py +91 -58
  93. rucio/core/replica.py +1303 -772
  94. rucio/core/replica_sorter.py +10 -12
  95. rucio/core/request.py +1133 -285
  96. rucio/core/rse.py +142 -102
  97. rucio/core/rse_counter.py +49 -18
  98. rucio/core/rse_expression_parser.py +6 -7
  99. rucio/core/rse_selector.py +41 -16
  100. rucio/core/rule.py +1538 -474
  101. rucio/core/rule_grouping.py +213 -68
  102. rucio/core/scope.py +50 -22
  103. rucio/core/subscription.py +92 -44
  104. rucio/core/topology.py +66 -24
  105. rucio/core/trace.py +42 -28
  106. rucio/core/transfer.py +543 -259
  107. rucio/core/vo.py +36 -18
  108. rucio/core/volatile_replica.py +59 -32
  109. rucio/daemons/__init__.py +0 -1
  110. rucio/daemons/abacus/__init__.py +0 -1
  111. rucio/daemons/abacus/account.py +29 -19
  112. rucio/daemons/abacus/collection_replica.py +21 -10
  113. rucio/daemons/abacus/rse.py +22 -12
  114. rucio/daemons/atropos/__init__.py +0 -1
  115. rucio/daemons/atropos/atropos.py +1 -2
  116. rucio/daemons/auditor/__init__.py +56 -28
  117. rucio/daemons/auditor/hdfs.py +17 -6
  118. rucio/daemons/auditor/srmdumps.py +116 -45
  119. rucio/daemons/automatix/__init__.py +0 -1
  120. rucio/daemons/automatix/automatix.py +30 -18
  121. rucio/daemons/badreplicas/__init__.py +0 -1
  122. rucio/daemons/badreplicas/minos.py +29 -18
  123. rucio/daemons/badreplicas/minos_temporary_expiration.py +5 -7
  124. rucio/daemons/badreplicas/necromancer.py +9 -13
  125. rucio/daemons/bb8/__init__.py +0 -1
  126. rucio/daemons/bb8/bb8.py +10 -13
  127. rucio/daemons/bb8/common.py +151 -154
  128. rucio/daemons/bb8/nuclei_background_rebalance.py +15 -9
  129. rucio/daemons/bb8/t2_background_rebalance.py +15 -8
  130. rucio/daemons/c3po/__init__.py +0 -1
  131. rucio/daemons/c3po/algorithms/__init__.py +0 -1
  132. rucio/daemons/c3po/algorithms/simple.py +8 -5
  133. rucio/daemons/c3po/algorithms/t2_free_space.py +10 -7
  134. rucio/daemons/c3po/algorithms/t2_free_space_only_pop.py +10 -7
  135. rucio/daemons/c3po/algorithms/t2_free_space_only_pop_with_network.py +30 -15
  136. rucio/daemons/c3po/c3po.py +81 -52
  137. rucio/daemons/c3po/collectors/__init__.py +0 -1
  138. rucio/daemons/c3po/collectors/agis.py +17 -17
  139. rucio/daemons/c3po/collectors/free_space.py +32 -13
  140. rucio/daemons/c3po/collectors/jedi_did.py +14 -5
  141. rucio/daemons/c3po/collectors/mock_did.py +11 -6
  142. rucio/daemons/c3po/collectors/network_metrics.py +12 -4
  143. rucio/daemons/c3po/collectors/workload.py +21 -19
  144. rucio/daemons/c3po/utils/__init__.py +0 -1
  145. rucio/daemons/c3po/utils/dataset_cache.py +15 -5
  146. rucio/daemons/c3po/utils/expiring_dataset_cache.py +16 -5
  147. rucio/daemons/c3po/utils/expiring_list.py +6 -7
  148. rucio/daemons/c3po/utils/popularity.py +5 -2
  149. rucio/daemons/c3po/utils/timeseries.py +25 -12
  150. rucio/daemons/cache/__init__.py +0 -1
  151. rucio/daemons/cache/consumer.py +21 -15
  152. rucio/daemons/common.py +42 -18
  153. rucio/daemons/conveyor/__init__.py +0 -1
  154. rucio/daemons/conveyor/common.py +69 -37
  155. rucio/daemons/conveyor/finisher.py +83 -46
  156. rucio/daemons/conveyor/poller.py +101 -69
  157. rucio/daemons/conveyor/preparer.py +35 -28
  158. rucio/daemons/conveyor/receiver.py +64 -21
  159. rucio/daemons/conveyor/stager.py +33 -28
  160. rucio/daemons/conveyor/submitter.py +71 -47
  161. rucio/daemons/conveyor/throttler.py +99 -35
  162. rucio/daemons/follower/__init__.py +0 -1
  163. rucio/daemons/follower/follower.py +12 -8
  164. rucio/daemons/hermes/__init__.py +0 -1
  165. rucio/daemons/hermes/hermes.py +57 -21
  166. rucio/daemons/judge/__init__.py +0 -1
  167. rucio/daemons/judge/cleaner.py +27 -17
  168. rucio/daemons/judge/evaluator.py +31 -18
  169. rucio/daemons/judge/injector.py +31 -23
  170. rucio/daemons/judge/repairer.py +28 -18
  171. rucio/daemons/oauthmanager/__init__.py +0 -1
  172. rucio/daemons/oauthmanager/oauthmanager.py +7 -8
  173. rucio/daemons/reaper/__init__.py +0 -1
  174. rucio/daemons/reaper/dark_reaper.py +15 -9
  175. rucio/daemons/reaper/reaper.py +109 -67
  176. rucio/daemons/replicarecoverer/__init__.py +0 -1
  177. rucio/daemons/replicarecoverer/suspicious_replica_recoverer.py +255 -116
  178. rucio/{api → daemons/rsedecommissioner}/__init__.py +0 -1
  179. rucio/daemons/rsedecommissioner/config.py +81 -0
  180. rucio/daemons/rsedecommissioner/profiles/__init__.py +24 -0
  181. rucio/daemons/rsedecommissioner/profiles/atlas.py +60 -0
  182. rucio/daemons/rsedecommissioner/profiles/generic.py +451 -0
  183. rucio/daemons/rsedecommissioner/profiles/types.py +92 -0
  184. rucio/daemons/rsedecommissioner/rse_decommissioner.py +280 -0
  185. rucio/daemons/storage/__init__.py +0 -1
  186. rucio/daemons/storage/consistency/__init__.py +0 -1
  187. rucio/daemons/storage/consistency/actions.py +152 -59
  188. rucio/daemons/tracer/__init__.py +0 -1
  189. rucio/daemons/tracer/kronos.py +47 -24
  190. rucio/daemons/transmogrifier/__init__.py +0 -1
  191. rucio/daemons/transmogrifier/transmogrifier.py +35 -26
  192. rucio/daemons/undertaker/__init__.py +0 -1
  193. rucio/daemons/undertaker/undertaker.py +10 -10
  194. rucio/db/__init__.py +0 -1
  195. rucio/db/sqla/__init__.py +16 -2
  196. rucio/db/sqla/constants.py +10 -1
  197. rucio/db/sqla/migrate_repo/__init__.py +0 -1
  198. rucio/db/sqla/migrate_repo/env.py +0 -1
  199. rucio/db/sqla/migrate_repo/versions/01eaf73ab656_add_new_rule_notification_state_progress.py +0 -1
  200. rucio/db/sqla/migrate_repo/versions/0437a40dbfd1_add_eol_at_in_rules.py +0 -3
  201. rucio/db/sqla/migrate_repo/versions/0f1adb7a599a_create_transfer_hops_table.py +1 -3
  202. rucio/db/sqla/migrate_repo/versions/102efcf145f4_added_stuck_at_column_to_rules.py +0 -3
  203. rucio/db/sqla/migrate_repo/versions/13d4f70c66a9_introduce_transfer_limits.py +1 -3
  204. rucio/db/sqla/migrate_repo/versions/140fef722e91_cleanup_distances_table.py +1 -3
  205. rucio/db/sqla/migrate_repo/versions/14ec5aeb64cf_add_request_external_host.py +0 -3
  206. rucio/db/sqla/migrate_repo/versions/156fb5b5a14_add_request_type_to_requests_idx.py +1 -4
  207. rucio/db/sqla/migrate_repo/versions/1677d4d803c8_split_rse_availability_into_multiple.py +0 -1
  208. rucio/db/sqla/migrate_repo/versions/16a0aca82e12_create_index_on_table_replicas_path.py +0 -2
  209. rucio/db/sqla/migrate_repo/versions/1803333ac20f_adding_provenance_and_phys_group.py +0 -1
  210. rucio/db/sqla/migrate_repo/versions/1a29d6a9504c_add_didtype_chck_to_requests.py +0 -1
  211. rucio/db/sqla/migrate_repo/versions/1a80adff031a_create_index_on_rules_hist_recent.py +0 -2
  212. rucio/db/sqla/migrate_repo/versions/1c45d9730ca6_increase_identity_length.py +0 -1
  213. rucio/db/sqla/migrate_repo/versions/1d1215494e95_add_quarantined_replicas_table.py +1 -3
  214. rucio/db/sqla/migrate_repo/versions/1d96f484df21_asynchronous_rules_and_rule_approval.py +0 -1
  215. rucio/db/sqla/migrate_repo/versions/1f46c5f240ac_add_bytes_column_to_bad_replicas.py +0 -3
  216. rucio/db/sqla/migrate_repo/versions/1fc15ab60d43_add_message_history_table.py +0 -1
  217. rucio/db/sqla/migrate_repo/versions/2190e703eb6e_move_rse_settings_to_rse_attributes.py +1 -2
  218. rucio/db/sqla/migrate_repo/versions/21d6b9dc9961_add_mismatch_scheme_state_to_requests.py +0 -1
  219. rucio/db/sqla/migrate_repo/versions/22cf51430c78_add_availability_column_to_table_rses.py +0 -3
  220. rucio/db/sqla/migrate_repo/versions/22d887e4ec0a_create_sources_table.py +1 -3
  221. rucio/db/sqla/migrate_repo/versions/25821a8a45a3_remove_unique_constraint_on_requests.py +1 -4
  222. rucio/db/sqla/migrate_repo/versions/25fc855625cf_added_unique_constraint_to_rules.py +0 -2
  223. rucio/db/sqla/migrate_repo/versions/269fee20dee9_add_repair_cnt_to_locks.py +0 -3
  224. rucio/db/sqla/migrate_repo/versions/271a46ea6244_add_ignore_availability_column_to_rules.py +0 -3
  225. rucio/db/sqla/migrate_repo/versions/277b5fbb41d3_switch_heartbeats_executable.py +1 -2
  226. rucio/db/sqla/migrate_repo/versions/27e3a68927fb_remove_replicas_tombstone_and_replicas_.py +0 -1
  227. rucio/db/sqla/migrate_repo/versions/2854cd9e168_added_rule_id_column.py +0 -1
  228. rucio/db/sqla/migrate_repo/versions/295289b5a800_processed_by_and__at_in_requests.py +0 -2
  229. rucio/db/sqla/migrate_repo/versions/2962ece31cf4_add_nbaccesses_column_in_the_did_table.py +0 -3
  230. rucio/db/sqla/migrate_repo/versions/2af3291ec4c_added_replicas_history_table.py +1 -3
  231. rucio/db/sqla/migrate_repo/versions/2b69addda658_add_columns_for_third_party_copy_read_.py +0 -2
  232. rucio/db/sqla/migrate_repo/versions/2b8e7bcb4783_add_config_table.py +1 -4
  233. rucio/db/sqla/migrate_repo/versions/2ba5229cb54c_add_submitted_at_to_requests_table.py +0 -3
  234. rucio/db/sqla/migrate_repo/versions/2cbee484dcf9_added_column_volume_to_rse_transfer_.py +1 -4
  235. rucio/db/sqla/migrate_repo/versions/2edee4a83846_add_source_to_requests_and_requests_.py +0 -1
  236. rucio/db/sqla/migrate_repo/versions/2eef46be23d4_change_tokens_pk.py +1 -3
  237. rucio/db/sqla/migrate_repo/versions/2f648fc909f3_index_in_rule_history_on_scope_name.py +0 -2
  238. rucio/db/sqla/migrate_repo/versions/3082b8cef557_add_naming_convention_table_and_closed_.py +1 -3
  239. rucio/db/sqla/migrate_repo/versions/30fa38b6434e_add_index_on_service_column_in_the_message_table.py +1 -3
  240. rucio/db/sqla/migrate_repo/versions/3152492b110b_added_staging_area_column.py +1 -2
  241. rucio/db/sqla/migrate_repo/versions/32c7d2783f7e_create_bad_replicas_table.py +1 -3
  242. rucio/db/sqla/migrate_repo/versions/3345511706b8_replicas_table_pk_definition_is_in_.py +1 -3
  243. rucio/db/sqla/migrate_repo/versions/35ef10d1e11b_change_index_on_table_requests.py +0 -2
  244. rucio/db/sqla/migrate_repo/versions/379a19b5332d_create_rse_limits_table.py +1 -3
  245. rucio/db/sqla/migrate_repo/versions/384b96aa0f60_created_rule_history_tables.py +2 -3
  246. rucio/db/sqla/migrate_repo/versions/3ac1660a1a72_extend_distance_table.py +0 -3
  247. rucio/db/sqla/migrate_repo/versions/3ad36e2268b0_create_collection_replicas_updates_table.py +1 -4
  248. rucio/db/sqla/migrate_repo/versions/3c9df354071b_extend_waiting_request_state.py +0 -1
  249. rucio/db/sqla/migrate_repo/versions/3d9813fab443_add_a_new_state_lost_in_badfilesstatus.py +0 -1
  250. rucio/db/sqla/migrate_repo/versions/40ad39ce3160_add_transferred_at_to_requests_table.py +0 -3
  251. rucio/db/sqla/migrate_repo/versions/4207be2fd914_add_notification_column_to_rules.py +0 -1
  252. rucio/db/sqla/migrate_repo/versions/42db2617c364_create_index_on_requests_external_id.py +0 -2
  253. rucio/db/sqla/migrate_repo/versions/436827b13f82_added_column_activity_to_table_requests.py +0 -3
  254. rucio/db/sqla/migrate_repo/versions/44278720f774_update_requests_typ_sta_upd_idx_index.py +0 -2
  255. rucio/db/sqla/migrate_repo/versions/45378a1e76a8_create_collection_replica_table.py +2 -4
  256. rucio/db/sqla/migrate_repo/versions/469d262be19_removing_created_at_index.py +0 -2
  257. rucio/db/sqla/migrate_repo/versions/4783c1f49cb4_create_distance_table.py +1 -3
  258. rucio/db/sqla/migrate_repo/versions/49a21b4d4357_create_index_on_table_tokens.py +1 -4
  259. rucio/db/sqla/migrate_repo/versions/4a2cbedda8b9_add_source_replica_expression_column_to_.py +0 -3
  260. rucio/db/sqla/migrate_repo/versions/4a7182d9578b_added_bytes_length_accessed_at_columns.py +0 -3
  261. rucio/db/sqla/migrate_repo/versions/4bab9edd01fc_create_index_on_requests_rule_id.py +0 -2
  262. rucio/db/sqla/migrate_repo/versions/4c3a4acfe006_new_attr_account_table.py +1 -3
  263. rucio/db/sqla/migrate_repo/versions/4cf0a2e127d4_adding_transient_metadata.py +0 -3
  264. rucio/db/sqla/migrate_repo/versions/4df2c5ddabc0_remove_temporary_dids.py +55 -0
  265. rucio/db/sqla/migrate_repo/versions/50280c53117c_add_qos_class_to_rse.py +0 -2
  266. rucio/db/sqla/migrate_repo/versions/52153819589c_add_rse_id_to_replicas_table.py +0 -2
  267. rucio/db/sqla/migrate_repo/versions/52fd9f4916fa_added_activity_to_rules.py +0 -3
  268. rucio/db/sqla/migrate_repo/versions/53b479c3cb0f_fix_did_meta_table_missing_updated_at_.py +0 -3
  269. rucio/db/sqla/migrate_repo/versions/5673b4b6e843_add_wfms_metadata_to_rule_tables.py +0 -3
  270. rucio/db/sqla/migrate_repo/versions/575767d9f89_added_source_history_table.py +1 -2
  271. rucio/db/sqla/migrate_repo/versions/58bff7008037_add_started_at_to_requests.py +0 -3
  272. rucio/db/sqla/migrate_repo/versions/58c8b78301ab_rename_callback_to_message.py +1 -3
  273. rucio/db/sqla/migrate_repo/versions/5f139f77382a_added_child_rule_id_column.py +1 -3
  274. rucio/db/sqla/migrate_repo/versions/688ef1840840_adding_did_meta_table.py +1 -2
  275. rucio/db/sqla/migrate_repo/versions/6e572a9bfbf3_add_new_split_container_column_to_rules.py +0 -3
  276. rucio/db/sqla/migrate_repo/versions/70587619328_add_comment_column_for_subscriptions.py +0 -3
  277. rucio/db/sqla/migrate_repo/versions/739064d31565_remove_history_table_pks.py +1 -2
  278. rucio/db/sqla/migrate_repo/versions/7541902bf173_add_didsfollowed_and_followevents_table.py +2 -4
  279. rucio/db/sqla/migrate_repo/versions/7ec22226cdbf_new_replica_state_for_temporary_.py +0 -1
  280. rucio/db/sqla/migrate_repo/versions/810a41685bc1_added_columns_rse_transfer_limits.py +1 -4
  281. rucio/db/sqla/migrate_repo/versions/83f991c63a93_correct_rse_expression_length.py +0 -2
  282. rucio/db/sqla/migrate_repo/versions/8523998e2e76_increase_size_of_extended_attributes_.py +0 -3
  283. rucio/db/sqla/migrate_repo/versions/8ea9122275b1_adding_missing_function_based_indices.py +1 -2
  284. rucio/db/sqla/migrate_repo/versions/90f47792bb76_add_clob_payload_to_messages.py +0 -3
  285. rucio/db/sqla/migrate_repo/versions/914b8f02df38_new_table_for_lifetime_model_exceptions.py +1 -3
  286. rucio/db/sqla/migrate_repo/versions/94a5961ddbf2_add_estimator_columns.py +0 -3
  287. rucio/db/sqla/migrate_repo/versions/9a1b149a2044_add_saml_identity_type.py +0 -1
  288. rucio/db/sqla/migrate_repo/versions/9a45bc4ea66d_add_vp_table.py +1 -2
  289. rucio/db/sqla/migrate_repo/versions/9eb936a81eb1_true_is_true.py +0 -2
  290. rucio/db/sqla/migrate_repo/versions/a08fa8de1545_transfer_stats_table.py +55 -0
  291. rucio/db/sqla/migrate_repo/versions/a118956323f8_added_vo_table_and_vo_col_to_rse.py +1 -3
  292. rucio/db/sqla/migrate_repo/versions/a193a275255c_add_status_column_in_messages.py +0 -2
  293. rucio/db/sqla/migrate_repo/versions/a5f6f6e928a7_1_7_0.py +1 -4
  294. rucio/db/sqla/migrate_repo/versions/a616581ee47_added_columns_to_table_requests.py +0 -1
  295. rucio/db/sqla/migrate_repo/versions/a6eb23955c28_state_idx_non_functional.py +0 -1
  296. rucio/db/sqla/migrate_repo/versions/a74275a1ad30_added_global_quota_table.py +1 -3
  297. rucio/db/sqla/migrate_repo/versions/a93e4e47bda_heartbeats.py +1 -4
  298. rucio/db/sqla/migrate_repo/versions/ae2a56fcc89_added_comment_column_to_rules.py +0 -1
  299. rucio/db/sqla/migrate_repo/versions/b0070f3695c8_add_deletedidmeta_table.py +57 -0
  300. rucio/db/sqla/migrate_repo/versions/b4293a99f344_added_column_identity_to_table_tokens.py +0 -3
  301. rucio/db/sqla/migrate_repo/versions/b5493606bbf5_fix_primary_key_for_subscription_history.py +41 -0
  302. rucio/db/sqla/migrate_repo/versions/b7d287de34fd_removal_of_replicastate_source.py +1 -2
  303. rucio/db/sqla/migrate_repo/versions/b818052fa670_add_index_to_quarantined_replicas.py +1 -3
  304. rucio/db/sqla/migrate_repo/versions/b8caac94d7f0_add_comments_column_for_subscriptions_.py +0 -3
  305. rucio/db/sqla/migrate_repo/versions/b96a1c7e1cc4_new_bad_pfns_table_and_bad_replicas_.py +1 -5
  306. rucio/db/sqla/migrate_repo/versions/bb695f45c04_extend_request_state.py +1 -3
  307. rucio/db/sqla/migrate_repo/versions/bc68e9946deb_add_staging_timestamps_to_request.py +0 -3
  308. rucio/db/sqla/migrate_repo/versions/bf3baa1c1474_correct_pk_and_idx_for_history_tables.py +1 -3
  309. rucio/db/sqla/migrate_repo/versions/c0937668555f_add_qos_policy_map_table.py +1 -2
  310. rucio/db/sqla/migrate_repo/versions/c129ccdb2d5_add_lumiblocknr_to_dids.py +0 -3
  311. rucio/db/sqla/migrate_repo/versions/ccdbcd48206e_add_did_type_column_index_on_did_meta_.py +1 -4
  312. rucio/db/sqla/migrate_repo/versions/cebad904c4dd_new_payload_column_for_heartbeats.py +1 -2
  313. rucio/db/sqla/migrate_repo/versions/d1189a09c6e0_oauth2_0_and_jwt_feature_support_adding_.py +1 -4
  314. rucio/db/sqla/migrate_repo/versions/d23453595260_extend_request_state_for_preparer.py +1 -3
  315. rucio/db/sqla/migrate_repo/versions/d6dceb1de2d_added_purge_column_to_rules.py +1 -4
  316. rucio/db/sqla/migrate_repo/versions/d6e2c3b2cf26_remove_third_party_copy_column_from_rse.py +0 -2
  317. rucio/db/sqla/migrate_repo/versions/d91002c5841_new_account_limits_table.py +1 -3
  318. rucio/db/sqla/migrate_repo/versions/e138c364ebd0_extending_columns_for_filter_and_.py +0 -3
  319. rucio/db/sqla/migrate_repo/versions/e59300c8b179_support_for_archive.py +1 -3
  320. rucio/db/sqla/migrate_repo/versions/f1b14a8c2ac1_postgres_use_check_constraints.py +0 -1
  321. rucio/db/sqla/migrate_repo/versions/f41ffe206f37_oracle_global_temporary_tables.py +1 -2
  322. rucio/db/sqla/migrate_repo/versions/f85a2962b021_adding_transfertool_column_to_requests_.py +1 -3
  323. rucio/db/sqla/migrate_repo/versions/fa7a7d78b602_increase_refresh_token_size.py +0 -2
  324. rucio/db/sqla/migrate_repo/versions/fb28a95fe288_add_replicas_rse_id_tombstone_idx.py +0 -1
  325. rucio/db/sqla/migrate_repo/versions/fe1a65b176c9_set_third_party_copy_read_and_write_.py +1 -2
  326. rucio/db/sqla/migrate_repo/versions/fe8ea2fa9788_added_third_party_copy_column_to_rse_.py +0 -3
  327. rucio/db/sqla/models.py +122 -216
  328. rucio/db/sqla/sautils.py +12 -5
  329. rucio/db/sqla/session.py +71 -43
  330. rucio/db/sqla/types.py +3 -4
  331. rucio/db/sqla/util.py +91 -69
  332. rucio/gateway/__init__.py +13 -0
  333. rucio/{api → gateway}/account.py +119 -46
  334. rucio/{api → gateway}/account_limit.py +12 -13
  335. rucio/{api → gateway}/authentication.py +106 -33
  336. rucio/{api → gateway}/config.py +12 -13
  337. rucio/{api → gateway}/credential.py +15 -4
  338. rucio/{api → gateway}/did.py +384 -140
  339. rucio/{api → gateway}/dirac.py +16 -6
  340. rucio/{api → gateway}/exporter.py +3 -4
  341. rucio/{api → gateway}/heartbeat.py +17 -5
  342. rucio/{api → gateway}/identity.py +63 -19
  343. rucio/{api → gateway}/importer.py +3 -4
  344. rucio/{api → gateway}/lifetime_exception.py +35 -10
  345. rucio/{api → gateway}/lock.py +34 -12
  346. rucio/{api/meta.py → gateway/meta_conventions.py} +18 -16
  347. rucio/{api → gateway}/permission.py +4 -5
  348. rucio/{api → gateway}/quarantined_replica.py +13 -4
  349. rucio/{api → gateway}/replica.py +12 -11
  350. rucio/{api → gateway}/request.py +129 -28
  351. rucio/{api → gateway}/rse.py +11 -12
  352. rucio/{api → gateway}/rule.py +117 -35
  353. rucio/{api → gateway}/scope.py +24 -14
  354. rucio/{api → gateway}/subscription.py +65 -43
  355. rucio/{api → gateway}/vo.py +17 -7
  356. rucio/rse/__init__.py +3 -4
  357. rucio/rse/protocols/__init__.py +0 -1
  358. rucio/rse/protocols/bittorrent.py +184 -0
  359. rucio/rse/protocols/cache.py +1 -2
  360. rucio/rse/protocols/dummy.py +1 -2
  361. rucio/rse/protocols/gfal.py +12 -10
  362. rucio/rse/protocols/globus.py +7 -7
  363. rucio/rse/protocols/gsiftp.py +2 -3
  364. rucio/rse/protocols/http_cache.py +1 -2
  365. rucio/rse/protocols/mock.py +1 -2
  366. rucio/rse/protocols/ngarc.py +1 -2
  367. rucio/rse/protocols/posix.py +12 -13
  368. rucio/rse/protocols/protocol.py +116 -52
  369. rucio/rse/protocols/rclone.py +6 -7
  370. rucio/rse/protocols/rfio.py +4 -5
  371. rucio/rse/protocols/srm.py +9 -10
  372. rucio/rse/protocols/ssh.py +8 -9
  373. rucio/rse/protocols/storm.py +2 -3
  374. rucio/rse/protocols/webdav.py +17 -14
  375. rucio/rse/protocols/xrootd.py +23 -17
  376. rucio/rse/rsemanager.py +19 -7
  377. rucio/tests/__init__.py +0 -1
  378. rucio/tests/common.py +43 -17
  379. rucio/tests/common_server.py +3 -3
  380. rucio/transfertool/__init__.py +0 -1
  381. rucio/transfertool/bittorrent.py +199 -0
  382. rucio/transfertool/bittorrent_driver.py +52 -0
  383. rucio/transfertool/bittorrent_driver_qbittorrent.py +133 -0
  384. rucio/transfertool/fts3.py +250 -138
  385. rucio/transfertool/fts3_plugins.py +152 -0
  386. rucio/transfertool/globus.py +9 -8
  387. rucio/transfertool/globus_library.py +1 -2
  388. rucio/transfertool/mock.py +21 -12
  389. rucio/transfertool/transfertool.py +33 -24
  390. rucio/vcsversion.py +4 -4
  391. rucio/version.py +5 -13
  392. rucio/web/__init__.py +0 -1
  393. rucio/web/rest/__init__.py +0 -1
  394. rucio/web/rest/flaskapi/__init__.py +0 -1
  395. rucio/web/rest/flaskapi/authenticated_bp.py +0 -1
  396. rucio/web/rest/flaskapi/v1/__init__.py +0 -1
  397. rucio/web/rest/flaskapi/v1/accountlimits.py +15 -13
  398. rucio/web/rest/flaskapi/v1/accounts.py +49 -48
  399. rucio/web/rest/flaskapi/v1/archives.py +12 -10
  400. rucio/web/rest/flaskapi/v1/auth.py +146 -144
  401. rucio/web/rest/flaskapi/v1/common.py +82 -41
  402. rucio/web/rest/flaskapi/v1/config.py +5 -6
  403. rucio/web/rest/flaskapi/v1/credentials.py +7 -8
  404. rucio/web/rest/flaskapi/v1/dids.py +158 -28
  405. rucio/web/rest/flaskapi/v1/dirac.py +8 -8
  406. rucio/web/rest/flaskapi/v1/export.py +3 -5
  407. rucio/web/rest/flaskapi/v1/heartbeats.py +3 -5
  408. rucio/web/rest/flaskapi/v1/identities.py +3 -5
  409. rucio/web/rest/flaskapi/v1/import.py +3 -4
  410. rucio/web/rest/flaskapi/v1/lifetime_exceptions.py +6 -9
  411. rucio/web/rest/flaskapi/v1/locks.py +2 -4
  412. rucio/web/rest/flaskapi/v1/main.py +10 -2
  413. rucio/web/rest/flaskapi/v1/{meta.py → meta_conventions.py} +26 -11
  414. rucio/web/rest/flaskapi/v1/metrics.py +1 -2
  415. rucio/web/rest/flaskapi/v1/nongrid_traces.py +4 -4
  416. rucio/web/rest/flaskapi/v1/ping.py +6 -7
  417. rucio/web/rest/flaskapi/v1/redirect.py +8 -9
  418. rucio/web/rest/flaskapi/v1/replicas.py +43 -19
  419. rucio/web/rest/flaskapi/v1/requests.py +178 -21
  420. rucio/web/rest/flaskapi/v1/rses.py +61 -26
  421. rucio/web/rest/flaskapi/v1/rules.py +48 -18
  422. rucio/web/rest/flaskapi/v1/scopes.py +3 -5
  423. rucio/web/rest/flaskapi/v1/subscriptions.py +22 -18
  424. rucio/web/rest/flaskapi/v1/traces.py +4 -4
  425. rucio/web/rest/flaskapi/v1/types.py +20 -0
  426. rucio/web/rest/flaskapi/v1/vos.py +3 -5
  427. rucio/web/rest/main.py +0 -1
  428. rucio/web/rest/metrics.py +0 -1
  429. rucio/web/rest/ping.py +27 -0
  430. {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/ldap.cfg.template +1 -1
  431. rucio-35.8.0.data/data/rucio/requirements.server.txt +268 -0
  432. {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/tools/bootstrap.py +3 -3
  433. {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/tools/merge_rucio_configs.py +2 -5
  434. {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/tools/reset_database.py +3 -3
  435. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio +87 -85
  436. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-abacus-account +0 -1
  437. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-abacus-collection-replica +0 -1
  438. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-abacus-rse +0 -1
  439. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-admin +45 -32
  440. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-atropos +0 -1
  441. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-auditor +13 -7
  442. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-automatix +1 -2
  443. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-bb8 +0 -1
  444. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-c3po +0 -1
  445. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-cache-client +2 -3
  446. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-cache-consumer +0 -1
  447. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-conveyor-finisher +1 -2
  448. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-conveyor-poller +0 -1
  449. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-conveyor-preparer +0 -1
  450. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-conveyor-receiver +0 -1
  451. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-conveyor-stager +0 -1
  452. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-conveyor-submitter +2 -3
  453. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-conveyor-throttler +0 -1
  454. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-dark-reaper +0 -1
  455. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-dumper +11 -10
  456. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-follower +0 -1
  457. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-hermes +0 -1
  458. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-judge-cleaner +0 -1
  459. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-judge-evaluator +2 -3
  460. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-judge-injector +0 -1
  461. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-judge-repairer +0 -1
  462. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-kronos +1 -3
  463. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-minos +0 -1
  464. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-minos-temporary-expiration +0 -1
  465. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-necromancer +1 -2
  466. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-oauth-manager +2 -3
  467. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-reaper +0 -1
  468. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-replica-recoverer +6 -7
  469. rucio-35.8.0.data/scripts/rucio-rse-decommissioner +66 -0
  470. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-storage-consistency-actions +0 -1
  471. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-transmogrifier +0 -1
  472. {rucio-32.8.6.data → rucio-35.8.0.data}/scripts/rucio-undertaker +1 -2
  473. rucio-35.8.0.dist-info/METADATA +72 -0
  474. rucio-35.8.0.dist-info/RECORD +493 -0
  475. {rucio-32.8.6.dist-info → rucio-35.8.0.dist-info}/WHEEL +1 -1
  476. {rucio-32.8.6.dist-info → rucio-35.8.0.dist-info}/licenses/AUTHORS.rst +3 -0
  477. rucio/api/temporary_did.py +0 -49
  478. rucio/common/schema/cms.py +0 -478
  479. rucio/common/schema/lsst.py +0 -423
  480. rucio/core/permission/cms.py +0 -1166
  481. rucio/core/temporary_did.py +0 -188
  482. rucio/daemons/reaper/light_reaper.py +0 -255
  483. rucio/web/rest/flaskapi/v1/tmp_dids.py +0 -115
  484. rucio-32.8.6.data/data/rucio/requirements.txt +0 -55
  485. rucio-32.8.6.data/scripts/rucio-light-reaper +0 -53
  486. rucio-32.8.6.dist-info/METADATA +0 -83
  487. rucio-32.8.6.dist-info/RECORD +0 -481
  488. {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/alembic.ini.template +0 -0
  489. {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/alembic_offline.ini.template +0 -0
  490. {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/globus-config.yml.template +0 -0
  491. {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/mail_templates/rule_approval_request.tmpl +0 -0
  492. {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/mail_templates/rule_approved_admin.tmpl +0 -0
  493. {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/mail_templates/rule_approved_user.tmpl +0 -0
  494. {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/mail_templates/rule_denied_admin.tmpl +0 -0
  495. {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/mail_templates/rule_denied_user.tmpl +0 -0
  496. {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/mail_templates/rule_ok_notification.tmpl +0 -0
  497. {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/rse-accounts.cfg.template +0 -0
  498. {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/rucio.cfg.atlas.client.template +0 -0
  499. {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/rucio.cfg.template +0 -0
  500. {rucio-32.8.6.data → rucio-35.8.0.data}/data/rucio/etc/rucio_multi_vo.cfg.template +0 -0
  501. {rucio-32.8.6.dist-info → rucio-35.8.0.dist-info}/licenses/LICENSE +0 -0
  502. {rucio-32.8.6.dist-info → rucio-35.8.0.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
1
  # Copyright European Organization for Nuclear Research (CERN) since 2012
3
2
  #
4
3
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,8 +18,7 @@ Conveyor stager is a daemon to manage stagein file transfers.
19
18
 
20
19
  import logging
21
20
  import threading
22
- from types import FrameType
23
- from typing import Optional
21
+ from typing import TYPE_CHECKING, Any, Optional
24
22
 
25
23
  import rucio.db.sqla.util
26
24
  from rucio.common import exception
@@ -32,22 +30,28 @@ from rucio.daemons.conveyor.submitter import submitter
32
30
  from rucio.db.sqla.constants import RequestType
33
31
  from rucio.transfertool.fts3 import FTS3Transfertool
34
32
 
33
+ if TYPE_CHECKING:
34
+ from collections.abc import Mapping, Sequence
35
+ from types import FrameType
36
+
37
+ from rucio.common.types import RSESettingsDict
38
+
35
39
  METRICS = MetricManager(module=__name__)
36
40
  GRACEFUL_STOP = threading.Event()
37
41
  DAEMON_NAME = 'conveyor-stager'
38
42
 
39
43
 
40
44
  def stager(
41
- once=False,
42
- rses=None,
43
- bulk=100,
44
- group_bulk=1,
45
- group_policy='rule',
46
- source_strategy=None,
47
- activities=None,
48
- sleep_time=600,
49
- total_threads=1
50
- ):
45
+ once: bool = False,
46
+ rses: Optional[list["RSESettingsDict"]] = None,
47
+ bulk: int = 100,
48
+ group_bulk: int = 1,
49
+ group_policy: str = 'rule',
50
+ source_strategy: Optional[str] = None,
51
+ activities: Optional[list[str]] = None,
52
+ sleep_time: int = 600,
53
+ total_threads: int = 1
54
+ ) -> None:
51
55
 
52
56
  submitter(
53
57
  once=once,
@@ -71,7 +75,7 @@ def stager(
71
75
  )
72
76
 
73
77
 
74
- def stop(signum: Optional[int] = None, frame: Optional[FrameType] = None) -> None:
78
+ def stop(signum: Optional[int] = None, frame: Optional["FrameType"] = None) -> None:
75
79
  """
76
80
  Graceful exit.
77
81
  """
@@ -80,22 +84,23 @@ def stop(signum: Optional[int] = None, frame: Optional[FrameType] = None) -> Non
80
84
 
81
85
 
82
86
  def run(
83
- once=False,
84
- total_threads=1,
85
- group_bulk=1,
86
- group_policy='rule',
87
- rses=None,
88
- include_rses=None,
89
- exclude_rses=None,
90
- vos=None,
91
- bulk=100,
92
- source_strategy=None,
93
- activities=[],
94
- sleep_time=600
95
- ):
87
+ once: bool = False,
88
+ total_threads: int = 1,
89
+ group_bulk: int = 1,
90
+ group_policy: str = 'rule',
91
+ rses: Optional["Sequence[Mapping[str, Any]]"] = None,
92
+ include_rses: Optional[str] = None,
93
+ exclude_rses: Optional[str] = None,
94
+ vos: Optional[list[str]] = None,
95
+ bulk: int = 100,
96
+ source_strategy: Optional[str] = None,
97
+ activities: Optional[list[str]] = None,
98
+ sleep_time: int = 600
99
+ ) -> None:
96
100
  """
97
- Starts up the conveyer threads.
101
+ Starts up the conveyor threads.
98
102
  """
103
+ activities = activities or []
99
104
  setup_logging(process_name=DAEMON_NAME)
100
105
 
101
106
  if rucio.db.sqla.util.is_old_db():
@@ -1,4 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
1
  # Copyright European Organization for Nuclear Research (CERN) since 2012
3
2
  #
4
3
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,27 +18,28 @@ Conveyor transfer submitter is a daemon to manage non-tape file transfers.
19
18
  import logging
20
19
  import threading
21
20
  from collections.abc import Mapping
22
- from types import FrameType
23
- from typing import TYPE_CHECKING, Any, Optional
21
+ from typing import TYPE_CHECKING, Optional
24
22
 
25
23
  import rucio.db.sqla.util
26
24
  from rucio.common import exception
27
- from rucio.common.config import config_get, config_get_bool, config_get_int, config_get_list, config_get_float
25
+ from rucio.common.config import config_get, config_get_bool, config_get_float, config_get_int, config_get_list
28
26
  from rucio.common.logging import setup_logging
29
27
  from rucio.common.schema import get_schema_value
30
28
  from rucio.common.stopwatch import Stopwatch
31
29
  from rucio.core.monitor import MetricManager
32
- from rucio.core.request import list_and_mark_transfer_requests_and_source_replicas
33
- from rucio.core.topology import Topology, ExpiringObjectCache
34
- from rucio.core.transfer import DEFAULT_MULTIHOP_TOMBSTONE_DELAY, list_transfer_admin_accounts, transfer_path_str, \
35
- TRANSFERTOOL_CLASSES_BY_NAME, ProtocolFactory
36
- from rucio.daemons.common import db_workqueue, ProducerConsumerDaemon
37
- from rucio.daemons.conveyor.common import submit_transfer, get_conveyor_rses, pick_and_prepare_submission_path
38
- from rucio.db.sqla.constants import RequestType, RequestState
30
+ from rucio.core.request import RequestWithSources, list_and_mark_transfer_requests_and_source_replicas
31
+ from rucio.core.topology import ExpiringObjectCache, Topology
32
+ from rucio.core.transfer import DEFAULT_MULTIHOP_TOMBSTONE_DELAY, TRANSFERTOOL_CLASSES_BY_NAME, ProtocolFactory, list_transfer_admin_accounts, transfer_path_str
33
+ from rucio.daemons.common import ProducerConsumerDaemon, db_workqueue
34
+ from rucio.daemons.conveyor.common import get_conveyor_rses, pick_and_prepare_submission_path, submit_transfer
35
+ from rucio.db.sqla.constants import RequestState, RequestType
39
36
  from rucio.transfertool.fts3 import FTS3Transfertool
40
37
  from rucio.transfertool.globus import GlobusTransferTool
41
38
 
42
39
  if TYPE_CHECKING:
40
+ from types import FrameType
41
+
42
+ from rucio.common.types import LoggerFunction, RSESettingsDict
43
43
  from rucio.daemons.common import HeartbeatHandler
44
44
 
45
45
  METRICS = MetricManager(module=__name__)
@@ -60,16 +60,16 @@ def _fetch_requests(
60
60
  ignore_availability: bool,
61
61
  filter_transfertool: Optional[str],
62
62
  metrics: MetricManager,
63
- cached_topology,
63
+ cached_topology: Optional[ExpiringObjectCache],
64
64
  set_last_processed_by: bool,
65
65
  heartbeat_handler: "HeartbeatHandler",
66
- ):
66
+ ) -> tuple[bool, tuple[Topology, dict[str, RequestWithSources]]]:
67
67
  """
68
68
  Fetches requests to be handled from the database
69
69
  """
70
70
  worker_number, total_workers, logger = heartbeat_handler.live()
71
71
 
72
- topology = cached_topology.get() if cached_topology else Topology(ignore_availability=ignore_availability)
72
+ topology: Topology = cached_topology.get() if cached_topology else Topology(ignore_availability=ignore_availability)
73
73
  topology.configure_multihop(logger=logger)
74
74
  stopwatch = Stopwatch()
75
75
 
@@ -114,17 +114,17 @@ def _fetch_requests(
114
114
 
115
115
 
116
116
  def _handle_requests(
117
- batch,
117
+ batch: tuple[Topology, Mapping[str, RequestWithSources]],
118
118
  *,
119
119
  transfertools: list[str],
120
120
  schemes: Optional[list[str]],
121
121
  failover_schemes: Optional[list[str]],
122
122
  max_sources: int,
123
123
  timeout: Optional[float],
124
- transfertool_kwargs,
124
+ transfertool_kwargs: dict,
125
125
  metrics: MetricManager,
126
- logger=logging.log,
127
- ):
126
+ logger: "LoggerFunction" = logging.log,
127
+ ) -> None:
128
128
  topology, requests_with_sources = batch
129
129
 
130
130
  protocol_factory = ProtocolFactory()
@@ -168,7 +168,7 @@ def _handle_requests(
168
168
  for job in grouped_jobs:
169
169
  logger(logging.DEBUG, 'submitjob: transfers=%s, job_params=%s' % ([str(t) for t in job['transfers']], job['job_params']))
170
170
  submit_transfer(transfertool_obj=transfertool_obj, transfers=job['transfers'], job_params=job['job_params'],
171
- timeout=timeout, logger=logger)
171
+ timeout=timeout, logger=logger) # type: ignore (unclear whether timeout is supposed to be float or int)
172
172
 
173
173
 
174
174
  def _get_max_time_in_queue_conf() -> dict[str, int]:
@@ -189,7 +189,7 @@ def _get_max_time_in_queue_conf() -> dict[str, int]:
189
189
 
190
190
  def submitter(
191
191
  once: bool = False,
192
- rses: Optional[list[Mapping[str, Any]]] = None,
192
+ rses: Optional[list["RSESettingsDict"]] = None,
193
193
  partition_wait_time: int = 10,
194
194
  bulk: int = 100,
195
195
  group_bulk: int = 1,
@@ -207,9 +207,9 @@ def submitter(
207
207
  request_type: Optional[list[RequestType]] = None,
208
208
  default_lifetime: int = 172800,
209
209
  metrics: MetricManager = METRICS,
210
- cached_topology=None,
210
+ cached_topology: Optional[ExpiringObjectCache] = None,
211
211
  total_threads: int = 1,
212
- ):
212
+ ) -> None:
213
213
  """
214
214
  Main loop to submit a new transfer primitive to a transfertool.
215
215
  """
@@ -219,8 +219,28 @@ def submitter(
219
219
 
220
220
  partition_hash_var = config_get('conveyor', 'partition_hash_var', default=None, raise_exception=False)
221
221
 
222
- schemes = config_get_list('conveyor', 'scheme', default=None, raise_exception=False)
223
- failover_schemes = config_get_list('conveyor', 'failover_scheme', default=None, raise_exception=False)
222
+ config_schemes = set(config_get_list('conveyor', 'scheme', raise_exception=False) or [])
223
+ config_failover_schemes = set(config_get_list('conveyor', 'failover_scheme', raise_exception=False) or [])
224
+
225
+ schemes_supported_by_tt = set()
226
+ for transfertool in transfertools:
227
+ schemes_supported_by_tt.update(TRANSFERTOOL_CLASSES_BY_NAME[transfertool].supported_schemes)
228
+
229
+ schemes = config_schemes.intersection(schemes_supported_by_tt)
230
+ failover_schemes = config_failover_schemes.intersection(schemes_supported_by_tt)
231
+
232
+ if config_schemes and not schemes:
233
+ logging.critical(f'None of the configured schemes ({list(config_schemes)}) is supported '
234
+ f'by any configured transfertool ({transfertools}). This configuration is invalid. Aborting')
235
+ return
236
+ if config_failover_schemes and not failover_schemes:
237
+ logging.critical(f'None of the configured failover schemes ({list(config_failover_schemes)}) is supported '
238
+ f'by any configured transfertool ({transfertools}). This configuration is invalid. Aborting')
239
+ return
240
+ if config_schemes.difference(schemes):
241
+ logging.info(f'Following schemes filtered out: {list(config_schemes.difference(schemes))}')
242
+ if config_failover_schemes.difference(failover_schemes):
243
+ logging.info(f'Following failover schemes filtered out: {list(config_failover_schemes.difference(failover_schemes))}')
224
244
 
225
245
  timeout = config_get_float('conveyor', 'submit_timeout', default=None, raise_exception=False)
226
246
 
@@ -262,7 +282,11 @@ def submitter(
262
282
  partition_wait_time=partition_wait_time,
263
283
  sleep_time=sleep_time,
264
284
  activities=activities)
265
- def _db_producer(*, activity, heartbeat_handler):
285
+ def _db_producer(
286
+ *,
287
+ activity: str,
288
+ heartbeat_handler: "HeartbeatHandler"
289
+ ) -> tuple[bool, tuple[Topology, dict[str, RequestWithSources]]]:
266
290
  return _fetch_requests(
267
291
  bulk=bulk,
268
292
  filter_transfertool=filter_transfertool,
@@ -277,12 +301,12 @@ def submitter(
277
301
  heartbeat_handler=heartbeat_handler,
278
302
  )
279
303
 
280
- def _consumer(batch):
304
+ def _consumer(batch: tuple[Topology, Mapping[str, RequestWithSources]]) -> None:
281
305
  return _handle_requests(
282
306
  batch,
283
307
  transfertools=transfertools,
284
- schemes=schemes,
285
- failover_schemes=failover_schemes,
308
+ schemes=list(schemes),
309
+ failover_schemes=list(failover_schemes),
286
310
  max_sources=max_sources,
287
311
  timeout=timeout,
288
312
  transfertool_kwargs=transfertool_kwargs,
@@ -296,7 +320,7 @@ def submitter(
296
320
  ).run()
297
321
 
298
322
 
299
- def stop(signum: "Optional[int]" = None, frame: "Optional[FrameType]" = None) -> None:
323
+ def stop(signum: Optional[int] = None, frame: Optional["FrameType"] = None) -> None:
300
324
  """
301
325
  Graceful exit.
302
326
  """
@@ -304,26 +328,26 @@ def stop(signum: "Optional[int]" = None, frame: "Optional[FrameType]" = None) ->
304
328
 
305
329
 
306
330
  def run(
307
- once=False,
308
- group_bulk=1,
309
- group_policy='rule',
310
- rses=None,
311
- include_rses=None,
312
- exclude_rses=None,
313
- vos=None,
314
- bulk=100,
315
- source_strategy=None,
316
- activities=None,
317
- exclude_activities=None,
318
- ignore_availability=False,
319
- sleep_time=600,
320
- max_sources=4,
321
- archive_timeout_override=None,
322
- total_threads=1,
331
+ once: bool = False,
332
+ group_bulk: int = 1,
333
+ group_policy: str = 'rule',
334
+ rses: Optional[list["RSESettingsDict"]] = None,
335
+ include_rses: Optional[str] = None,
336
+ exclude_rses: Optional[str] = None,
337
+ vos: Optional[list[str]] = None,
338
+ bulk: int = 100,
339
+ source_strategy: Optional[str] = None,
340
+ activities: Optional[list[str]] = None,
341
+ exclude_activities: Optional[list[str]] = None,
342
+ ignore_availability: bool = False,
343
+ sleep_time: int = 600,
344
+ max_sources: int = 4,
345
+ archive_timeout_override: Optional[int] = None,
346
+ total_threads: int = 1,
323
347
  **_kwargs
324
- ):
348
+ ) -> None:
325
349
  """
326
- Starts up the conveyer threads.
350
+ Starts up the conveyor threads.
327
351
  """
328
352
  setup_logging(process_name=DAEMON_NAME)
329
353
 
@@ -1,4 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
1
  # Copyright European Organization for Nuclear Research (CERN) since 2012
3
2
  #
4
3
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,39 +16,77 @@
17
16
  Conveyor throttler is a daemon to manage rucio internal queue.
18
17
  """
19
18
  import logging
19
+ import math
20
20
  import threading
21
21
  import traceback
22
22
  from collections import defaultdict
23
- from types import FrameType
24
- from typing import TYPE_CHECKING, Optional
23
+ from typing import TYPE_CHECKING, Optional, TypedDict, Union
25
24
 
26
- import math
27
25
  from sqlalchemy import null
28
26
 
29
27
  import rucio.db.sqla.util
30
28
  from rucio.common import exception
31
29
  from rucio.common.logging import setup_logging
32
30
  from rucio.core.monitor import MetricManager
33
- from rucio.core.request import (get_request_stats, release_all_waiting_requests, release_waiting_requests_fifo,
34
- release_waiting_requests_grouped_fifo, set_transfer_limit_stats, re_sync_all_transfer_limits)
35
- from rucio.core.rse import RseCollection
31
+ from rucio.core.request import get_request_stats, re_sync_all_transfer_limits, release_all_waiting_requests, release_waiting_requests_fifo, release_waiting_requests_grouped_fifo, reset_stale_waiting_requests, set_transfer_limit_stats
32
+ from rucio.core.rse import RseCollection, RseData
36
33
  from rucio.core.transfer import applicable_rse_transfer_limits
37
- from rucio.daemons.common import db_workqueue, ProducerConsumerDaemon
34
+ from rucio.daemons.common import ProducerConsumerDaemon, db_workqueue
38
35
  from rucio.db.sqla.constants import RequestState, TransferLimitDirection
39
36
 
40
37
  if TYPE_CHECKING:
38
+ from collections.abc import Iterator
39
+ from types import FrameType
40
+
41
+ from rucio.common.types import InternalAccount, LoggerFunction
41
42
  from rucio.daemons.common import HeartbeatHandler
42
43
 
44
+ class LimitDict(TypedDict):
45
+ activity: Optional[str]
46
+ direction: TransferLimitDirection
47
+ waitings: int
48
+ transfers: int
49
+ max_transfers: int
50
+ rse_expression: str
51
+ strategy: str
52
+ volume: int
53
+ deadline: int
54
+
55
+ class AccountStatDict(TypedDict):
56
+ waiting: int
57
+ active: int
58
+ residual_capacity: float
59
+
60
+ class StatDict(TypedDict):
61
+ accounts: AccountStatDict
62
+ residual_capacity: float
63
+ waiting: int
64
+ active: int
65
+
66
+ class LimitStatDict(TypedDict):
67
+ limit: LimitDict
68
+ stat: StatDict
69
+
70
+ ReleaseGroupsDict = dict[
71
+ tuple[
72
+ RseData, # source_rse
73
+ RseData, # dest_rse
74
+ str, # activity
75
+ ],
76
+ list[LimitStatDict] # applicable_limits
77
+ ]
78
+
79
+
43
80
  GRACEFUL_STOP = threading.Event()
44
81
  METRICS = MetricManager(module=__name__)
45
82
  DAEMON_NAME = 'conveyor-throttler'
46
83
 
47
84
 
48
85
  def throttler(
49
- once=False,
50
- sleep_time=600,
51
- partition_wait_time=10
52
- ):
86
+ once: bool = False,
87
+ sleep_time: int = 600,
88
+ partition_wait_time: int = 10
89
+ ) -> None:
53
90
  """
54
91
  Main loop to check rse transfer limits.
55
92
  """
@@ -62,7 +99,11 @@ def throttler(
62
99
  executable=DAEMON_NAME,
63
100
  partition_wait_time=partition_wait_time,
64
101
  sleep_time=sleep_time)
65
- def _db_producer(*, activity: str, heartbeat_handler: "HeartbeatHandler"):
102
+ def _db_producer(
103
+ *,
104
+ activity: str,
105
+ heartbeat_handler: "HeartbeatHandler"
106
+ ) -> tuple[bool, Optional["ReleaseGroupsDict"]]:
66
107
  worker_number, total_workers, logger = heartbeat_handler.live()
67
108
  if worker_number != 0:
68
109
  logger(logging.INFO, 'Throttler thread id is not 0, will sleep. Only thread 0 will work')
@@ -73,7 +114,7 @@ def throttler(
73
114
  release_groups = _get_request_stats(rse_collection, logger=logger)
74
115
  return True, release_groups
75
116
 
76
- def _consumer(release_groups):
117
+ def _consumer(release_groups: Optional["ReleaseGroupsDict"]) -> None:
77
118
  if release_groups is None:
78
119
  return
79
120
  logger = logging.log
@@ -82,6 +123,7 @@ def throttler(
82
123
  _handle_requests(release_groups, logger=logger)
83
124
  except Exception:
84
125
  logger(logging.CRITICAL, "Failed to schedule requests, error: %s" % (traceback.format_exc()))
126
+ reset_stale_waiting_requests()
85
127
 
86
128
  ProducerConsumerDaemon(
87
129
  producers=[_db_producer],
@@ -90,7 +132,7 @@ def throttler(
90
132
  ).run()
91
133
 
92
134
 
93
- def stop(signum: Optional[int] = None, frame: Optional[FrameType] = None) -> None:
135
+ def stop(signum: Optional[int] = None, frame: Optional["FrameType"] = None) -> None:
94
136
  """
95
137
  Graceful exit.
96
138
  """
@@ -98,9 +140,12 @@ def stop(signum: Optional[int] = None, frame: Optional[FrameType] = None) -> Non
98
140
  GRACEFUL_STOP.set()
99
141
 
100
142
 
101
- def run(once=False, sleep_time=600):
143
+ def run(
144
+ once: bool = False,
145
+ sleep_time: int = 600
146
+ ) -> None:
102
147
  """
103
- Starts up the conveyer threads.
148
+ Starts up the conveyor threads.
104
149
  """
105
150
  setup_logging(process_name=DAEMON_NAME)
106
151
 
@@ -114,19 +159,25 @@ class RequestGrouper:
114
159
 
115
160
  class RseStatistic:
116
161
  def __init__(self):
117
- self.sources_with_limits = set()
118
- self.destinations_with_limits = set()
119
- self.unavailable_sources = set()
120
- self.unavailable_destinations = set()
162
+ self.sources_with_limits: set[RseData] = set()
163
+ self.destinations_with_limits: set[RseData] = set()
164
+ self.unavailable_sources: set[RseData] = set()
165
+ self.unavailable_destinations: set[RseData] = set()
121
166
  self.has_any_per_activity_limit = False
122
167
  self.any_source_has_per_activity_limit = False
123
168
  self.any_destination_has_per_activity_limit = False
124
169
 
125
170
  def __init__(self):
126
- self.waiting_transfer_groups = {}
171
+ self.waiting_transfer_groups: 'ReleaseGroupsDict' = {}
127
172
  self.rse_stats = defaultdict(self.RseStatistic)
128
173
 
129
- def record_waiting_request_group(self, source_rse, dest_rse, activity, applicable_limits):
174
+ def record_waiting_request_group(
175
+ self,
176
+ source_rse: RseData,
177
+ dest_rse: RseData,
178
+ activity: str,
179
+ applicable_limits: list['LimitStatDict']
180
+ ) -> None:
130
181
  """
131
182
  Record a group of requests in waiting state, while computing some statistics about them.
132
183
  """
@@ -152,12 +203,12 @@ class RequestGrouper:
152
203
 
153
204
  self.waiting_transfer_groups[source_rse, dest_rse, activity] = applicable_limits
154
205
 
155
- def merged_groups(self):
206
+ def merged_groups(self) -> "ReleaseGroupsDict":
156
207
  """
157
208
  Merge groups which can be handled together
158
209
  """
159
210
 
160
- merged_groups = {}
211
+ merged_groups: "ReleaseGroupsDict" = {}
161
212
  for (source_rse, dest_rse, activity), applicable_limits in self.waiting_transfer_groups.items():
162
213
 
163
214
  src_info = self.rse_stats[source_rse]
@@ -187,12 +238,16 @@ class RequestGrouper:
187
238
  if not src_info.has_any_per_activity_limit and not src_info.any_destination_has_per_activity_limit:
188
239
  activity = None
189
240
 
190
- merged_groups.setdefault((source_rse, dest_rse, activity), applicable_limits)
241
+ merged_groups.setdefault((source_rse, dest_rse, activity), applicable_limits) # type: ignore
191
242
 
192
243
  return merged_groups
193
244
 
194
245
 
195
- def _get_request_stats(rse_collection: RseCollection, *, logger=logging.log):
246
+ def _get_request_stats(
247
+ rse_collection: RseCollection,
248
+ *,
249
+ logger: "LoggerFunction" = logging.log
250
+ ) -> "ReleaseGroupsDict":
196
251
  """
197
252
  Group waiting requests into arbitrary groups for bulk handling.
198
253
  The current grouping (source rse + dest rse + activity) was dictated
@@ -209,7 +264,7 @@ def _get_request_stats(rse_collection: RseCollection, *, logger=logging.log):
209
264
  """
210
265
  logging.info("Throttler retrieve requests statistics")
211
266
 
212
- db_stats = get_request_stats(
267
+ db_stats = get_request_stats( # type: ignore (Session parameter is missing)
213
268
  state=[RequestState.QUEUED,
214
269
  RequestState.SUBMITTING,
215
270
  RequestState.SUBMITTED,
@@ -278,7 +333,7 @@ def _get_request_stats(rse_collection: RseCollection, *, logger=logging.log):
278
333
 
279
334
  if state == RequestState.WAITING:
280
335
  grouper.record_waiting_request_group(
281
- source_rse=source_rse,
336
+ source_rse=source_rse, # type: ignore
282
337
  dest_rse=dest_rse,
283
338
  activity=activity,
284
339
  applicable_limits=applicable_limits,
@@ -322,14 +377,17 @@ def _get_request_stats(rse_collection: RseCollection, *, logger=logging.log):
322
377
  if waiting != limit['waitings'] or active != limit['transfers']:
323
378
  set_transfer_limit_stats(limit['id'], waitings=waiting, transfers=active)
324
379
 
325
- for account, to_release_for_account in _split_threshold_per_account(stat['accounts'], total_to_release=residual_capacity):
380
+ for account, to_release_for_account in _split_threshold_per_account(stat['accounts'], total_to_release=residual_capacity): # type: ignore (stat['accounts'] is not None)
326
381
  stat['accounts'][account]['residual_capacity'] = to_release_for_account
327
382
 
328
383
  release_groups = grouper.merged_groups()
329
384
  return release_groups
330
385
 
331
386
 
332
- def _split_threshold_per_account(per_account_stats, total_to_release):
387
+ def _split_threshold_per_account(
388
+ per_account_stats: dict["InternalAccount", dict[str, float]],
389
+ total_to_release: float
390
+ ) -> Union[tuple[None, int], "Iterator[tuple[InternalAccount, float]]"]:
333
391
  """
334
392
  Compute how many requests to release for each account. Try to achieve a fair share of transfers between accounts.
335
393
  :param per_account_stats: a dict with how many active and waiting transfers each account has
@@ -355,7 +413,9 @@ def _split_threshold_per_account(per_account_stats, total_to_release):
355
413
  remaining_to_release -= to_release_for_account
356
414
 
357
415
 
358
- def _combine_limits(applicable_limits):
416
+ def _combine_limits(
417
+ applicable_limits: list['LimitStatDict']
418
+ ) -> tuple[float, str, Optional[int], Optional[int]]:
359
419
  """
360
420
  Take multiple limits and combines them into one single (strictest) limit which
361
421
  respects the constraints of each initial limits. This is to handle cases like:
@@ -391,7 +451,10 @@ def _combine_limits(applicable_limits):
391
451
  return to_release, strategy, volume, deadline
392
452
 
393
453
 
394
- def _handle_requests(release_groups, logger):
454
+ def _handle_requests(
455
+ release_groups: "ReleaseGroupsDict",
456
+ logger: "LoggerFunction"
457
+ ) -> None:
395
458
  """
396
459
  Release (set to queued state) waiting requests in groups defined by release_groups.
397
460
 
@@ -440,8 +503,9 @@ def _handle_requests(release_groups, logger):
440
503
  to_release_for_account = {}
441
504
  limits_by_account = {}
442
505
  for limit_stat in applicable_limits:
443
- for account, account_limit in limit_stat['stat']['accounts'].items():
444
- to_release_for_account[account] = min(to_release_for_account.get(account, to_release), account_limit['residual_capacity'])
506
+ acc_dict = limit_stat['stat']['accounts']
507
+ for account, account_limit in acc_dict.items():
508
+ to_release_for_account[account] = min(to_release_for_account.get(account, to_release), account_limit['residual_capacity']) # type: ignore (Issue with TypedDict.__getitem__)
445
509
  limits_by_account.setdefault(account, []).append(account_limit)
446
510
 
447
511
  for account, to_release_account in to_release_for_account.items():
@@ -1,4 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
1
  # Copyright European Organization for Nuclear Research (CERN) since 2012
3
2
  #
4
3
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,4 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
1
  # Copyright European Organization for Nuclear Research (CERN) since 2012
3
2
  #
4
3
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -25,7 +24,7 @@ from rucio.common import exception
25
24
  from rucio.common.logging import setup_logging
26
25
  from rucio.common.utils import get_thread_with_periodic_running_function
27
26
  from rucio.core.did import create_reports
28
- from rucio.core.heartbeat import live, die, sanity_check
27
+ from rucio.core.heartbeat import die, live, sanity_check
29
28
 
30
29
  if TYPE_CHECKING:
31
30
  from types import FrameType
@@ -35,7 +34,9 @@ graceful_stop = threading.Event()
35
34
  DAEMON_NAME = 'rucio-follower'
36
35
 
37
36
 
38
- def aggregate_events(once=False):
37
+ def aggregate_events(
38
+ once: bool = False
39
+ ) -> None:
39
40
  """
40
41
  Collect all the events affecting the dids followed by the corresponding account.
41
42
  """
@@ -70,7 +71,10 @@ def stop(signum: "Optional[int]" = None, frame: "Optional[FrameType]" = None) ->
70
71
  graceful_stop.set()
71
72
 
72
73
 
73
- def run(once=False, threads=1):
74
+ def run(
75
+ once: bool = False,
76
+ threads: int = 1
77
+ ) -> None:
74
78
  """
75
79
  Starts up the follower threads
76
80
  """
@@ -88,10 +92,10 @@ def run(once=False, threads=1):
88
92
  else:
89
93
  logging.info("starting follower threads")
90
94
  # Run the follower daemon thrice a day
91
- threads = [get_thread_with_periodic_running_function(28800, aggregate_events, graceful_stop) for i in range(threads)]
92
- [t.start() for t in threads]
95
+ thread_list = [get_thread_with_periodic_running_function(28800, aggregate_events, graceful_stop) for i in range(threads)]
96
+ [t.start() for t in thread_list]
93
97
 
94
98
  logging.info("waiting for interrupts")
95
99
  # Interruptible joins require a timeout.
96
- while threads[0].is_alive():
97
- [t.join(timeout=3.14) for t in threads]
100
+ while thread_list[0].is_alive():
101
+ [t.join(timeout=3.14) for t in thread_list]
@@ -1,4 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
1
  # Copyright European Organization for Nuclear Research (CERN) since 2012
3
2
  #
4
3
  # Licensed under the Apache License, Version 2.0 (the "License");