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,188 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- # Copyright European Organization for Nuclear Research (CERN) since 2012
3
- #
4
- # Licensed under the Apache License, Version 2.0 (the "License");
5
- # you may not use this file except in compliance with the License.
6
- # You may obtain a copy of the License at
7
- #
8
- # http://www.apache.org/licenses/LICENSE-2.0
9
- #
10
- # Unless required by applicable law or agreed to in writing, software
11
- # distributed under the License is distributed on an "AS IS" BASIS,
12
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- # See the License for the specific language governing permissions and
14
- # limitations under the License.
15
-
16
- from datetime import datetime
17
- from typing import TYPE_CHECKING
18
-
19
- from sqlalchemy import and_, or_, func, delete
20
- from sqlalchemy.sql.expression import case, insert, update
21
-
22
- from rucio.core.did import attach_dids
23
- from rucio.core.replica import add_replica
24
- from rucio.db.sqla import models, filter_thread_work
25
- from rucio.db.sqla.session import read_session, transactional_session
26
-
27
- # from rucio.rse import rsemanager as rsemgr
28
-
29
- if TYPE_CHECKING:
30
- from sqlalchemy.orm import Session
31
-
32
-
33
- @transactional_session
34
- def add_temporary_dids(dids, account, *, session: "Session"):
35
- """
36
- Bulk add temporary data identifiers.
37
-
38
- :param dids: A list of dids.
39
- :param account: The account owner.
40
- :param session: The database session in use.
41
- """
42
- temporary_dids = []
43
- for did in dids:
44
-
45
- if did.get('pfn'):
46
- did['path'] = did['pfn']
47
- # In waiting to properly extract the path
48
- # p = rsemgr.create_protocol(rse_settings=rsemgr.get_rse_info(rse, session=session), operation='write', scheme=scheme)
49
- # if not replica_rse.deterministic:
50
- # pfns = p.parse_pfns(pfns=pfns)
51
- # tmp = pfns[file['pfn']]
52
- # file['path'] = ''.join([tmp['path'], tmp['name']])
53
-
54
- temporary_dids.append({'scope': did['scope'],
55
- 'name': did['name'],
56
- 'rse_id': did['rse_id'],
57
- 'path': did.get('path'),
58
- 'bytes': did.get('bytes'),
59
- 'md5': did.get('md5'),
60
- 'adler32': did.get('adler32'),
61
- 'guid': did.get('guid'),
62
- 'events': did.get('envents'),
63
- 'parent_scope': did.get('parent_scope'),
64
- 'parent_name': did.get('parent_name'),
65
- 'offset': did.get('offset'),
66
- 'expired_at': datetime.utcnow()})
67
- try:
68
- if temporary_dids:
69
- session.execute(insert(models.TemporaryDataIdentifier), temporary_dids)
70
- except:
71
- raise
72
-
73
-
74
- @transactional_session
75
- def compose(scope, name, rse_id, bytes_, sources, account,
76
- md5=None, adler32=None, pfn=None, meta={}, rules=[],
77
- parent_scope=None, parent_name=None,
78
- *, session: "Session"):
79
- """
80
- Concatenates a list of existing dids into a new file replica
81
-
82
- :param scope: the scope name.
83
- :param name: The data identifier name.
84
- :param rse_id: the rse id.
85
- :param bytes_: the size of the file.
86
- :sources sources: The list of temporary DIDs.
87
- :param account: The account owner.
88
- :param md5: The md5 checksum.
89
- :param adler32: The adler32 checksum.
90
- :param pfn: Physical file name (for nondeterministic rse).
91
- :param meta: Meta-data associated with the file. Represented as key/value pairs in a dictionary.
92
- :param rules: Replication rules associated with the file. A list of dictionaries, e.g., [{'copies': 2, 'rse_expression': 'TIERS1'}, ].
93
- :param parent_scope: Possible dataset scope.
94
- :param parent_name: Possibe dataset name.
95
- :param session: The database session in use.
96
- """
97
- # Create the new file did and replica
98
- add_replica(rse_id=rse_id, scope=scope, name=name, bytes_=bytes_, account=account,
99
- adler32=adler32, md5=md5, pfn=pfn, meta=meta, rules=rules,
100
- session=session)
101
-
102
- # Attach the file to a dataset
103
- if parent_scope and parent_name:
104
- attach_dids(scope=parent_scope, name=parent_name,
105
- dids=[{'scope': scope, 'name': name}], account=account,
106
- rse_id=None, session=session)
107
-
108
- # Mark the merged dids as obsolete
109
- now, expired_dids = datetime.utcnow(), []
110
- for source in sources:
111
- expired_dids.append({'scope': source['scope'],
112
- 'name': source['name'],
113
- 'expired_at': now})
114
- if expired_dids:
115
- session.execute(update(models.TemporaryDataIdentifier), expired_dids)
116
-
117
-
118
- @read_session
119
- def list_expired_temporary_dids(rse_id, limit, worker_number=None, total_workers=None,
120
- *, session: "Session"):
121
- """
122
- List expired temporary DIDs.
123
-
124
- :param rse_id: the rse id.
125
- :param limit: The maximum number of replicas returned.
126
- :param worker_number: id of the executing worker.
127
- :param total_workers: Number of total workers.
128
- :param session: The database session in use.
129
-
130
- :returns: a list of dictionary replica.
131
- """
132
- is_none = None
133
- query = session.query(models.TemporaryDataIdentifier.scope,
134
- models.TemporaryDataIdentifier.name,
135
- models.TemporaryDataIdentifier.path,
136
- models.TemporaryDataIdentifier.bytes).\
137
- with_hint(models.TemporaryDataIdentifier, "INDEX(tmp_dids TMP_DIDS_EXPIRED_AT_IDX)", 'oracle').\
138
- filter(case((models.TemporaryDataIdentifier.expired_at != is_none, models.TemporaryDataIdentifier.rse_id)) == rse_id)
139
-
140
- query = filter_thread_work(session=session, query=query, total_threads=total_workers, thread_id=worker_number, hash_variable='name')
141
-
142
- return [{'path': path,
143
- 'rse_id': rse_id,
144
- 'scope': scope,
145
- 'name': name,
146
- 'bytes': bytes_}
147
- for scope, name, path, bytes_ in query.limit(limit)]
148
-
149
-
150
- @transactional_session
151
- def delete_temporary_dids(dids, *, session: "Session"):
152
- """
153
- Delete temporary file replicas.
154
-
155
- :param dids: the list of files to delete.
156
- :param session
157
- """
158
- where_clause = []
159
- for did in dids:
160
- where_clause.append(and_(models.TemporaryDataIdentifier.scope == did['scope'],
161
- models.TemporaryDataIdentifier.name == did['name']))
162
-
163
- if where_clause:
164
- stmt = delete(models.TemporaryDataIdentifier).\
165
- prefix_with("/*+ INDEX(tmp_dids TMP_DIDS_PK) */", dialect='oracle').\
166
- where(or_(*where_clause)).execution_options(synchronize_session=False)
167
- result = session.execute(stmt)
168
- return result.rowcount
169
- return
170
-
171
-
172
- @read_session
173
- def get_count_of_expired_temporary_dids(rse_id, *, session: "Session"):
174
- """
175
- List expired temporary DIDs.
176
-
177
- :param rse_id: the rse id.
178
- :param session: The database session in use.
179
-
180
- :returns: a count number.
181
- """
182
- is_none = None
183
- count = session.query(func.count(models.TemporaryDataIdentifier.scope)).\
184
- with_hint(models.TemporaryDataIdentifier, "INDEX(tmp_dids TMP_DIDS_EXPIRED_AT_IDX)", 'oracle').\
185
- filter(case((models.TemporaryDataIdentifier.expired_at != is_none, models.TemporaryDataIdentifier.rse_id)) == rse_id).\
186
- one()
187
-
188
- return count[0] or 0
@@ -1,255 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- # Copyright European Organization for Nuclear Research (CERN) since 2012
3
- #
4
- # Licensed under the Apache License, Version 2.0 (the "License");
5
- # you may not use this file except in compliance with the License.
6
- # You may obtain a copy of the License at
7
- #
8
- # http://www.apache.org/licenses/LICENSE-2.0
9
- #
10
- # Unless required by applicable law or agreed to in writing, software
11
- # distributed under the License is distributed on an "AS IS" BASIS,
12
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- # See the License for the specific language governing permissions and
14
- # limitations under the License.
15
-
16
- '''
17
- Light Reaper is a daemon to manage temporary object/file deletion.
18
- '''
19
-
20
- import hashlib
21
- import logging
22
- import os
23
- import random
24
- import socket
25
- import sys
26
- import threading
27
- import time
28
- import traceback
29
- from typing import TYPE_CHECKING
30
-
31
- import rucio.db.sqla.util
32
- from rucio.common.config import config_get_bool
33
- from rucio.common.exception import (SourceNotFound, DatabaseException, ServiceUnavailable,
34
- RSEAccessDenied, RSENotFound, ResourceTemporaryUnavailable, VONotFound)
35
- from rucio.common.logging import setup_logging, formatted_logger
36
- from rucio.common.utils import daemon_sleep
37
- from rucio.core import rse as rse_core
38
- from rucio.core.heartbeat import live, die, sanity_check
39
- from rucio.core.message import add_message
40
- from rucio.core.rse_expression_parser import parse_expression
41
- from rucio.core.temporary_did import (list_expired_temporary_dids, delete_temporary_dids)
42
- from rucio.core.vo import list_vos
43
- from rucio.rse import rsemanager as rsemgr
44
-
45
- if TYPE_CHECKING:
46
- from types import FrameType
47
- from typing import Optional
48
-
49
- logging.getLogger("requests").setLevel(logging.CRITICAL)
50
-
51
- GRACEFUL_STOP = threading.Event()
52
- DAEMON_NAME = 'reaper'
53
-
54
-
55
- def reaper(rses=[], worker_number=0, total_workers=1, chunk_size=100, once=False, scheme=None, sleep_time=60):
56
- """
57
- Main loop to select and delete files.
58
-
59
- :param rses: List of RSEs the reaper should work against. If empty, it considers all RSEs.
60
- :param worker_number: The worker number.
61
- :param total_workers: The total number of workers.
62
- :param chunk_size: the size of chunk for deletion.
63
- :param once: If True, only runs one iteration of the main loop.
64
- :param scheme: Force the reaper to use a particular protocol, e.g., mock.
65
- :param sleep_time: Thread sleep time after each chunk of work.
66
- """
67
- logging.info('Starting Light Reaper %s-%s: Will work on RSEs: %s', worker_number, total_workers, ', '.join([rse['rse'] for rse in rses]))
68
-
69
- pid = os.getpid()
70
- thread = threading.current_thread()
71
- hostname = socket.gethostname()
72
- executable = ' '.join(sys.argv)
73
- hash_executable = hashlib.sha256(sys.argv[0] + ''.join([rse['rse'] for rse in rses])).hexdigest()
74
- sanity_check(executable=None, hostname=hostname)
75
-
76
- while not GRACEFUL_STOP.is_set():
77
- try:
78
- # heartbeat
79
- heartbeat = live(executable=executable, hostname=hostname, pid=pid, thread=thread, hash_executable=hash_executable)
80
- prepend_str = 'light-reaper [%i/%i] : ' % (heartbeat['assign_thread'], heartbeat['nr_threads'])
81
- logger = formatted_logger(logging.log, prepend_str + '%s')
82
- logger(logging.INFO, 'Live gives %s', heartbeat)
83
- nothing_to_do = True
84
- start_time = time.time()
85
-
86
- random.shuffle(rses)
87
- for rse in rses:
88
- rse_id = rse['id']
89
- rse = rse['rse']
90
- replicas = list_expired_temporary_dids(rse_id=rse_id,
91
- limit=chunk_size, worker_number=worker_number,
92
- total_workers=total_workers)
93
-
94
- rse_info = rsemgr.get_rse_info(rse_id=rse_id)
95
- prot = rsemgr.create_protocol(rse_info, 'delete', scheme=scheme)
96
- deleted_replicas = []
97
- try:
98
- prot.connect()
99
- for replica in replicas:
100
- nothing_to_do = False
101
- try:
102
- # pfn = str(rsemgr.lfns2pfns(rse_settings=rse_info,
103
- # lfns=[{'scope': replica['scope'].external, 'name': replica['name'], 'path': replica['path']}],
104
- # operation='delete', scheme=scheme).values()[0])
105
- pfn = 's3://%s%s%s' % (prot.attributes['hostname'], prot.attributes['prefix'], replica['name'])
106
- # logging.debug('Light Reaper %s-%s: Deletion ATTEMPT of %s:%s as %s on %s', worker_number, total_workers, replica['scope'], replica['name'], pfn, rse)
107
- start = time.time()
108
- prot.delete(pfn)
109
- duration = time.time() - start
110
- logger(logging.INFO, 'Deletion SUCCESS of %s:%s as %s on %s in %s seconds', replica['scope'], replica['name'], pfn, rse, duration)
111
- payload = {'scope': replica['scope'].external,
112
- 'name': replica['name'],
113
- 'rse': rse,
114
- 'rse_id': rse_id,
115
- 'file-size': replica.get('bytes') or 0,
116
- 'bytes': replica.get('bytes') or 0,
117
- 'url': pfn,
118
- 'duration': duration,
119
- 'protocol': prot.attributes['scheme']}
120
- if replica['scope'].vo != 'def':
121
- payload['vo'] = replica['scope'].vo
122
- add_message('deletion-done', payload)
123
- deleted_replicas.append(replica)
124
- except SourceNotFound:
125
- err_msg = 'Deletion NOTFOUND of %s:%s as %s on %s' % (replica['scope'], replica['name'], pfn, rse)
126
- logger(logging.WARNING, err_msg)
127
- deleted_replicas.append(replica)
128
- except (ServiceUnavailable, RSEAccessDenied, ResourceTemporaryUnavailable) as error:
129
- err_msg = 'Deletion NOACCESS of %s:%s as %s on %s: %s' % (replica['scope'], replica['name'], pfn, rse, str(error))
130
- logger(logging.WARNING, err_msg)
131
- payload = {'scope': replica['scope'].external,
132
- 'name': replica['name'],
133
- 'rse': rse,
134
- 'rse_id': rse_id,
135
- 'file-size': replica['bytes'] or 0,
136
- 'bytes': replica['bytes'] or 0,
137
- 'url': pfn,
138
- 'reason': str(error),
139
- 'protocol': prot.attributes['scheme']}
140
- if replica['scope'].vo != 'def':
141
- payload['vo'] = replica['scope'].vo
142
- add_message('deletion-failed', payload)
143
-
144
- except:
145
- logger(logging.CRITICAL, traceback.format_exc())
146
- finally:
147
- prot.close()
148
-
149
- delete_temporary_dids(dids=deleted_replicas)
150
-
151
- if once:
152
- break
153
-
154
- if once:
155
- break
156
-
157
- if nothing_to_do:
158
- logger(logging.INFO, 'Nothing to do. I will sleep for 60s')
159
- daemon_sleep(start_time=start_time, sleep_time=sleep_time, graceful_stop=GRACEFUL_STOP)
160
-
161
- except DatabaseException as error:
162
- logging.warning('Reaper: %s', str(error))
163
- except:
164
- logging.critical(traceback.format_exc())
165
-
166
- die(executable=executable, hostname=hostname, pid=pid, thread=thread, hash_executable=hash_executable)
167
- logging.info('Graceful stop requested')
168
- logging.info('Graceful stop done')
169
- return
170
-
171
-
172
- def stop(signum: "Optional[int]" = None, frame: "Optional[FrameType]" = None) -> None:
173
- """
174
- Graceful exit.
175
- """
176
- GRACEFUL_STOP.set()
177
-
178
-
179
- def run(total_workers=1, chunk_size=100, once=False, rses=[], scheme=None,
180
- exclude_rses=None, include_rses=None, vos=None, delay_seconds=0, sleep_time=60):
181
- """
182
- Starts up the reaper threads.
183
-
184
- :param total_workers: The total number of workers.
185
- :param chunk_size: the size of chunk for deletion.
186
- :param once: If True, only runs one iteration of the main loop.
187
- :param rses: List of RSEs the reaper should work against. If empty, it considers all RSEs. (Single-VO only)
188
- :param scheme: Force the reaper to use a particular protocol/scheme, e.g., mock.
189
- :param exclude_rses: RSE expression to exclude RSEs from the Reaper.
190
- :param include_rses: RSE expression to include RSEs.
191
- :param vos: VOs on which to look for RSEs. Only used in multi-VO mode.
192
- If None, we either use all VOs if run from "def", or the current VO otherwise.
193
- :param sleep_time: Thread sleep time after each chunk of work.
194
- """
195
- setup_logging(process_name=DAEMON_NAME)
196
-
197
- if rucio.db.sqla.util.is_old_db():
198
- raise DatabaseException('Database was not updated, daemon won\'t start')
199
-
200
- logging.info('main: starting processes')
201
-
202
- multi_vo = config_get_bool('common', 'multi_vo', raise_exception=False, default=False)
203
- if not multi_vo:
204
- if vos:
205
- logging.warning('Ignoring argument vos, this is only applicable in a multi-VO setup.')
206
- vos = ['def']
207
- else:
208
- if vos:
209
- invalid = set(vos) - set([v['vo'] for v in list_vos()])
210
- if invalid:
211
- msg = 'VO{} {} cannot be found'.format('s' if len(invalid) > 1 else '', ', '.join([repr(v) for v in invalid]))
212
- raise VONotFound(msg)
213
- else:
214
- vos = [v['vo'] for v in list_vos()]
215
- logging.info('Light Reaper: This instance will work on VO%s: %s' % ('s' if len(vos) > 1 else '', ', '.join([v for v in vos])))
216
-
217
- all_rses = []
218
- for vo in vos:
219
- all_rses.extend(rse_core.list_rses(filters={'vo': vo}))
220
-
221
- if rses:
222
- invalid = set(rses) - set([rse['rse'] for rse in all_rses])
223
- if invalid:
224
- msg = 'RSE{} {} cannot be found'.format('s' if len(invalid) > 1 else '',
225
- ', '.join([repr(rse) for rse in invalid]))
226
- raise RSENotFound(msg)
227
- rses = [rse for rse in all_rses if rse['rse'] in rses]
228
- else:
229
- rses = all_rses
230
-
231
- if exclude_rses:
232
- excluded_rses = parse_expression(exclude_rses)
233
- rses = [rse for rse in rses if rse not in excluded_rses]
234
-
235
- if include_rses:
236
- included_rses = parse_expression(include_rses)
237
- rses = [rse for rse in rses if rse in included_rses]
238
-
239
- if not rses:
240
- logging.error('Light Reaper: No RSEs found. Exiting.')
241
- return
242
-
243
- threads = []
244
- for worker in range(total_workers):
245
- kwargs = {'worker_number': worker,
246
- 'total_workers': total_workers,
247
- 'rses': rses,
248
- 'once': once,
249
- 'chunk_size': chunk_size,
250
- 'scheme': scheme,
251
- 'sleep_time': sleep_time}
252
- threads.append(threading.Thread(target=reaper, kwargs=kwargs, name='Worker: %s, Total_Workers: %s' % (worker, total_workers)))
253
- [t.start() for t in threads]
254
- while threads[0].is_alive():
255
- [t.join(timeout=3.14) for t in threads]
@@ -1,115 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- # Copyright European Organization for Nuclear Research (CERN) since 2012
3
- #
4
- # Licensed under the Apache License, Version 2.0 (the "License");
5
- # you may not use this file except in compliance with the License.
6
- # You may obtain a copy of the License at
7
- #
8
- # http://www.apache.org/licenses/LICENSE-2.0
9
- #
10
- # Unless required by applicable law or agreed to in writing, software
11
- # distributed under the License is distributed on an "AS IS" BASIS,
12
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- # See the License for the specific language governing permissions and
14
- # limitations under the License.
15
-
16
- from flask import Flask, request
17
-
18
- from rucio.api.temporary_did import add_temporary_dids
19
- from rucio.web.rest.flaskapi.authenticated_bp import AuthenticatedBlueprint
20
- from rucio.web.rest.flaskapi.v1.common import response_headers, ErrorHandlingMethodView, json_list
21
-
22
-
23
- class BulkDIDS(ErrorHandlingMethodView):
24
-
25
- def post(self):
26
- """
27
- ---
28
- summary: Add Temporary Data Identifiers
29
- description: Bulk adds temporary data identifiers.
30
- tags:
31
- - Temporary Data Identifiers
32
- requestBody:
33
- content:
34
- application/json:
35
- schema:
36
- description: A list of temporary dids.
37
- type: array
38
- items:
39
- description: A temporary did.
40
- properties:
41
- rse:
42
- description: The name of the RSE.
43
- type: string
44
- rse_id:
45
- description: The id of the RSE. Can be specified instead of the RSE name.
46
- type: string
47
- scope:
48
- description: The scope.
49
- type: string
50
- parent_scope:
51
- description: The parent scope.
52
- type: string
53
- name:
54
- description: The name of the DID.
55
- type: string
56
- path:
57
- description: The path of the DID.
58
- type: string
59
- pfn:
60
- description: The pfn of the DID.
61
- type: string
62
- bytes:
63
- description: The size of the DID in bytes.
64
- type: integer
65
- md5:
66
- description: The md5 checksum of the DID.
67
- type: string
68
- adler32:
69
- description: The adler32 checksum of the DID.
70
- type: string
71
- guid:
72
- description: The guid of the DID.
73
- type: string
74
- events:
75
- description: The events of the DID.
76
- type: string
77
- parent_name:
78
- description: The name of the parent.
79
- type: string
80
- offset:
81
- description: The offset of the DID.
82
- type: integer
83
- responses:
84
- 201:
85
- description: Created
86
- content:
87
- application/json:
88
- schema:
89
- type: string
90
- enum: ["Created"]
91
- 401:
92
- description: Invalid Auth Token
93
- 406:
94
- description: Not acceptable
95
- """
96
- dids = json_list()
97
- add_temporary_dids(dids=dids, issuer=request.environ.get('issuer'), vo=request.environ.get('vo'))
98
- return 'Created', 201
99
-
100
-
101
- def blueprint():
102
- bp = AuthenticatedBlueprint('tmp_dids', __name__, url_prefix='/tmp_dids')
103
-
104
- bulk_dids_view = BulkDIDS.as_view('bulk_dids')
105
- bp.add_url_rule('', view_func=bulk_dids_view, methods=['post', ])
106
-
107
- bp.after_request(response_headers)
108
- return bp
109
-
110
-
111
- def make_doc():
112
- """ Only used for sphinx documentation """
113
- doc_app = Flask(__name__)
114
- doc_app.register_blueprint(blueprint())
115
- return doc_app
@@ -1,55 +0,0 @@
1
- # All dependencies needed to run rucio client (and server/daemons) should be defined here
2
- requests>=2.25.1,<=2.31.0 # Python HTTP for Humans.
3
- urllib3~=1.26.16 # HTTP library with thread-safe connection pooling, file post, etc.
4
- dogpile.cache~=1.2.2 # Caching API plugins (1.1.2 is the first version to support pymemcache)
5
- tabulate~=0.9.0 # Pretty-print tabular data
6
- jsonschema~=4.18.4 # For JSON schema validation (Policy modules)
7
-
8
- # All dependencies needed in extras for rucio client (and server/daemons) should be defined here
9
- paramiko~=3.4.0 # ssh_extras; SSH2 protocol library (also needed in the server)
10
- kerberos~=1.3.1 # kerberos_extras for client and server
11
- pykerberos~=1.2.4 # kerberos_extras for client and server
12
- requests-kerberos>=0.14.0 # kerberos_extras for client and server
13
- python-swiftclient~=4.3.0 # swift_extras
14
- argcomplete~=3.1.1 # argcomplete_extras; Bash tab completion for argparse
15
- python-magic~=0.4.27 # dumper_extras; File type identification using libmagic
16
-
17
- # All dependencies needed to run rucio server/daemons should be defined here
18
- SQLAlchemy==2.0.19 # DB backend
19
- alembic~=1.11.1 # Lightweight database migration tool for SQLAlchemy
20
- pymemcache==4.0.0 # A comprehensive, fast, pure-Python memcached client (Used by Dogpile)
21
- python-dateutil==2.8.2 # Extensions to the standard datetime module
22
- stomp.py==8.1.0 # ActiveMQ Messaging Protocol
23
- statsd==4.0.1 # Needed to log into graphite with more than 1 Hz
24
- geoip2==4.7.0 # GeoIP2 API (for IPv6 support)
25
- google-auth==2.22.0 # Google authentication library for Python
26
- redis==4.6.0 # Python client for Redis key-value store
27
- Flask==2.3.2 # Python web framework
28
- oic==1.6.1 # for authentication via OpenID Connect protocol
29
- prometheus_client==0.17.1 # Python client for the Prometheus monitoring system
30
- boto3==1.28.5 # S3 boto protocol (new version)
31
-
32
- # All dependencies needed in extras for rucio server/daemons should be defined here
33
- cx_oracle==8.3.0 # oracle_extras
34
- psycopg2-binary==2.9.6 # postgresql_extras
35
- PyMySQL==1.1.0 # mysql_extras
36
- PyYAML==6.0.1 # globus_extras and used for reading test configuration files
37
- globus-sdk==3.24.0 # globus_extras
38
- python3-saml==1.15.0 # saml_extras
39
- pymongo==4.4.1 # pymongo (metadata plugin)
40
-
41
- # All dependencies needed to develop/test rucio should be defined here
42
- pytest==7.4.0
43
- pytest-xdist~=3.3.1 # Used for parallel testing
44
- pyflakes==3.0.1 # Passive checker of Python programs
45
- flake8==6.0.0 # Wrapper around PyFlakes&pep8; python_version < '3.9'
46
- pycodestyle==2.10.0 # New package replacing pep8; python_version < '3.9'
47
- pylint==3.0.0a7
48
- astroid==3.0.0a9
49
- virtualenv==20.24.0 # Virtual Python Environment builder
50
- xmltodict==0.13.0 # Makes working with XML feel like you are working with JSON
51
- pytz==2023.3 # World timezone definitions, modern and historical
52
- pydoc-markdown~=4.8.2 # Used for generating Markdown documentation for docusaurus
53
- sh~=2.0.4 # Convenience library for running subprocesses in Python
54
- apispec==6.3.0 # Generate OpenApi definition out of pydoc comments
55
- apispec-webframeworks # Integration of apispec in Flask
@@ -1,53 +0,0 @@
1
- #!python
2
- # -*- coding: utf-8 -*-
3
- # Copyright European Organization for Nuclear Research (CERN) since 2012
4
- #
5
- # Licensed under the Apache License, Version 2.0 (the "License");
6
- # you may not use this file except in compliance with the License.
7
- # You may obtain a copy of the License at
8
- #
9
- # http://www.apache.org/licenses/LICENSE-2.0
10
- #
11
- # Unless required by applicable law or agreed to in writing, software
12
- # distributed under the License is distributed on an "AS IS" BASIS,
13
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- # See the License for the specific language governing permissions and
15
- # limitations under the License.
16
-
17
- """
18
- Reaper is a daemon to manage sub-file deletion
19
- """
20
-
21
- import argparse
22
- import signal
23
-
24
- from rucio.daemons.reaper.light_reaper import run, stop
25
-
26
-
27
- def get_parser():
28
- """
29
- Returns the argparse parser.
30
- """
31
- parser = argparse.ArgumentParser(description="The light-reaper is responsible of deletion of temporary files")
32
- parser.add_argument("--run-once", action="store_true", default=False, help='One iteration only')
33
- parser.add_argument("--total-workers", action="store", default=1, type=int, help='Total number of workers per process')
34
- parser.add_argument("--chunk-size", action="store", default=10, type=int, help='Chunk size')
35
- parser.add_argument("--scheme", action="store", default=None, type=str, help='Force the reaper to use a particular protocol, e.g., mock.')
36
- parser.add_argument('--rses', nargs='+', type=str, help='List of RSEs')
37
- parser.add_argument('--exclude-rses', action="store", default=None, type=str, help='RSEs expression to exclude RSEs')
38
- parser.add_argument('--include-rses', action="store", default=None, type=str, help='RSEs expression to include RSEs')
39
- parser.add_argument('--vos', nargs='+', type=str, help='Optional list of VOs to consider. Only used in multi-VO mode.')
40
- parser.add_argument('--sleep-time', action="store", default=60, type=int, help='Concurrency control: thread sleep time after each chunk of work')
41
- return parser
42
-
43
-
44
- if __name__ == '__main__':
45
- signal.signal(signal.SIGTERM, stop)
46
- parser = get_parser()
47
- args = parser.parse_args()
48
- try:
49
- run(total_workers=args.total_workers, chunk_size=args.chunk_size,
50
- once=args.run_once, scheme=args.scheme, rses=args.rses,
51
- exclude_rses=args.exclude_rses, include_rses=args.include_rses, vos=args.vos, sleep_time=args.sleep_time)
52
- except KeyboardInterrupt:
53
- stop()