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");
@@ -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.expiring_dataset_cache import ExpiringDatasetCache
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,24 +48,24 @@ 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])}
63
+ decision: dict[str, Any] = {'did': '{}:{}'.format(did[0].internal, did[1])}
61
64
  if (self._added_cache.check_dataset(decision['did'])):
62
65
  decision['error_reason'] = 'already added replica for this did in the last 24h'
63
66
  return decision
64
67
 
65
- if (not did[0].external.startswith('data')) and (not did[0].external.startswith('mc')):
68
+ if (did[0].external is not None) and (not did[0].external.startswith('data')) and (not did[0].external.startswith('mc')):
66
69
  decision['error_reason'] = 'not a data or mc dataset'
67
70
  return decision
68
71
 
@@ -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,12 +14,14 @@
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
+ from rucio.common.constants import RseAttr
20
21
  from rucio.common.exception import DataIdentifierNotFound
21
22
  from rucio.core.did import get_did
22
23
  from rucio.core.replica import list_dataset_replicas
23
- from rucio.core.rse import list_rse_attributes, get_rse, get_rse_name
24
+ from rucio.core.rse import get_rse, get_rse_name, list_rse_attributes
24
25
  from rucio.core.rse_expression_parser import parse_expression
25
26
  from rucio.daemons.c3po.collectors.free_space import FreeSpaceCollector
26
27
  from rucio.daemons.c3po.collectors.network_metrics import NetworkMetricsCollector
@@ -30,12 +31,26 @@ from rucio.daemons.c3po.utils.popularity import get_popularity
30
31
  from rucio.daemons.c3po.utils.timeseries import RedisTimeSeries
31
32
  from rucio.db.sqla.constants import ReplicaState
32
33
 
34
+ if TYPE_CHECKING:
35
+ from rucio.common.types import InternalScope
36
+
33
37
 
34
38
  class PlacementAlgorithm:
35
39
  """
36
40
  Placement algorithm that focusses on free space on T2 DATADISK RSEs. It incorporates network metrics for placement decisions.
37
41
  """
38
- def __init__(self, datatypes, dest_rse_expr, max_bytes_hour, max_files_hour, max_bytes_hour_rse, max_files_hour_rse, min_popularity, min_recent_requests, max_replicas):
42
+ def __init__(
43
+ self,
44
+ datatypes: str,
45
+ dest_rse_expr: str,
46
+ max_bytes_hour: int,
47
+ max_files_hour: int,
48
+ max_bytes_hour_rse: int,
49
+ max_files_hour_rse: int,
50
+ min_popularity: int,
51
+ min_recent_requests: int,
52
+ max_replicas: int
53
+ ):
39
54
  self._fsc = FreeSpaceCollector()
40
55
  self._nmc = NetworkMetricsCollector()
41
56
  self._added_cache = ExpiringDatasetCache(config_get('c3po', 'redis_host'), config_get_int('c3po', 'redis_port'), timeout=86400)
@@ -61,14 +76,14 @@ class PlacementAlgorithm:
61
76
  rse_attrs = list_rse_attributes(rse_id=rse['id'])
62
77
  rse_attrs['rse_id'] = rse['id']
63
78
  self._rses[rse['id']] = rse_attrs
64
- self._sites[rse_attrs['site']] = rse_attrs
79
+ self._sites[rse_attrs[RseAttr.SITE]] = rse_attrs
65
80
 
66
81
  self._dst_penalties = {}
67
82
  self._src_penalties = {}
68
83
 
69
84
  self._print_params()
70
85
 
71
- def _print_params(self):
86
+ def _print_params(self) -> None:
72
87
  logging.debug('Parameter Overview:')
73
88
  logging.debug('Algorithm: t2_free_space_only_pop_with_network')
74
89
  logging.debug('Datatypes: %s' % ','.join(self._datatypes))
@@ -77,7 +92,7 @@ class PlacementAlgorithm:
77
92
  logging.debug('Min recent requests / Min popularity: %d / %d' % (self._min_recent_requests, self._min_popularity))
78
93
  logging.debug('Max existing replicas: %d' % self._max_replicas)
79
94
 
80
- def __update_penalties(self):
95
+ def __update_penalties(self) -> None:
81
96
  for rse_id, penalty in self._dst_penalties.items():
82
97
  if penalty < 100.0:
83
98
  self._dst_penalties[rse_id] += 10.0
@@ -86,13 +101,13 @@ class PlacementAlgorithm:
86
101
  if penalty < 100.0:
87
102
  self._src_penalties[rse_id] += 10.0
88
103
 
89
- def check_did(self, did):
90
- decision = {'did': '{}:{}'.format(did[0].internal, did[1])}
104
+ def check_did(self, did: tuple['InternalScope', str]) -> dict[str, Any]:
105
+ decision: dict[str, Any] = {'did': '{}:{}'.format(did[0].internal, did[1])}
91
106
  if (self._added_cache.check_dataset(decision['did'])):
92
107
  decision['error_reason'] = 'already added replica for this did in the last 24h'
93
108
  return decision
94
109
 
95
- if (not did[0].external.startswith('data')) and (not did[0].external.startswith('mc')):
110
+ if (did[0].external is not None) and (not did[0].external.startswith('data')) and (not did[0].external.startswith('mc')):
96
111
  decision['error_reason'] = 'not a data or mc dataset'
97
112
  return decision
98
113
 
@@ -141,13 +156,13 @@ class PlacementAlgorithm:
141
156
  decision['error_reason'] = 'problems connecting to ES'
142
157
  return decision
143
158
 
144
- if (last_accesses < self._min_recent_requests) and (pop < self._min_popularity):
159
+ if (last_accesses < self._min_recent_requests) and (decision['popularity'] < self._min_popularity):
145
160
  decision['error_reason'] = 'did not popular enough'
146
161
  return decision
147
162
 
148
163
  return decision
149
164
 
150
- def place(self, did):
165
+ def place(self, did: tuple['InternalScope', str]) -> dict[str, Any]:
151
166
  self.__update_penalties()
152
167
  self._added_bytes.trim()
153
168
  self._added_files.trim()
@@ -166,10 +181,10 @@ class PlacementAlgorithm:
166
181
  for rep in reps:
167
182
  rse_attr = list_rse_attributes(rep['rse_id'])
168
183
  src_rse_id = rep['rse_id']
169
- if 'site' not in rse_attr:
184
+ if RseAttr.SITE not in rse_attr:
170
185
  continue
171
186
 
172
- src_site = rse_attr['site']
187
+ src_site = rse_attr[RseAttr.SITE]
173
188
  src_rse_info = get_rse(rse_id=src_rse_id)
174
189
 
175
190
  if 'type' not in rse_attr:
@@ -189,10 +204,10 @@ class PlacementAlgorithm:
189
204
  net_metrics = self._nmc.getMbps(src_site, metric_type)
190
205
  if net_metrics:
191
206
  break
192
- if len(net_metrics) == 0:
207
+ if len(net_metrics) == 0: # type: ignore
193
208
  continue
194
209
  available_reps[src_rse_id] = {}
195
- for dst_site, mbps in net_metrics.items():
210
+ for dst_site, mbps in net_metrics.items(): # type: ignore
196
211
  if src_site == dst_site:
197
212
  continue
198
213
  if dst_site in self._sites:
@@ -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");
@@ -24,7 +23,7 @@ from json import dumps
24
23
  from queue import Queue
25
24
  from threading import Event, Thread
26
25
  from time import sleep
27
- from typing import TYPE_CHECKING
26
+ from typing import TYPE_CHECKING, Optional
28
27
  from uuid import uuid4
29
28
 
30
29
  from requests import post
@@ -43,13 +42,17 @@ from rucio.daemons.c3po.collectors.workload import WorkloadCollector
43
42
 
44
43
  if TYPE_CHECKING:
45
44
  from types import FrameType
46
- from typing import Optional
47
45
 
48
46
  GRACEFUL_STOP = Event()
49
47
  DAEMON_NAME = 'c3po'
50
48
 
51
49
 
52
- def read_free_space(once=False, thread=0, waiting_time=1800, sleep_time=10):
50
+ def read_free_space(
51
+ once: bool = False,
52
+ thread: int = 0,
53
+ waiting_time: int = 1800,
54
+ sleep_time: int = 10
55
+ ) -> None:
53
56
  """
54
57
  Thread to collect the space usage information for RSEs.
55
58
  """
@@ -66,7 +69,12 @@ def read_free_space(once=False, thread=0, waiting_time=1800, sleep_time=10):
66
69
  timer = 0
67
70
 
68
71
 
69
- def read_workload(once=False, thread=0, waiting_time=1800, sleep_time=10):
72
+ def read_workload(
73
+ once: bool = False,
74
+ thread: int = 0,
75
+ waiting_time: int = 1800,
76
+ sleep_time: int = 10
77
+ ) -> None:
70
78
  """
71
79
  Thread to collect the workload information from PanDA.
72
80
  """
@@ -83,7 +91,12 @@ def read_workload(once=False, thread=0, waiting_time=1800, sleep_time=10):
83
91
  timer = 0
84
92
 
85
93
 
86
- def print_workload(once=False, thread=0, waiting_time=600, sleep_time=10):
94
+ def print_workload(
95
+ once: bool = False,
96
+ thread: int = 0,
97
+ waiting_time: int = 600,
98
+ sleep_time: int = 10
99
+ ) -> None:
87
100
  """
88
101
  Thread to regularly output the workload to logs for debugging.
89
102
  """
@@ -101,7 +114,13 @@ def print_workload(once=False, thread=0, waiting_time=600, sleep_time=10):
101
114
  timer = 0
102
115
 
103
116
 
104
- def read_dids(once=False, thread=0, did_collector=None, waiting_time=60, sleep_time=10):
117
+ def read_dids(
118
+ once: bool = False,
119
+ thread: int = 0,
120
+ did_collector: Optional[JediDIDCollector] = None,
121
+ waiting_time: int = 60,
122
+ sleep_time: int = 10
123
+ ) -> None:
105
124
  """
106
125
  Thread to collect DIDs for the placement algorithm.
107
126
  """
@@ -112,33 +131,41 @@ def read_dids(once=False, thread=0, did_collector=None, waiting_time=60, sleep_t
112
131
  sleep(sleep_time)
113
132
  continue
114
133
 
115
- did_collector.get_dids()
134
+ if did_collector is not None:
135
+ did_collector.get_dids()
116
136
  timer = 0
117
137
 
118
138
 
119
- def add_rule(client, did, src_rse, dst_rse):
139
+ def add_rule(
140
+ client: Client,
141
+ did: dict[str, str],
142
+ src_rse: str,
143
+ dst_rse: str
144
+ ) -> None:
120
145
  logging.debug('add rule for %s from %s to %s' % (did, src_rse, dst_rse))
121
146
  r = client.add_replication_rule([did, ], 1, dst_rse, lifetime=604800, account='c3po', source_replica_expression=src_rse, activity='Data Brokering', asynchronous=True)
122
147
  logging.debug(r)
123
148
 
124
149
 
125
- def place_replica(once=False,
126
- thread=0,
127
- did_queue=None,
128
- waiting_time=100,
129
- dry_run=False,
130
- sampling=False,
131
- algorithms='t2_free_space_only_pop_with_network',
132
- datatypes='NTUP,DAOD',
133
- dest_rse_expr='type=DATADISK',
134
- max_bytes_hour=100000000000000,
135
- max_files_hour=100000,
136
- max_bytes_hour_rse=50000000000000,
137
- max_files_hour_rse=10000,
138
- min_popularity=8,
139
- min_recent_requests=5,
140
- max_replicas=5,
141
- sleep_time=10):
150
+ def place_replica(
151
+ did_queue: Queue,
152
+ once: bool = False,
153
+ thread: int = 0,
154
+ waiting_time: int = 100,
155
+ dry_run: bool = False,
156
+ sampling: bool = False,
157
+ algorithms: str = 't2_free_space_only_pop_with_network',
158
+ datatypes: str = 'NTUP,DAOD',
159
+ dest_rse_expr: str = 'type=DATADISK',
160
+ max_bytes_hour: int = 100000000000000,
161
+ max_files_hour: int = 100000,
162
+ max_bytes_hour_rse: int = 50000000000000,
163
+ max_files_hour_rse: int = 10000,
164
+ min_popularity: int = 8,
165
+ min_recent_requests: int = 5,
166
+ max_replicas: int = 5,
167
+ sleep_time: int = 10
168
+ ) -> None:
142
169
  """
143
170
  Thread to run the placement algorithm to decide if and where to put new replicas.
144
171
  """
@@ -149,17 +176,17 @@ def place_replica(once=False,
149
176
  if 'algorithms' in c3po_options:
150
177
  algorithms = config_get('c3po', 'algorithms')
151
178
 
152
- algorithms = algorithms.split(',')
179
+ algorithms_list = algorithms.split(',')
153
180
 
154
181
  if not dry_run:
155
- if len(algorithms) != 1:
182
+ if len(algorithms_list) != 1:
156
183
  logging.error('Multiple algorithms are only allowed in dry_run mode')
157
184
  return
158
185
  client = Client(auth_type='x509_proxy', account='c3po', creds={'client_proxy': '/opt/rucio/etc/ddmadmin.long.proxy'})
159
186
 
160
187
  vo = client.vo
161
188
  instances = {}
162
- for algorithm in algorithms:
189
+ for algorithm in algorithms_list:
163
190
  module_path = 'rucio.daemons.c3po.algorithms.' + algorithm
164
191
  module = __import__(module_path, globals(), locals(), ['PlacementAlgorithm'])
165
192
  instance = module.PlacementAlgorithm(datatypes, dest_rse_expr, max_bytes_hour, max_files_hour, max_bytes_hour_rse, max_files_hour_rse, min_popularity, min_recent_requests, max_replicas)
@@ -245,7 +272,7 @@ def place_replica(once=False,
245
272
  if (not dry_run) and create_rule:
246
273
  # DO IT!
247
274
  try:
248
- add_rule(client, {'scope': did[0].external, 'name': did[1]}, decision.get('source_rse'), decision.get('destination_rse'))
275
+ add_rule(client, {'scope': did[0].external, 'name': did[1]}, decision.get('source_rse'), decision.get('destination_rse')) # type: ignore
249
276
  except exception.RucioException as e:
250
277
  logging.debug(e)
251
278
 
@@ -254,34 +281,36 @@ def place_replica(once=False,
254
281
  logging.critical(e)
255
282
 
256
283
 
257
- def stop(signum: "Optional[int]" = None, frame: "Optional[FrameType]" = None) -> None:
284
+ def stop(signum: Optional[int] = None, frame: Optional['FrameType'] = None) -> None:
258
285
  """
259
286
  Graceful exit.
260
287
  """
261
288
  GRACEFUL_STOP.set()
262
289
 
263
290
 
264
- def run(once=False,
265
- threads=1,
266
- only_workload=False,
267
- dry_run=False,
268
- sampling=False,
269
- algorithms='t2_free_space_only_pop_with_network',
270
- datatypes='NTUP,DAOD',
271
- dest_rse_expr='type=DATADISK',
272
- max_bytes_hour=100000000000000,
273
- max_files_hour=100000,
274
- max_bytes_hour_rse=50000000000000,
275
- max_files_hour_rse=10000,
276
- min_popularity=8,
277
- min_recent_requests=5,
278
- max_replicas=5,
279
- waiting_time_read_free_space=1800,
280
- waiting_time_read_workload=1800,
281
- waiting_time_print_workload=600,
282
- waiting_time_read_dids=60,
283
- waiting_time_place_replica=100,
284
- sleep_time=10):
291
+ def run(
292
+ once: bool = False,
293
+ threads: int = 1,
294
+ only_workload: bool = False,
295
+ dry_run: bool = False,
296
+ sampling: bool = False,
297
+ algorithms: str = 't2_free_space_only_pop_with_network',
298
+ datatypes: str = 'NTUP,DAOD',
299
+ dest_rse_expr: str = 'type=DATADISK',
300
+ max_bytes_hour: int = 100000000000000,
301
+ max_files_hour: int = 100000,
302
+ max_bytes_hour_rse: int = 50000000000000,
303
+ max_files_hour_rse: int = 10000,
304
+ min_popularity: int = 8,
305
+ min_recent_requests: int = 5,
306
+ max_replicas: int = 5,
307
+ waiting_time_read_free_space: int = 1800,
308
+ waiting_time_read_workload: int = 1800,
309
+ waiting_time_print_workload: int = 600,
310
+ waiting_time_read_dids: int = 60,
311
+ waiting_time_place_replica: int = 100,
312
+ sleep_time: int = 10
313
+ ) -> None:
285
314
  """
286
315
  Starts up the main thread
287
316
  """
@@ -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");
@@ -14,17 +13,18 @@
14
13
  # limitations under the License.
15
14
 
16
15
  from json import loads
16
+ from typing import Optional
17
17
 
18
18
  from requests import get
19
19
 
20
20
  from rucio.common.config import config_get
21
21
 
22
22
 
23
- class MappingCollector(object):
23
+ class MappingCollector:
24
24
  """
25
25
  Provides mappings from PanDA / DDM resources to ATLAS sites and back.
26
26
  """
27
- class _MappingCollector(object):
27
+ class _MappingCollector:
28
28
  '''
29
29
  _MappingCollector
30
30
  '''
@@ -36,7 +36,7 @@ class MappingCollector(object):
36
36
  self._fetch_panda_mapping()
37
37
  self._fetch_ddm_mapping()
38
38
 
39
- def _fetch_panda_mapping(self):
39
+ def _fetch_panda_mapping(self) -> None:
40
40
  '''
41
41
  _fetch_panda_mapping
42
42
  '''
@@ -51,7 +51,7 @@ class MappingCollector(object):
51
51
  self.site_to_panda[entry['atlas_site']] = []
52
52
  self.site_to_panda[entry['atlas_site']].append(entry['panda_resource'])
53
53
 
54
- def _fetch_ddm_mapping(self):
54
+ def _fetch_ddm_mapping(self) -> None:
55
55
  '''
56
56
  _fetch_ddm_mapping
57
57
  '''
@@ -75,34 +75,34 @@ class MappingCollector(object):
75
75
  if not MappingCollector.instance:
76
76
  MappingCollector.instance = MappingCollector._MappingCollector()
77
77
 
78
- def ddm_to_site(self, ddm):
78
+ def ddm_to_site(self, ddm: str) -> Optional[str]:
79
79
  '''
80
80
  ddm_to_site
81
81
  '''
82
- if ddm not in self.instance.ddm_to_site:
82
+ if ddm not in self.instance.ddm_to_site: # type: ignore
83
83
  return None
84
- return self.instance.ddm_to_site[ddm]
84
+ return self.instance.ddm_to_site[ddm] # type: ignore
85
85
 
86
- def panda_to_site(self, panda):
86
+ def panda_to_site(self, panda: str) -> Optional[str]:
87
87
  '''
88
88
  panda_to_site
89
89
  '''
90
- if panda not in self.instance.panda_to_site:
90
+ if panda not in self.instance.panda_to_site: # type: ignore
91
91
  return None
92
- return self.instance.panda_to_site[panda]
92
+ return self.instance.panda_to_site[panda] # type: ignore
93
93
 
94
- def site_to_ddm(self, site):
94
+ def site_to_ddm(self, site: str) -> Optional[str]:
95
95
  '''
96
96
  site_to_ddm
97
97
  '''
98
- if site not in self.instance.site_to_ddm:
98
+ if site not in self.instance.site_to_ddm: # type: ignore
99
99
  return None
100
- return self.instance.site_to_ddm[site]
100
+ return self.instance.site_to_ddm[site] # type: ignore
101
101
 
102
- def site_to_panda(self, site):
102
+ def site_to_panda(self, site: str) -> Optional[str]:
103
103
  '''
104
104
  site_to_panda
105
105
  '''
106
- if site not in self.instance.site_to_panda:
106
+ if site not in self.instance.site_to_panda: # type: ignore
107
107
  return None
108
- return self.instance.site_to_panda[site]
108
+ return self.instance.site_to_panda[site] # type: ignore
@@ -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,15 +16,22 @@
17
16
  Collector to get the SRM free and used information for DATADISK RSEs.
18
17
  """
19
18
 
20
- from rucio.db.sqla.models import RSEUsage, RSEAttrAssociation
19
+ from typing import TYPE_CHECKING, Optional
20
+
21
+ from sqlalchemy import and_, select
22
+
23
+ from rucio.db.sqla.models import RSEAttrAssociation, RSEUsage
21
24
  from rucio.db.sqla.session import read_session
22
25
 
26
+ if TYPE_CHECKING:
27
+ from sqlalchemy.orm import Session
28
+
23
29
 
24
- class FreeSpaceCollector(object):
30
+ class FreeSpaceCollector:
25
31
  """
26
32
  Collector to get the SRM free and used information for DATADISK RSEs.
27
33
  """
28
- class _FreeSpaceCollector(object):
34
+ class _FreeSpaceCollector:
29
35
  """
30
36
  Hidden implementation
31
37
  """
@@ -33,14 +39,27 @@ class FreeSpaceCollector(object):
33
39
  self.rses = {}
34
40
 
35
41
  @read_session
36
- def _collect_free_space(self, *, session=None):
42
+ def _collect_free_space(
43
+ self,
44
+ *,
45
+ session: Optional["Session"] = None
46
+ ) -> None:
37
47
  """
38
48
  Retrieve free space from database
39
49
  """
40
- query = session.query(RSEUsage.rse_id, RSEUsage.free, RSEUsage.used).\
41
- join(RSEAttrAssociation, RSEUsage.rse_id == RSEAttrAssociation.rse_id).\
42
- filter(RSEUsage.source == 'storage').filter(RSEAttrAssociation.key == 'type', RSEAttrAssociation.value == 'DATADISK')
43
- for rse_id, free, used in query:
50
+ stmt = select(
51
+ RSEUsage.rse_id,
52
+ RSEUsage.free,
53
+ RSEUsage.used
54
+ ).join(
55
+ RSEAttrAssociation,
56
+ RSEAttrAssociation.rse_id == RSEUsage.rse_id
57
+ ).where(
58
+ and_(RSEUsage.source == 'storage',
59
+ RSEAttrAssociation.key == 'type',
60
+ RSEAttrAssociation.value == 'DATADISK'),
61
+ )
62
+ for rse_id, free, used in session.execute(stmt).all(): # type: ignore (session could be None)
44
63
  self.rses[rse_id] = {'total': used + free, 'used': used, 'free': free}
45
64
 
46
65
  instance = None
@@ -49,14 +68,14 @@ class FreeSpaceCollector(object):
49
68
  if not FreeSpaceCollector.instance:
50
69
  FreeSpaceCollector.instance = FreeSpaceCollector._FreeSpaceCollector()
51
70
 
52
- def collect_free_space(self):
71
+ def collect_free_space(self) -> None:
53
72
  """
54
73
  Execute the free space collector
55
74
  """
56
- self.instance._collect_free_space()
75
+ self.instance._collect_free_space() # type: ignore
57
76
 
58
- def get_rse_space(self):
77
+ def get_rse_space(self) -> dict[str, dict[str, int]]:
59
78
  """
60
79
  Return the RSE space
61
80
  """
62
- return self.instance.rses
81
+ return self.instance.rses # type: ignore
@@ -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,17 +13,27 @@
14
13
  # limitations under the License.
15
14
 
16
15
  import logging
16
+ from typing import TYPE_CHECKING, Optional
17
17
 
18
18
  from rucio.db.sqla.session import read_session
19
19
 
20
+ if TYPE_CHECKING:
21
+ from queue import Queue
20
22
 
21
- class JediDIDCollector():
22
- def __init__(self, queue):
23
+ from sqlalchemy.orm import Session
24
+
25
+
26
+ class JediDIDCollector:
27
+ def __init__(self, queue: "Queue"):
23
28
  self.queue = queue
24
29
  self.max_tid = 0
25
30
 
26
31
  @read_session
27
- def get_dids(self, *, session=None):
32
+ def get_dids(
33
+ self,
34
+ *,
35
+ session: Optional["Session"] = None
36
+ ) -> None:
28
37
  query = """select t.jeditaskid, t.username, t.status, d.datasetname from ATLAS_PANDA.JEDI_TASKS t
29
38
  inner join ATLAS_PANDA.JEDI_DATASETS d
30
39
  on t.jeditaskid = d.jeditaskid
@@ -32,7 +41,7 @@ class JediDIDCollector():
32
41
  and d.type = 'input'
33
42
  order by d.jeditaskid asc"""
34
43
 
35
- tasks = session.execute(query)
44
+ tasks = session.execute(query) # type: ignore
36
45
 
37
46
  for t in tasks.fetchall():
38
47
  status = t[2]