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");
@@ -14,43 +13,50 @@
14
13
  # limitations under the License.
15
14
 
16
15
  import logging
17
- from datetime import datetime, date, timedelta
16
+ from datetime import date, datetime, timedelta
18
17
  from string import Template
18
+ from typing import TYPE_CHECKING, Any, Literal, Optional, Union
19
19
 
20
20
  from requests import get
21
- from sqlalchemy import func, and_, or_, cast, BigInteger
22
- from sqlalchemy.orm import aliased
23
- from sqlalchemy.sql.expression import case, select
21
+ from sqlalchemy import BigInteger, and_, case, cast, false, func, or_, select
22
+ from sqlalchemy.orm import Session, aliased
24
23
 
25
- from rucio.common.config import config_get, config_get_int, config_get_bool
24
+ from rucio.common.config import config_get, config_get_bool, config_get_int
26
25
  from rucio.common.exception import (
27
- InsufficientTargetRSEs,
28
- RuleNotFound,
29
26
  DuplicateRule,
30
27
  InsufficientAccountLimit,
28
+ InsufficientTargetRSEs,
29
+ RuleNotFound,
31
30
  )
32
31
  from rucio.common.types import InternalAccount, InternalScope
33
32
  from rucio.core.lock import get_dataset_locks
34
- from rucio.core.rse import list_rse_attributes, get_rse_name, get_rse_vo
33
+ from rucio.core.rse import get_rse_name, get_rse_vo, list_rse_attributes
35
34
  from rucio.core.rse_expression_parser import parse_expression
36
35
  from rucio.core.rse_selector import RSESelector
37
- from rucio.core.rule import get_rule, add_rule, update_rule
36
+ from rucio.core.rule import add_rule, get_rule, update_rule
38
37
  from rucio.db.sqla import models
39
- from rucio.db.sqla.constants import DIDType, RuleState, RuleGrouping, LockState
40
- from rucio.db.sqla.session import transactional_session, read_session
38
+ from rucio.db.sqla.constants import DIDType, LockState, RuleGrouping, RuleState
39
+ from rucio.db.sqla.session import read_session, transactional_session
40
+
41
+ if TYPE_CHECKING:
42
+ from collections.abc import Mapping, Sequence
43
+
44
+ from sqlalchemy.engine import Row
45
+
46
+ from rucio.common.types import LoggerFunction
41
47
 
42
48
 
43
49
  @transactional_session
44
50
  def rebalance_rule(
45
- parent_rule,
46
- activity,
47
- rse_expression,
48
- priority,
49
- source_replica_expression="*\\bb8-enabled=false",
50
- comment=None,
51
+ parent_rule: "Mapping[str, Any]",
52
+ activity: str,
53
+ rse_expression: str,
54
+ priority: int,
55
+ source_replica_expression: str = "*\\bb8-enabled=false",
56
+ comment: Optional[str] = None,
51
57
  *,
52
- session,
53
- ):
58
+ session: Session,
59
+ ) -> Optional[list[str]]:
54
60
  """
55
61
  Rebalance a replication rule to a new RSE
56
62
  :param parent_rule: Replication rule to be rebalanced.
@@ -117,7 +123,10 @@ def rebalance_rule(
117
123
  return child_rule
118
124
 
119
125
 
120
- def __dump_url(rse_id, logger=logging.log):
126
+ def __dump_url(
127
+ rse_id: str,
128
+ logger: "LoggerFunction" = logging.log
129
+ ) -> Union[list[str], Literal[False]]:
121
130
  """
122
131
  getting potential urls of the dump over last week
123
132
  :param rse_id: RSE where the dump is released.
@@ -173,7 +182,11 @@ def __dump_url(rse_id, logger=logging.log):
173
182
  return urls
174
183
 
175
184
 
176
- def _list_rebalance_rule_candidates_dump(rse_id, mode=None, logger=logging.log):
185
+ def _list_rebalance_rule_candidates_dump(
186
+ rse_id: str,
187
+ mode: Optional[str] = None,
188
+ logger: "LoggerFunction" = logging.log
189
+ ) -> list[tuple]:
177
190
  """
178
191
  Download dump to temporary directory
179
192
  :param rse_id: RSE of the source.
@@ -185,11 +198,11 @@ def _list_rebalance_rule_candidates_dump(rse_id, mode=None, logger=logging.log):
185
198
  candidates = []
186
199
  rules = {}
187
200
  rse_dump_urls = __dump_url(rse_id=rse_id)
188
- rse_dump_urls.reverse()
189
201
  resp = None
190
202
  if not rse_dump_urls:
191
203
  logger(logging.DEBUG, "URL of the dump was not built from template.")
192
204
  return candidates
205
+ rse_dump_urls.reverse()
193
206
  success = False
194
207
  while not success and len(rse_dump_urls):
195
208
  url = rse_dump_urls.pop()
@@ -251,7 +264,12 @@ def _list_rebalance_rule_candidates_dump(rse_id, mode=None, logger=logging.log):
251
264
 
252
265
 
253
266
  @transactional_session
254
- def list_rebalance_rule_candidates(rse_id, mode=None, *, session=None):
267
+ def list_rebalance_rule_candidates(
268
+ rse_id: str,
269
+ mode: Optional[str] = None,
270
+ *,
271
+ session: Optional[Session] = None
272
+ ) -> Union[list[tuple], list["Row[tuple]"]]:
255
273
  """
256
274
  List the rebalance rule candidates based on the agreed on specification
257
275
  :param rse_id: RSE of the source.
@@ -288,10 +306,8 @@ def list_rebalance_rule_candidates(rse_id, mode=None, *, session=None):
288
306
  min_expires_date_in_days = datetime.utcnow() + timedelta(
289
307
  days=min_expires_date_in_days
290
308
  )
291
- expiration_clause = or_(
292
- models.ReplicationRule.expires_at > min_expires_date_in_days,
293
- models.ReplicationRule.expires_at.is_(None),
294
- )
309
+ expiration_clause = or_(models.ReplicationRule.expires_at > min_expires_date_in_days,
310
+ models.ReplicationRule.expires_at.is_(None))
295
311
  rule_clause.append(expiration_clause)
296
312
 
297
313
  # Only move rules which were created more than <min_created_days> days ago
@@ -391,105 +407,89 @@ def list_rebalance_rule_candidates(rse_id, mode=None, *, session=None):
391
407
  expiration_time=3600,
392
408
  )
393
409
  if only_move_closed_did:
394
- did_clause.append(models.DataIdentifier.is_open == False) # NOQA
410
+ did_clause.append(models.DataIdentifier.is_open == false())
395
411
 
396
412
  # Now build the query
397
413
  external_dsl = aliased(models.DatasetLock)
398
- count_locks = (
399
- select(func.count())
400
- .where(
401
- and_(
402
- external_dsl.scope == models.DatasetLock.scope,
403
- external_dsl.name == models.DatasetLock.name,
404
- external_dsl.rse_id == models.DatasetLock.rse_id,
405
- )
406
- )
407
- .as_scalar()
408
- )
409
- query = (
410
- session.query(
411
- models.DatasetLock.scope,
412
- models.DatasetLock.name,
413
- models.ReplicationRule.id,
414
- models.ReplicationRule.rse_expression,
415
- models.ReplicationRule.subscription_id,
416
- models.DataIdentifier.bytes,
417
- models.DataIdentifier.length,
418
- case(
419
- (
420
- or_(
421
- models.DatasetLock.length < 1,
422
- models.DatasetLock.length.is_(None),
423
- ),
424
- 0,
425
- ),
426
- else_=cast(
427
- models.DatasetLock.bytes / models.DatasetLock.length, BigInteger
428
- ),
429
- ),
430
- )
431
- .join(
432
- models.ReplicationRule,
433
- models.ReplicationRule.id == models.DatasetLock.rule_id,
434
- )
435
- .join(
436
- models.DataIdentifier,
437
- and_(
438
- models.DatasetLock.scope == models.DataIdentifier.scope,
439
- models.DatasetLock.name == models.DataIdentifier.name,
414
+ count_locks = select(
415
+ func.count()
416
+ ).select_from(
417
+ models.DatasetLock
418
+ ).where(
419
+ and_(external_dsl.scope == models.DatasetLock.scope,
420
+ external_dsl.name == models.DatasetLock.name,
421
+ external_dsl.rse_id == models.DatasetLock.rse_id)
422
+ ).scalar_subquery()
423
+
424
+ stmt = select(
425
+ models.DatasetLock.scope,
426
+ models.DatasetLock.name,
427
+ models.ReplicationRule.id,
428
+ models.ReplicationRule.rse_expression,
429
+ models.ReplicationRule.subscription_id,
430
+ models.DataIdentifier.bytes,
431
+ models.DataIdentifier.length,
432
+ case(
433
+ (
434
+ or_(models.DatasetLock.length < 1,
435
+ models.DatasetLock.length.is_(None)),
436
+ 0
440
437
  ),
441
- )
442
- .filter(models.DatasetLock.rse_id == rse_id)
443
- .filter(and_(*rule_clause))
444
- .filter(and_(*did_clause))
445
- .filter(
446
- case(
447
- (
448
- or_(
449
- models.DatasetLock.length < 1,
450
- models.DatasetLock.length.is_(None),
451
- ),
452
- 0,
453
- ),
454
- else_=cast(
455
- models.DatasetLock.bytes / models.DatasetLock.length, BigInteger
456
- ),
438
+ else_=cast(
439
+ models.DatasetLock.bytes / models.DatasetLock.length, BigInteger
457
440
  )
458
- > 1000000000
459
441
  )
460
- .filter(count_locks == 1)
461
- )
462
- summary = query.order_by(
442
+ ).join(
443
+ models.ReplicationRule,
444
+ models.ReplicationRule.id == models.DatasetLock.rule_id
445
+ ).join(
446
+ models.DataIdentifier,
447
+ and_(models.DatasetLock.scope == models.DataIdentifier.scope,
448
+ models.DatasetLock.name == models.DataIdentifier.name)
449
+ ).where(
450
+ and_(models.DatasetLock.rse_id == rse_id,
451
+ *rule_clause,
452
+ *did_clause,
453
+ case(
454
+ (
455
+ or_(models.DatasetLock.length < 1,
456
+ models.DatasetLock.length.is_(None)),
457
+ 0
458
+ ),
459
+ else_=cast(
460
+ models.DatasetLock.bytes / models.DatasetLock.length, BigInteger
461
+ )
462
+ ) > 1000000000,
463
+ count_locks == 1)
464
+ ).order_by(
463
465
  case(
464
466
  (
465
- or_(
466
- models.DatasetLock.length < 1,
467
- models.DatasetLock.length.is_(None),
468
- ),
469
- 0,
467
+ or_(models.DatasetLock.length < 1,
468
+ models.DatasetLock.length.is_(None)),
469
+ 0
470
470
  ),
471
471
  else_=cast(
472
472
  models.DatasetLock.bytes / models.DatasetLock.length, BigInteger
473
- ),
473
+ )
474
474
  ),
475
- models.DatasetLock.accessed_at,
476
- ).all()
477
- return summary
475
+ models.DatasetLock.accessed_at
476
+ )
477
+ return list(session.execute(stmt).all()) # type: ignore (session could be None)
478
478
 
479
479
 
480
480
  @read_session
481
481
  def select_target_rse(
482
- parent_rule,
483
- current_rse_id,
484
- rse_expression,
485
- subscription_id,
486
- rse_attributes,
487
- other_rses=[],
488
- exclude_expression=None,
489
- force_expression=None,
482
+ parent_rule: "Mapping[str, Any]",
483
+ current_rse_id: str,
484
+ rse_expression: str,
485
+ subscription_id: str,
486
+ rse_attributes: "Mapping[str, Any]",
487
+ other_rses: Optional["Sequence[str]"] = None,
488
+ exclude_expression: Optional[str] = None,
489
+ force_expression: Optional[str] = None,
490
490
  *,
491
- session=None,
492
- ):
491
+ session: Optional[Session] = None,
492
+ ) -> str:
493
493
  """
494
494
  Select a new target RSE for a rebalanced rule.
495
495
  :param parent_rule rule that is rebalanced.
@@ -504,6 +504,7 @@ def select_target_rse(
504
504
  :returns: New RSE expression.
505
505
  """
506
506
 
507
+ other_rses = other_rses or []
507
508
  current_rse = get_rse_name(rse_id=current_rse_id)
508
509
  current_rse_expr = current_rse
509
510
  # if parent rule has a vo, enforce it
@@ -577,20 +578,20 @@ def select_target_rse(
577
578
 
578
579
  @transactional_session
579
580
  def rebalance_rse(
580
- rse_id,
581
- max_bytes=1e9,
582
- max_files=None,
583
- dry_run=False,
584
- exclude_expression=None,
585
- comment=None,
586
- force_expression=None,
587
- mode=None,
588
- priority=3,
589
- source_replica_expression="*\\bb8-enabled=false",
581
+ rse_id: str,
582
+ max_bytes: float = 1e9,
583
+ max_files: Optional[int] = None,
584
+ dry_run: bool = False,
585
+ exclude_expression: Optional[str] = None,
586
+ comment: Optional[str] = None,
587
+ force_expression: Optional[str] = None,
588
+ mode: Optional[str] = None,
589
+ priority: int = 3,
590
+ source_replica_expression: str = "*\\bb8-enabled=false",
590
591
  *,
591
- session=None,
592
- logger=logging.log,
593
- ):
592
+ session: Optional[Session] = None,
593
+ logger: "LoggerFunction" = logging.log,
594
+ ) -> list[tuple]:
594
595
  """
595
596
  Rebalance data from an RSE
596
597
  :param rse_id: RSE to rebalance data from.
@@ -705,7 +706,7 @@ def rebalance_rse(
705
706
  except Exception as error:
706
707
  logger(
707
708
  logging.ERROR,
708
- "Exception %s occured while rebalancing %s:%s, rule_id: %s!",
709
+ "Exception %s occurred while rebalancing %s:%s, rule_id: %s!",
709
710
  str(error),
710
711
  scope,
711
712
  name,
@@ -723,38 +724,34 @@ def rebalance_rse(
723
724
 
724
725
 
725
726
  @read_session
726
- def get_active_locks(*, session=None):
727
- locks_dict = {}
728
- rule_ids = (
729
- session.query(models.ReplicationRule.id)
730
- .filter(
731
- or_(
732
- models.ReplicationRule.state == RuleState.REPLICATING,
733
- models.ReplicationRule.state == RuleState.STUCK,
734
- ),
735
- models.ReplicationRule.comments == "Background rebalancing",
736
- )
737
- .all()
727
+ def get_active_locks(
728
+ *,
729
+ session: Optional[Session] = None
730
+ ) -> dict[str, dict[str, int]]:
731
+ locks_dict: dict[str, dict[str, int]] = {}
732
+ stmt = select(
733
+ models.ReplicationRule.id
734
+ ).where(
735
+ and_(or_(models.ReplicationRule.state == RuleState.REPLICATING,
736
+ models.ReplicationRule.state == RuleState.STUCK),
737
+ models.ReplicationRule.comments == "Background rebalancing")
738
738
  )
739
- for row in rule_ids:
740
- rule_id = row[0]
741
- query = (
742
- session.query(
743
- func.count(),
744
- func.sum(models.ReplicaLock.bytes),
745
- models.ReplicaLock.state,
746
- models.ReplicaLock.rse_id,
747
- )
748
- .filter(
749
- and_(
750
- models.ReplicaLock.rule_id == rule_id,
751
- models.ReplicaLock.state != LockState.OK,
752
- )
753
- )
754
- .group_by(models.ReplicaLock.state, models.ReplicaLock.rse_id)
739
+ for rule_id in session.execute(stmt).scalars().all(): # type: ignore (session could be None)
740
+ stmt = select(
741
+ func.count(),
742
+ func.sum(models.ReplicaLock.bytes),
743
+ models.ReplicaLock.state,
744
+ models.ReplicaLock.rse_id
745
+ ).select_from(
746
+ models.ReplicaLock
747
+ ).where(
748
+ and_(models.ReplicaLock.rule_id == rule_id,
749
+ models.ReplicaLock.state != LockState.OK)
750
+ ).group_by(
751
+ models.ReplicaLock.state,
752
+ models.ReplicaLock.rse_id
755
753
  )
756
- for lock in query.all():
757
- cnt, size, _, rse_id = lock
754
+ for cnt, size, _, rse_id in session.execute(stmt).all(): # type: ignore (session could be None)
758
755
  if rse_id not in locks_dict:
759
756
  locks_dict[rse_id] = {"bytes": 0, "locks": 0}
760
757
  locks_dict[rse_id]["locks"] += cnt
@@ -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,9 +16,10 @@
17
16
  This script is to be used to background rebalance ATLAS t2 datadisks
18
17
  """
19
18
 
20
- from sqlalchemy import or_
19
+ from sqlalchemy import and_, or_, select
21
20
 
22
- from rucio.core.rse import get_rse_usage, get_rse_attribute
21
+ from rucio.common.constants import RseAttr
22
+ from rucio.core.rse import get_rse_attribute, get_rse_usage
23
23
  from rucio.core.rse_expression_parser import parse_expression
24
24
  from rucio.daemons.bb8.common import rebalance_rse
25
25
  from rucio.db.sqla import models
@@ -34,7 +34,7 @@ total_rebalance_volume = 0
34
34
 
35
35
 
36
36
  # groupdisks
37
- def group_space(site):
37
+ def group_space(site: str) -> int:
38
38
  """
39
39
  groupdisks of given site
40
40
  contributing to primaries
@@ -60,7 +60,7 @@ total_secondary = 0
60
60
  total_total = 0
61
61
  global_ratio = float(0)
62
62
  for rse in rses:
63
- site_name = get_rse_attribute(rse['id'], 'site')
63
+ site_name = get_rse_attribute(rse['id'], RseAttr.SITE)
64
64
  rse['groupdisk'] = group_space(site_name)
65
65
  rse['primary'] = get_rse_usage(rse_id=rse['id'], source='rucio')[0]['used'] - get_rse_usage(rse_id=rse['id'], source='expired')[0]['used']
66
66
  rse['primary'] += rse['groupdisk']
@@ -81,12 +81,18 @@ rses_over_ratio = sorted([rse for rse in rses if rse['ratio'] > global_ratio + g
81
81
  rses_under_ratio = sorted([rse for rse in rses if rse['ratio'] < global_ratio - global_ratio * tolerance], key=lambda k: k['ratio'], reverse=False)
82
82
 
83
83
  session = get_session()
84
- active_rses = session.query(models.ReplicationRule.rse_expression).filter(or_(models.ReplicationRule.state == RuleState.REPLICATING, models.ReplicationRule.state == RuleState.STUCK),
85
- models.ReplicationRule.comments == 'T2 Background rebalancing').group_by(models.ReplicationRule.rse_expression).all()
86
-
84
+ stmt = select(
85
+ models.ReplicationRule.rse_expression
86
+ ).where(
87
+ and_(or_(models.ReplicationRule.state == RuleState.REPLICATING,
88
+ models.ReplicationRule.state == RuleState.STUCK),
89
+ models.ReplicationRule.comments == 'T2 Background rebalancing')
90
+ ).group_by(
91
+ models.ReplicationRule.rse_expression
92
+ )
87
93
  # Excluding RSEs
88
94
  print('Excluding RSEs as destination which have active Background Rebalancing rules:')
89
- for rse in active_rses:
95
+ for rse in session.execute(stmt).all():
90
96
  print(' %s' % (rse[0]))
91
97
  for des in rses_under_ratio:
92
98
  des_as_expr = des['rse']
@@ -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,9 +16,10 @@
17
16
  This script is to be used to background rebalance ATLAS t2 datadisks
18
17
  """
19
18
 
20
- from sqlalchemy import or_
19
+ from sqlalchemy import and_, or_, select
21
20
 
22
- from rucio.core.rse import get_rse_usage, get_rse_attribute
21
+ from rucio.common.constants import RseAttr
22
+ from rucio.core.rse import get_rse_attribute, get_rse_usage
23
23
  from rucio.core.rse_expression_parser import parse_expression
24
24
  from rucio.daemons.bb8.common import rebalance_rse
25
25
  from rucio.db.sqla import models
@@ -34,7 +34,7 @@ total_rebalance_volume = 0
34
34
 
35
35
 
36
36
  # groupdisks
37
- def group_space(site):
37
+ def group_space(site: str) -> int:
38
38
  """
39
39
  groupdisks of given site
40
40
  contributing to primaries
@@ -60,7 +60,7 @@ total_secondary = 0
60
60
  total_total = 0
61
61
  global_ratio = float(0)
62
62
  for rse in rses:
63
- site_name = get_rse_attribute(rse['id'], 'site')
63
+ site_name = get_rse_attribute(rse['id'], RseAttr.SITE)
64
64
  rse['groupdisk'] = group_space(site_name)
65
65
  rse['primary'] = get_rse_usage(rse_id=rse['id'], source='rucio')[0]['used'] - get_rse_usage(rse_id=rse['id'], source='expired')[0]['used']
66
66
  rse['primary'] += rse['groupdisk']
@@ -81,12 +81,19 @@ rses_over_ratio = sorted([rse for rse in rses if rse['ratio'] > global_ratio + g
81
81
  rses_under_ratio = sorted([rse for rse in rses if rse['ratio'] < global_ratio - global_ratio * tolerance], key=lambda k: k['ratio'], reverse=False)
82
82
 
83
83
  session = get_session()
84
- active_rses = session.query(models.ReplicationRule.rse_expression).filter(or_(models.ReplicationRule.state == RuleState.REPLICATING, models.ReplicationRule.state == RuleState.STUCK),
85
- models.ReplicationRule.comments == 'T2 Background rebalancing').group_by(models.ReplicationRule.rse_expression).all()
84
+ stmt = select(
85
+ models.ReplicationRule.rse_expression
86
+ ).where(
87
+ and_(or_(models.ReplicationRule.state == RuleState.REPLICATING,
88
+ models.ReplicationRule.state == RuleState.STUCK),
89
+ models.ReplicationRule.comments == 'T2 Background rebalancing')
90
+ ).group_by(
91
+ models.ReplicationRule.rse_expression
92
+ )
86
93
 
87
94
  # Excluding RSEs
88
95
  print('Excluding RSEs as destination which have active Background Rebalancing rules:')
89
- for rse in active_rses:
96
+ for rse in session.execute(stmt).all():
90
97
  print(' %s' % (rse[0]))
91
98
  for des in rses_under_ratio:
92
99
  des_as_expr = des['rse']
@@ -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");
@@ -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");
@@ -16,6 +15,7 @@
16
15
  import logging
17
16
  from operator import itemgetter
18
17
  from random import shuffle
18
+ from typing import TYPE_CHECKING, Any
19
19
 
20
20
  from rucio.common.exception import DataIdentifierNotFound
21
21
  from rucio.core.did import get_did
@@ -24,6 +24,9 @@ from rucio.daemons.c3po.collectors.agis import MappingCollector
24
24
  from rucio.daemons.c3po.collectors.workload import WorkloadCollector
25
25
  from rucio.db.sqla.constants import ReplicaState
26
26
 
27
+ if TYPE_CHECKING:
28
+ from rucio.common.types import InternalScope
29
+
27
30
 
28
31
  class PlacementAlgorithm:
29
32
  def __init__(self):
@@ -31,20 +34,20 @@ class PlacementAlgorithm:
31
34
  self._wc = WorkloadCollector()
32
35
  self.__setup_penalties()
33
36
 
34
- def __setup_penalties(self):
37
+ def __setup_penalties(self) -> None:
35
38
  self._penalties = {}
36
39
  for panda_site in self._wc.get_sites():
37
40
  site = self._mc.panda_to_site(panda_site)
38
41
  self._penalties[site] = 0.1
39
42
 
40
- def __update_penalties(self):
43
+ def __update_penalties(self) -> None:
41
44
  for site, penalty in self._penalties.items():
42
45
  if penalty > 0.1:
43
46
  self._penalties[site] = penalty - 0.1
44
47
 
45
- def place(self, did):
48
+ def place(self, did: tuple['InternalScope', str]) -> dict[str, Any]:
46
49
  self.__update_penalties()
47
- decision = {'did': '{}:{}'.format(did['scope'].internal, did['name'])}
50
+ decision: dict[str, Any] = {'did': '{}:{}'.format(did['scope'].internal, did['name'])} # type: ignore (did is treated as a dict here, and as a tuple everywhere else)
48
51
  try:
49
52
  meta = get_did(did[0], did[1])
50
53
  except DataIdentifierNotFound:
@@ -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");
@@ -15,18 +14,22 @@
15
14
 
16
15
  import logging
17
16
  from operator import itemgetter
17
+ from typing import TYPE_CHECKING, Any
18
18
 
19
19
  from rucio.common.config import config_get, config_get_int
20
20
  from rucio.common.exception import DataIdentifierNotFound
21
21
  from rucio.core.did import get_did
22
22
  from rucio.core.replica import list_dataset_replicas
23
- from rucio.core.rse import list_rse_attributes, get_rse_name
23
+ from rucio.core.rse import get_rse_name, list_rse_attributes
24
24
  from rucio.core.rse_expression_parser import parse_expression
25
25
  from rucio.daemons.c3po.collectors.free_space import FreeSpaceCollector
26
26
  from rucio.daemons.c3po.utils.dataset_cache import DatasetCache
27
27
  from rucio.daemons.c3po.utils.popularity import get_popularity
28
28
  from rucio.db.sqla.constants import ReplicaState
29
29
 
30
+ if TYPE_CHECKING:
31
+ from rucio.common.types import InternalScope
32
+
30
33
 
31
34
  class PlacementAlgorithm:
32
35
  """
@@ -45,20 +48,20 @@ class PlacementAlgorithm:
45
48
 
46
49
  self.__setup_penalties()
47
50
 
48
- def __setup_penalties(self):
51
+ def __setup_penalties(self) -> None:
49
52
  self._penalties = {}
50
53
  for rse_id in self._rses:
51
54
  self._penalties[rse_id] = 1.0
52
55
 
53
- def __update_penalties(self):
56
+ def __update_penalties(self) -> None:
54
57
  for rse_id, penalty in self._penalties.items():
55
58
  if penalty > 1.0:
56
59
  self._penalties[rse_id] = penalty - 1
57
60
 
58
- def place(self, did):
61
+ def place(self, did: tuple['InternalScope', str]) -> dict[str, Any]:
59
62
  self.__update_penalties()
60
- decision = {'did': '{}:{}'.format(did[0].internal, did[1])}
61
- if (not did[0].external.startswith('data')) and (not did[0].external.startswith('mc')):
63
+ decision: dict[str, Any] = {'did': '{}:{}'.format(did[0].internal, did[1])}
64
+ if (did[0].external is not None) and (not did[0].external.startswith('data')) and (not did[0].external.startswith('mc')):
62
65
  decision['error_reason'] = 'not a data or mc dataset'
63
66
  return decision
64
67