rucio 35.7.0__py3-none-any.whl → 37.0.0rc2__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 (268) hide show
  1. rucio/alembicrevision.py +1 -1
  2. rucio/{daemons/c3po/collectors → cli}/__init__.py +1 -0
  3. rucio/cli/account.py +216 -0
  4. rucio-35.7.0.data/scripts/rucio → rucio/cli/bin_legacy/rucio.py +769 -486
  5. rucio-35.7.0.data/scripts/rucio-admin → rucio/cli/bin_legacy/rucio_admin.py +476 -423
  6. rucio/cli/command.py +272 -0
  7. rucio/cli/config.py +72 -0
  8. rucio/cli/did.py +191 -0
  9. rucio/cli/download.py +128 -0
  10. rucio/cli/lifetime_exception.py +33 -0
  11. rucio/cli/replica.py +162 -0
  12. rucio/cli/rse.py +293 -0
  13. rucio/cli/rule.py +158 -0
  14. rucio/cli/scope.py +40 -0
  15. rucio/cli/subscription.py +73 -0
  16. rucio/cli/upload.py +60 -0
  17. rucio/cli/utils.py +226 -0
  18. rucio/client/accountclient.py +0 -1
  19. rucio/client/baseclient.py +33 -24
  20. rucio/client/client.py +45 -1
  21. rucio/client/didclient.py +5 -3
  22. rucio/client/downloadclient.py +6 -8
  23. rucio/client/replicaclient.py +0 -2
  24. rucio/client/richclient.py +317 -0
  25. rucio/client/rseclient.py +4 -4
  26. rucio/client/uploadclient.py +26 -12
  27. rucio/common/bittorrent.py +234 -0
  28. rucio/common/cache.py +66 -29
  29. rucio/common/checksum.py +168 -0
  30. rucio/common/client.py +122 -0
  31. rucio/common/config.py +22 -35
  32. rucio/common/constants.py +61 -3
  33. rucio/common/didtype.py +72 -24
  34. rucio/common/dumper/__init__.py +45 -38
  35. rucio/common/dumper/consistency.py +75 -30
  36. rucio/common/dumper/data_models.py +63 -19
  37. rucio/common/dumper/path_parsing.py +19 -8
  38. rucio/common/exception.py +65 -8
  39. rucio/common/extra.py +5 -10
  40. rucio/common/logging.py +13 -13
  41. rucio/common/pcache.py +8 -7
  42. rucio/common/plugins.py +59 -27
  43. rucio/common/policy.py +12 -3
  44. rucio/common/schema/__init__.py +84 -34
  45. rucio/common/schema/generic.py +0 -17
  46. rucio/common/schema/generic_multi_vo.py +0 -17
  47. rucio/common/stomp_utils.py +383 -119
  48. rucio/common/test_rucio_server.py +12 -6
  49. rucio/common/types.py +132 -52
  50. rucio/common/utils.py +93 -643
  51. rucio/core/account_limit.py +14 -12
  52. rucio/core/authentication.py +2 -2
  53. rucio/core/config.py +23 -42
  54. rucio/core/credential.py +14 -15
  55. rucio/core/did.py +5 -1
  56. rucio/core/did_meta_plugins/elasticsearch_meta.py +407 -0
  57. rucio/core/did_meta_plugins/filter_engine.py +62 -3
  58. rucio/core/did_meta_plugins/json_meta.py +2 -2
  59. rucio/core/did_meta_plugins/mongo_meta.py +43 -30
  60. rucio/core/did_meta_plugins/postgres_meta.py +75 -39
  61. rucio/core/identity.py +6 -5
  62. rucio/core/importer.py +4 -3
  63. rucio/core/lifetime_exception.py +2 -2
  64. rucio/core/lock.py +8 -7
  65. rucio/core/message.py +6 -0
  66. rucio/core/monitor.py +30 -29
  67. rucio/core/naming_convention.py +2 -2
  68. rucio/core/nongrid_trace.py +2 -2
  69. rucio/core/oidc.py +11 -9
  70. rucio/core/permission/__init__.py +79 -37
  71. rucio/core/permission/generic.py +1 -7
  72. rucio/core/permission/generic_multi_vo.py +1 -7
  73. rucio/core/quarantined_replica.py +4 -3
  74. rucio/core/replica.py +464 -139
  75. rucio/core/replica_sorter.py +55 -59
  76. rucio/core/request.py +34 -32
  77. rucio/core/rse.py +301 -97
  78. rucio/core/rse_counter.py +1 -2
  79. rucio/core/rse_expression_parser.py +7 -7
  80. rucio/core/rse_selector.py +9 -7
  81. rucio/core/rule.py +41 -40
  82. rucio/core/rule_grouping.py +42 -40
  83. rucio/core/scope.py +5 -4
  84. rucio/core/subscription.py +26 -28
  85. rucio/core/topology.py +11 -11
  86. rucio/core/trace.py +2 -2
  87. rucio/core/transfer.py +29 -15
  88. rucio/core/volatile_replica.py +4 -3
  89. rucio/daemons/atropos/atropos.py +1 -1
  90. rucio/daemons/auditor/__init__.py +2 -2
  91. rucio/daemons/auditor/srmdumps.py +6 -6
  92. rucio/daemons/automatix/automatix.py +32 -21
  93. rucio/daemons/badreplicas/necromancer.py +2 -2
  94. rucio/daemons/bb8/nuclei_background_rebalance.py +1 -1
  95. rucio/daemons/bb8/t2_background_rebalance.py +1 -1
  96. rucio/daemons/cache/consumer.py +26 -90
  97. rucio/daemons/common.py +15 -25
  98. rucio/daemons/conveyor/finisher.py +2 -2
  99. rucio/daemons/conveyor/poller.py +18 -28
  100. rucio/daemons/conveyor/receiver.py +53 -123
  101. rucio/daemons/conveyor/stager.py +1 -0
  102. rucio/daemons/conveyor/submitter.py +3 -3
  103. rucio/daemons/hermes/hermes.py +129 -369
  104. rucio/daemons/judge/evaluator.py +2 -2
  105. rucio/daemons/oauthmanager/oauthmanager.py +3 -3
  106. rucio/daemons/reaper/dark_reaper.py +7 -3
  107. rucio/daemons/reaper/reaper.py +12 -16
  108. rucio/daemons/rsedecommissioner/config.py +1 -1
  109. rucio/daemons/rsedecommissioner/profiles/generic.py +5 -4
  110. rucio/daemons/rsedecommissioner/profiles/types.py +7 -6
  111. rucio/daemons/rsedecommissioner/rse_decommissioner.py +1 -1
  112. rucio/daemons/storage/consistency/actions.py +8 -6
  113. rucio/daemons/tracer/kronos.py +117 -142
  114. rucio/db/sqla/constants.py +5 -0
  115. rucio/db/sqla/migrate_repo/versions/1677d4d803c8_split_rse_availability_into_multiple.py +4 -4
  116. rucio/db/sqla/migrate_repo/versions/30d5206e9cad_increase_oauthrequest_redirect_msg_.py +37 -0
  117. rucio/db/sqla/models.py +157 -154
  118. rucio/db/sqla/session.py +58 -27
  119. rucio/db/sqla/types.py +2 -2
  120. rucio/db/sqla/util.py +2 -2
  121. rucio/gateway/account.py +18 -12
  122. rucio/gateway/account_limit.py +137 -60
  123. rucio/gateway/authentication.py +18 -12
  124. rucio/gateway/config.py +30 -20
  125. rucio/gateway/credential.py +9 -10
  126. rucio/gateway/did.py +70 -53
  127. rucio/gateway/dirac.py +6 -4
  128. rucio/gateway/exporter.py +3 -2
  129. rucio/gateway/heartbeat.py +6 -4
  130. rucio/gateway/identity.py +36 -51
  131. rucio/gateway/importer.py +3 -2
  132. rucio/gateway/lifetime_exception.py +3 -2
  133. rucio/gateway/meta_conventions.py +17 -6
  134. rucio/gateway/permission.py +4 -1
  135. rucio/gateway/quarantined_replica.py +3 -2
  136. rucio/gateway/replica.py +31 -22
  137. rucio/gateway/request.py +27 -18
  138. rucio/gateway/rse.py +69 -37
  139. rucio/gateway/rule.py +46 -26
  140. rucio/gateway/scope.py +3 -2
  141. rucio/gateway/subscription.py +14 -11
  142. rucio/gateway/vo.py +12 -8
  143. rucio/rse/__init__.py +3 -3
  144. rucio/rse/protocols/bittorrent.py +11 -1
  145. rucio/rse/protocols/cache.py +0 -11
  146. rucio/rse/protocols/dummy.py +0 -11
  147. rucio/rse/protocols/gfal.py +14 -9
  148. rucio/rse/protocols/globus.py +1 -1
  149. rucio/rse/protocols/http_cache.py +1 -1
  150. rucio/rse/protocols/posix.py +2 -2
  151. rucio/rse/protocols/protocol.py +84 -317
  152. rucio/rse/protocols/rclone.py +2 -1
  153. rucio/rse/protocols/rfio.py +10 -1
  154. rucio/rse/protocols/ssh.py +2 -1
  155. rucio/rse/protocols/storm.py +2 -13
  156. rucio/rse/protocols/webdav.py +74 -30
  157. rucio/rse/protocols/xrootd.py +2 -1
  158. rucio/rse/rsemanager.py +170 -53
  159. rucio/rse/translation.py +260 -0
  160. rucio/tests/common.py +23 -13
  161. rucio/tests/common_server.py +26 -9
  162. rucio/transfertool/bittorrent.py +15 -14
  163. rucio/transfertool/bittorrent_driver.py +5 -7
  164. rucio/transfertool/bittorrent_driver_qbittorrent.py +9 -8
  165. rucio/transfertool/fts3.py +20 -16
  166. rucio/transfertool/mock.py +2 -3
  167. rucio/vcsversion.py +4 -4
  168. rucio/version.py +7 -0
  169. rucio/web/rest/flaskapi/v1/accounts.py +17 -3
  170. rucio/web/rest/flaskapi/v1/auth.py +5 -5
  171. rucio/web/rest/flaskapi/v1/credentials.py +3 -2
  172. rucio/web/rest/flaskapi/v1/dids.py +21 -15
  173. rucio/web/rest/flaskapi/v1/identities.py +33 -9
  174. rucio/web/rest/flaskapi/v1/redirect.py +5 -4
  175. rucio/web/rest/flaskapi/v1/replicas.py +12 -8
  176. rucio/web/rest/flaskapi/v1/rses.py +15 -4
  177. rucio/web/rest/flaskapi/v1/traces.py +56 -19
  178. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/alembic.ini.template +1 -1
  179. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/alembic_offline.ini.template +1 -1
  180. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/rucio.cfg.atlas.client.template +3 -2
  181. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/rucio.cfg.template +3 -19
  182. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/rucio_multi_vo.cfg.template +1 -18
  183. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/requirements.server.txt +97 -68
  184. rucio-37.0.0rc2.data/scripts/rucio +133 -0
  185. rucio-37.0.0rc2.data/scripts/rucio-admin +97 -0
  186. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-atropos +2 -2
  187. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-auditor +2 -1
  188. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-automatix +2 -2
  189. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-cache-client +17 -10
  190. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-conveyor-receiver +1 -0
  191. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-kronos +1 -0
  192. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-minos +2 -2
  193. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-minos-temporary-expiration +2 -2
  194. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-necromancer +2 -2
  195. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-reaper +6 -6
  196. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-transmogrifier +2 -2
  197. rucio-37.0.0rc2.dist-info/METADATA +92 -0
  198. {rucio-35.7.0.dist-info → rucio-37.0.0rc2.dist-info}/RECORD +239 -245
  199. {rucio-35.7.0.dist-info → rucio-37.0.0rc2.dist-info}/licenses/AUTHORS.rst +3 -0
  200. rucio/common/schema/atlas.py +0 -413
  201. rucio/common/schema/belleii.py +0 -408
  202. rucio/common/schema/domatpc.py +0 -401
  203. rucio/common/schema/escape.py +0 -426
  204. rucio/common/schema/icecube.py +0 -406
  205. rucio/core/permission/atlas.py +0 -1348
  206. rucio/core/permission/belleii.py +0 -1077
  207. rucio/core/permission/escape.py +0 -1078
  208. rucio/daemons/c3po/algorithms/__init__.py +0 -13
  209. rucio/daemons/c3po/algorithms/simple.py +0 -134
  210. rucio/daemons/c3po/algorithms/t2_free_space.py +0 -128
  211. rucio/daemons/c3po/algorithms/t2_free_space_only_pop.py +0 -130
  212. rucio/daemons/c3po/algorithms/t2_free_space_only_pop_with_network.py +0 -294
  213. rucio/daemons/c3po/c3po.py +0 -371
  214. rucio/daemons/c3po/collectors/agis.py +0 -108
  215. rucio/daemons/c3po/collectors/free_space.py +0 -81
  216. rucio/daemons/c3po/collectors/jedi_did.py +0 -57
  217. rucio/daemons/c3po/collectors/mock_did.py +0 -51
  218. rucio/daemons/c3po/collectors/network_metrics.py +0 -71
  219. rucio/daemons/c3po/collectors/workload.py +0 -112
  220. rucio/daemons/c3po/utils/__init__.py +0 -13
  221. rucio/daemons/c3po/utils/dataset_cache.py +0 -50
  222. rucio/daemons/c3po/utils/expiring_dataset_cache.py +0 -56
  223. rucio/daemons/c3po/utils/expiring_list.py +0 -62
  224. rucio/daemons/c3po/utils/popularity.py +0 -85
  225. rucio/daemons/c3po/utils/timeseries.py +0 -89
  226. rucio/rse/protocols/gsiftp.py +0 -92
  227. rucio-35.7.0.data/scripts/rucio-c3po +0 -85
  228. rucio-35.7.0.dist-info/METADATA +0 -72
  229. /rucio/{daemons/c3po → cli/bin_legacy}/__init__.py +0 -0
  230. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/globus-config.yml.template +0 -0
  231. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/ldap.cfg.template +0 -0
  232. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/mail_templates/rule_approval_request.tmpl +0 -0
  233. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/mail_templates/rule_approved_admin.tmpl +0 -0
  234. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/mail_templates/rule_approved_user.tmpl +0 -0
  235. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/mail_templates/rule_denied_admin.tmpl +0 -0
  236. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/mail_templates/rule_denied_user.tmpl +0 -0
  237. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/mail_templates/rule_ok_notification.tmpl +0 -0
  238. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/rse-accounts.cfg.template +0 -0
  239. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/tools/bootstrap.py +0 -0
  240. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/tools/merge_rucio_configs.py +0 -0
  241. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/tools/reset_database.py +0 -0
  242. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-abacus-account +0 -0
  243. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-abacus-collection-replica +0 -0
  244. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-abacus-rse +0 -0
  245. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-bb8 +0 -0
  246. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-cache-consumer +0 -0
  247. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-conveyor-finisher +0 -0
  248. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-conveyor-poller +0 -0
  249. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-conveyor-preparer +0 -0
  250. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-conveyor-stager +0 -0
  251. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-conveyor-submitter +0 -0
  252. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-conveyor-throttler +0 -0
  253. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-dark-reaper +0 -0
  254. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-dumper +0 -0
  255. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-follower +0 -0
  256. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-hermes +0 -0
  257. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-judge-cleaner +0 -0
  258. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-judge-evaluator +0 -0
  259. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-judge-injector +0 -0
  260. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-judge-repairer +0 -0
  261. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-oauth-manager +0 -0
  262. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-replica-recoverer +0 -0
  263. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-rse-decommissioner +0 -0
  264. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-storage-consistency-actions +0 -0
  265. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-undertaker +0 -0
  266. {rucio-35.7.0.dist-info → rucio-37.0.0rc2.dist-info}/WHEEL +0 -0
  267. {rucio-35.7.0.dist-info → rucio-37.0.0rc2.dist-info}/licenses/LICENSE +0 -0
  268. {rucio-35.7.0.dist-info → rucio-37.0.0rc2.dist-info}/top_level.txt +0 -0
rucio/core/rse_counter.py CHANGED
@@ -178,9 +178,8 @@ def fill_rse_counter_history_table(*, session: "Session"):
178
178
 
179
179
  :param session: Database session in use.
180
180
  """
181
- RSEUsageHistory = models.RSEUsageHistory
182
181
  stmt = select(
183
182
  models.RSEUsage
184
183
  )
185
184
  for usage in session.execute(stmt).scalars().all():
186
- RSEUsageHistory(rse_id=usage['rse_id'], used=usage['used'], files=usage['files'], source=usage['source']).save(session=session)
185
+ models.RSEUsageHistory(rse_id=usage['rse_id'], used=usage['used'], files=usage['files'], source=usage['source']).save(session=session)
@@ -15,11 +15,11 @@
15
15
  import abc
16
16
  import re
17
17
  from hashlib import sha256
18
- from typing import TYPE_CHECKING
18
+ from typing import TYPE_CHECKING, Any
19
19
 
20
20
  from dogpile.cache.api import NoValue
21
21
 
22
- from rucio.common.cache import make_region_memcached
22
+ from rucio.common.cache import MemcacheRegion
23
23
  from rucio.common.exception import InvalidRSEExpression, RSEWriteBlocked
24
24
  from rucio.core.rse import get_rse_attribute, get_rses_with_attribute, list_rses
25
25
  from rucio.db.sqla.session import transactional_session
@@ -37,7 +37,7 @@ COMPLEMENT = r'(\\%s)' % (PRIMITIVE)
37
37
 
38
38
  PATTERN = r'^%s(%s|%s|%s)*' % (PRIMITIVE, UNION, INTERSECTION, COMPLEMENT)
39
39
 
40
- REGION = make_region_memcached(expiration_time=600)
40
+ REGION = MemcacheRegion(expiration_time=600)
41
41
 
42
42
 
43
43
  @transactional_session
@@ -286,7 +286,7 @@ class RSEAttributeSmallerCheck(BaseExpressionElement):
286
286
  """
287
287
  Inherited from :py:func:`BaseExpressionElement.resolve_elements`
288
288
  """
289
- rse_list = get_rses_with_attribute(key=self.key, session=session)
289
+ rse_list: list[dict[str, Any]] = get_rses_with_attribute(key=self.key, session=session)
290
290
  if not rse_list:
291
291
  return (set(), {})
292
292
 
@@ -294,7 +294,7 @@ class RSEAttributeSmallerCheck(BaseExpressionElement):
294
294
  rse_dict = {}
295
295
  for rse in rse_list:
296
296
  try:
297
- if float(get_rse_attribute(rse['id'], self.key, session=session)) < float(self.value):
297
+ if float(get_rse_attribute(rse['id'], self.key, session=session)) < float(self.value): # type: ignore (get_rse_attribute could return None)
298
298
  rse_dict[rse['id']] = rse
299
299
  output.append(rse['id'])
300
300
  except ValueError:
@@ -321,7 +321,7 @@ class RSEAttributeLargerCheck(BaseExpressionElement):
321
321
  """
322
322
  Inherited from :py:func:`BaseExpressionElement.resolve_elements`
323
323
  """
324
- rse_list = get_rses_with_attribute(key=self.key, session=session)
324
+ rse_list: list[dict[str, Any]] = get_rses_with_attribute(key=self.key, session=session)
325
325
  if not rse_list:
326
326
  return (set(), {})
327
327
 
@@ -329,7 +329,7 @@ class RSEAttributeLargerCheck(BaseExpressionElement):
329
329
  rse_dict = {}
330
330
  for rse in rse_list:
331
331
  try:
332
- if float(get_rse_attribute(rse['id'], self.key, session=session)) > float(self.value):
332
+ if float(get_rse_attribute(rse['id'], self.key, session=session)) > float(self.value): # type: ignore (get_rse_attribute could return None)
333
333
  rse_dict[rse['id']] = rse
334
334
  output.append(rse['id'])
335
335
  except ValueError:
@@ -12,12 +12,10 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- from collections.abc import Iterable, Sequence
16
15
  from random import shuffle, uniform
17
16
  from typing import TYPE_CHECKING, Optional
18
17
 
19
18
  from rucio.common.exception import InsufficientAccountLimit, InsufficientTargetRSEs, InvalidRuleWeight, RSEOverQuota
20
- from rucio.common.types import InternalAccount
21
19
  from rucio.core.account import get_all_rse_usages_per_account, get_usage, has_account_attribute
22
20
  from rucio.core.account_limit import get_global_account_limits, get_local_account_limit
23
21
  from rucio.core.rse import get_rse_limits, has_rse_attribute, list_rse_attributes
@@ -26,8 +24,12 @@ from rucio.core.rse_expression_parser import parse_expression
26
24
  from rucio.db.sqla.session import read_session
27
25
 
28
26
  if TYPE_CHECKING:
27
+ from collections.abc import Iterable, Sequence
28
+
29
29
  from sqlalchemy.orm import Session
30
30
 
31
+ from rucio.common.types import InternalAccount
32
+
31
33
 
32
34
  class RSESelector:
33
35
  """
@@ -138,9 +140,9 @@ class RSESelector:
138
140
  def select_rse(
139
141
  self,
140
142
  size: int,
141
- preferred_rse_ids: Iterable[str],
143
+ preferred_rse_ids: "Iterable[str]",
142
144
  copies: int = 0,
143
- blocklist: Optional[Sequence[str]] = None,
145
+ blocklist: Optional["Sequence[str]"] = None,
144
146
  prioritize_order_over_weight: bool = False,
145
147
  existing_rse_size: Optional[dict[str, int]] = None
146
148
  ) -> list[tuple[str, bool, bool]]:
@@ -258,13 +260,13 @@ class RSESelector:
258
260
  @read_session
259
261
  def resolve_rse_expression(
260
262
  rse_expression: str,
261
- account: InternalAccount,
263
+ account: "InternalAccount",
262
264
  weight: Optional[int] = None,
263
265
  copies: int = 1,
264
266
  ignore_account_limit: bool = False,
265
267
  size: int = 0,
266
- preferred_rses: Optional[Iterable[str]] = None,
267
- blocklist: Optional[Sequence[str]] = None,
268
+ preferred_rses: Optional["Iterable[str]"] = None,
269
+ blocklist: Optional["Sequence[str]"] = None,
268
270
  prioritize_order_over_weight: bool = False,
269
271
  existing_rse_size: Optional[dict[str, int]] = None,
270
272
  *,
rucio/core/rule.py CHANGED
@@ -14,7 +14,6 @@
14
14
 
15
15
  import json
16
16
  import logging
17
- from collections.abc import Callable, Iterator, Sequence
18
17
  from configparser import NoOptionError, NoSectionError
19
18
  from copy import deepcopy
20
19
  from datetime import datetime, timedelta
@@ -36,7 +35,7 @@ from sqlalchemy.sql.expression import and_, false, null, or_, true, tuple_
36
35
  import rucio.core.did
37
36
  import rucio.core.lock # import get_replica_locks, get_files_and_replica_locks_of_dataset
38
37
  import rucio.core.replica # import get_and_lock_file_replicas, get_and_lock_file_replicas_for_dataset
39
- from rucio.common.cache import make_region_memcached
38
+ from rucio.common.cache import MemcacheRegion
40
39
  from rucio.common.config import config_get
41
40
  from rucio.common.constants import RseAttr
42
41
  from rucio.common.exception import (
@@ -84,10 +83,12 @@ from rucio.db.sqla.constants import OBSOLETE, BadFilesStatus, DIDAvailability, D
84
83
  from rucio.db.sqla.session import read_session, stream_session, transactional_session
85
84
 
86
85
  if TYPE_CHECKING:
86
+ from collections.abc import Callable, Iterator, Sequence
87
+
87
88
  from sqlalchemy.orm import Session
88
89
 
89
90
 
90
- REGION = make_region_memcached(expiration_time=900)
91
+ REGION = MemcacheRegion(expiration_time=900)
91
92
  METRICS = MetricManager(module=__name__)
92
93
  AutoApproveT = TypeVar('AutoApproveT', bound='AutoApprove')
93
94
 
@@ -113,7 +114,7 @@ class AutoApprove(PolicyPackageAlgorithms):
113
114
  return self.get_configured_algorithm()(self.rule, self.did, self.session)
114
115
 
115
116
  @classmethod
116
- def get_configured_algorithm(cls: type[AutoApproveT]) -> Callable[[models.ReplicationRule, models.DataIdentifier, 'Session'], bool]:
117
+ def get_configured_algorithm(cls: type[AutoApproveT]) -> "Callable[[models.ReplicationRule, models.DataIdentifier, Session], bool]":
117
118
  """
118
119
  Get the configured auto-approve algorithm
119
120
  """
@@ -125,7 +126,7 @@ class AutoApprove(PolicyPackageAlgorithms):
125
126
  return super()._get_one_algorithm(cls._algorithm_type, configured_algorithm)
126
127
 
127
128
  @classmethod
128
- def register(cls: type[AutoApproveT], name: str, fn_auto_approve: Callable[[models.ReplicationRule, models.DataIdentifier, 'Session'], bool]) -> None:
129
+ def register(cls: type[AutoApproveT], name: str, fn_auto_approve: "Callable[[models.ReplicationRule, models.DataIdentifier, Session], bool]") -> None:
129
130
  """
130
131
  Register a new auto-approve algorithm
131
132
  """
@@ -163,7 +164,7 @@ class AutoApprove(PolicyPackageAlgorithms):
163
164
 
164
165
  @transactional_session
165
166
  def add_rule(
166
- dids: Sequence[DIDDict],
167
+ dids: 'Sequence[DIDDict]',
167
168
  account: InternalAccount,
168
169
  copies: int,
169
170
  rse_expression: str,
@@ -477,8 +478,8 @@ def add_rule(
477
478
 
478
479
  @transactional_session
479
480
  def add_rules(
480
- dids: Sequence[DIDDict],
481
- rules: Sequence[RuleDict],
481
+ dids: 'Sequence[DIDDict]',
482
+ rules: 'Sequence[RuleDict]',
482
483
  *,
483
484
  session: "Session",
484
485
  logger: LoggerFunction = logging.log
@@ -954,7 +955,7 @@ def list_rules(
954
955
  filters: Optional[dict[str, Any]] = None,
955
956
  *,
956
957
  session: "Session"
957
- ) -> Iterator[dict[str, Any]]:
958
+ ) -> 'Iterator[dict[str, Any]]':
958
959
  """
959
960
  List replication rules.
960
961
 
@@ -1021,7 +1022,7 @@ def list_rule_history(
1021
1022
  rule_id: str,
1022
1023
  *,
1023
1024
  session: "Session"
1024
- ) -> Iterator[dict[str, Any]]:
1025
+ ) -> 'Iterator[dict[str, Any]]':
1025
1026
  """
1026
1027
  List the rule history of a rule.
1027
1028
 
@@ -1055,7 +1056,7 @@ def list_rule_full_history(
1055
1056
  name: str,
1056
1057
  *,
1057
1058
  session: "Session"
1058
- ) -> Iterator[dict[str, Any]]:
1059
+ ) -> 'Iterator[dict[str, Any]]':
1059
1060
  """
1060
1061
  List the rule history of a DID.
1061
1062
 
@@ -1094,7 +1095,7 @@ def list_associated_rules_for_file(
1094
1095
  name: str,
1095
1096
  *,
1096
1097
  session: "Session"
1097
- ) -> Iterator[dict[str, Any]]:
1098
+ ) -> 'Iterator[dict[str, Any]]':
1098
1099
  """
1099
1100
  List replication rules a file is affected from.
1100
1101
 
@@ -2110,7 +2111,7 @@ def get_updated_dids(
2110
2111
  total_workers: int,
2111
2112
  worker_number: int,
2112
2113
  limit: int = 100,
2113
- blocked_dids: Optional[Sequence[tuple[str, str]]] = None,
2114
+ blocked_dids: Optional['Sequence[tuple[str, str]]'] = None,
2114
2115
  *,
2115
2116
  session: "Session"
2116
2117
  ) -> list[tuple[str, InternalScope, str, DIDReEvaluation]]:
@@ -2196,7 +2197,7 @@ def get_expired_rules(
2196
2197
  total_workers: int,
2197
2198
  worker_number: int,
2198
2199
  limit: int = 100,
2199
- blocked_rules: Optional[Sequence[str]] = None,
2200
+ blocked_rules: Optional['Sequence[str]'] = None,
2200
2201
  *,
2201
2202
  session: "Session"
2202
2203
  ) -> list[tuple[str, str]]:
@@ -2246,7 +2247,7 @@ def get_injected_rules(
2246
2247
  total_workers: int,
2247
2248
  worker_number: int,
2248
2249
  limit: int = 100,
2249
- blocked_rules: Optional[Sequence[str]] = None,
2250
+ blocked_rules: Optional['Sequence[str]'] = None,
2250
2251
  *,
2251
2252
  session: "Session"
2252
2253
  ) -> list[str]:
@@ -2295,7 +2296,7 @@ def get_stuck_rules(
2295
2296
  worker_number: int,
2296
2297
  delta: int = 600,
2297
2298
  limit: int = 10,
2298
- blocked_rules: Optional[Sequence[str]] = None,
2299
+ blocked_rules: Optional['Sequence[str]'] = None,
2299
2300
  *,
2300
2301
  session: "Session"
2301
2302
  ) -> list[str]:
@@ -3152,7 +3153,7 @@ def list_rules_for_rse_decommissioning(
3152
3153
  rse_id: str,
3153
3154
  *,
3154
3155
  session: "Session"
3155
- ) -> Iterator[dict[str, Any]]:
3156
+ ) -> 'Iterator[dict[str, Any]]':
3156
3157
  """Return a generator of rules at the RSE that is being decommissioned.
3157
3158
 
3158
3159
  Decommissioning of an RSE involves deleting or moving away all rules that are
@@ -3215,13 +3216,13 @@ def list_rules_for_rse_decommissioning(
3215
3216
 
3216
3217
  @transactional_session
3217
3218
  def __find_missing_locks_and_create_them(
3218
- datasetfiles: Sequence[dict[str, Any]],
3219
- locks: dict[tuple[InternalScope, str], Sequence[models.ReplicaLock]],
3220
- replicas: dict[tuple[InternalScope, str], Sequence[models.CollectionReplica]],
3221
- source_replicas: dict[tuple[InternalScope, str], Sequence[models.CollectionReplica]],
3219
+ datasetfiles: 'Sequence[dict[str, Any]]',
3220
+ locks: dict[tuple[InternalScope, str], 'Sequence[models.ReplicaLock]'],
3221
+ replicas: dict[tuple[InternalScope, str], 'Sequence[models.CollectionReplica]'],
3222
+ source_replicas: dict[tuple[InternalScope, str], 'Sequence[models.CollectionReplica]'],
3222
3223
  rseselector: RSESelector,
3223
3224
  rule: models.ReplicationRule,
3224
- source_rses: Sequence[str],
3225
+ source_rses: 'Sequence[str]',
3225
3226
  *,
3226
3227
  session: "Session",
3227
3228
  logger: LoggerFunction = logging.log
@@ -3273,7 +3274,7 @@ def __find_missing_locks_and_create_them(
3273
3274
 
3274
3275
  @transactional_session
3275
3276
  def __find_surplus_locks_and_remove_them(
3276
- datasetfiles: Sequence[dict[str, Any]],
3277
+ datasetfiles: 'Sequence[dict[str, Any]]',
3277
3278
  locks: dict[tuple[InternalScope, str], list[models.ReplicaLock]],
3278
3279
  rule: models.ReplicationRule,
3279
3280
  *,
@@ -3324,13 +3325,13 @@ def __find_surplus_locks_and_remove_them(
3324
3325
 
3325
3326
  @transactional_session
3326
3327
  def __find_stuck_locks_and_repair_them(
3327
- datasetfiles: Sequence[dict[str, Any]],
3328
- locks: dict[tuple[InternalScope, str], Sequence[models.ReplicaLock]],
3329
- replicas: dict[tuple[InternalScope, str], Sequence[models.CollectionReplica]],
3330
- source_replicas: dict[tuple[InternalScope, str], Sequence[models.CollectionReplica]],
3328
+ datasetfiles: 'Sequence[dict[str, Any]]',
3329
+ locks: dict[tuple[InternalScope, str], 'Sequence[models.ReplicaLock]'],
3330
+ replicas: dict[tuple[InternalScope, str], 'Sequence[models.CollectionReplica]'],
3331
+ source_replicas: dict[tuple[InternalScope, str], 'Sequence[models.CollectionReplica]'],
3331
3332
  rseselector: RSESelector,
3332
3333
  rule: models.ReplicationRule,
3333
- source_rses: Sequence[str],
3334
+ source_rses: 'Sequence[str]',
3334
3335
  *,
3335
3336
  session: "Session",
3336
3337
  logger: LoggerFunction = logging.log
@@ -3802,8 +3803,8 @@ def __evaluate_did_attach(
3802
3803
  def __resolve_did_to_locks_and_replicas(
3803
3804
  did: models.DataIdentifier,
3804
3805
  nowait: bool = False,
3805
- restrict_rses: Optional[Sequence[str]] = None,
3806
- source_rses: Optional[Sequence[str]] = None,
3806
+ restrict_rses: Optional['Sequence[str]'] = None,
3807
+ source_rses: Optional['Sequence[str]'] = None,
3807
3808
  only_stuck: bool = False,
3808
3809
  *,
3809
3810
  session: "Session"
@@ -3908,10 +3909,10 @@ def __resolve_did_to_locks_and_replicas(
3908
3909
 
3909
3910
  @transactional_session
3910
3911
  def __resolve_dids_to_locks_and_replicas(
3911
- dids: Sequence[models.DataIdentifierAssociation],
3912
+ dids: 'Sequence[models.DataIdentifierAssociation]',
3912
3913
  nowait: bool = False,
3913
- restrict_rses: Optional[Sequence[str]] = None,
3914
- source_rses: Optional[Sequence[str]] = None,
3914
+ restrict_rses: Optional['Sequence[str]'] = None,
3915
+ source_rses: Optional['Sequence[str]'] = None,
3915
3916
  *,
3916
3917
  session: "Session"
3917
3918
  ) -> tuple[list[dict[str, Any]],
@@ -4078,14 +4079,14 @@ def __resolve_dids_to_locks_and_replicas(
4078
4079
 
4079
4080
  @transactional_session
4080
4081
  def __create_locks_replicas_transfers(
4081
- datasetfiles: Sequence[dict[str, Any]],
4082
- locks: dict[tuple[InternalScope, str], Sequence[models.ReplicaLock]],
4083
- replicas: dict[tuple[InternalScope, str], Sequence[models.CollectionReplica]],
4084
- source_replicas: dict[tuple[InternalScope, str], Sequence[models.CollectionReplica]],
4082
+ datasetfiles: 'Sequence[dict[str, Any]]',
4083
+ locks: dict[tuple[InternalScope, str], 'Sequence[models.ReplicaLock]'],
4084
+ replicas: dict[tuple[InternalScope, str], 'Sequence[models.CollectionReplica]'],
4085
+ source_replicas: dict[tuple[InternalScope, str], 'Sequence[models.CollectionReplica]'],
4085
4086
  rseselector: RSESelector,
4086
4087
  rule: models.ReplicationRule,
4087
- preferred_rse_ids: Optional[Sequence[str]] = None,
4088
- source_rses: Optional[Sequence[str]] = None,
4088
+ preferred_rse_ids: Optional['Sequence[str]'] = None,
4089
+ source_rses: Optional['Sequence[str]'] = None,
4089
4090
  *,
4090
4091
  session: "Session",
4091
4092
  logger: LoggerFunction = logging.log
@@ -4460,7 +4461,7 @@ def archive_localgroupdisk_datasets(
4460
4461
  @read_session
4461
4462
  def get_scratch_policy(
4462
4463
  account: InternalAccount,
4463
- rses: Sequence[dict[str, Any]],
4464
+ rses: 'Sequence[dict[str, Any]]',
4464
4465
  lifetime: Optional[int],
4465
4466
  *,
4466
4467
  session: "Session"
@@ -13,7 +13,6 @@
13
13
  # limitations under the License.
14
14
 
15
15
  import logging
16
- from collections.abc import Sequence
17
16
  from datetime import datetime
18
17
  from typing import TYPE_CHECKING, Any, Optional
19
18
 
@@ -26,29 +25,32 @@ import rucio.core.replica
26
25
  from rucio.common.config import config_get_int
27
26
  from rucio.common.constants import RseAttr
28
27
  from rucio.common.exception import InsufficientTargetRSEs
29
- from rucio.common.types import InternalScope
30
28
  from rucio.core import account_counter, rse_counter
31
29
  from rucio.core import request as request_core
32
30
  from rucio.core.rse import get_rse, get_rse_attribute, get_rse_name
33
- from rucio.core.rse_selector import RSESelector
34
31
  from rucio.db.sqla import models
35
32
  from rucio.db.sqla.constants import OBSOLETE, DIDType, LockState, ReplicaState, RequestType, RuleGrouping
36
33
  from rucio.db.sqla.session import transactional_session
37
34
 
38
35
  if TYPE_CHECKING:
36
+ from collections.abc import Sequence
37
+
39
38
  from sqlalchemy.orm import Session
40
39
 
40
+ from rucio.common.types import InternalScope
41
+ from rucio.core.rse_selector import RSESelector
42
+
41
43
 
42
44
  @transactional_session
43
45
  def apply_rule_grouping(
44
- datasetfiles: Sequence[dict[str, Any]],
45
- locks: dict[tuple[InternalScope, str], Sequence[models.ReplicaLock]],
46
- replicas: dict[tuple[InternalScope, str], Sequence[models.CollectionReplica]],
47
- source_replicas: dict[tuple[InternalScope, str], Sequence[models.CollectionReplica]],
48
- rseselector: RSESelector,
46
+ datasetfiles: "Sequence[dict[str, Any]]",
47
+ locks: dict[tuple["InternalScope", str], "Sequence[models.ReplicaLock]"],
48
+ replicas: dict[tuple["InternalScope", str], "Sequence[models.CollectionReplica]"],
49
+ source_replicas: dict[tuple["InternalScope", str], "Sequence[models.CollectionReplica]"],
50
+ rseselector: "RSESelector",
49
51
  rule: models.ReplicationRule,
50
- preferred_rse_ids: Optional[Sequence[str]] = None,
51
- source_rses: Optional[Sequence[str]] = None,
52
+ preferred_rse_ids: Optional["Sequence[str]"] = None,
53
+ source_rses: Optional["Sequence[str]"] = None,
52
54
  *,
53
55
  session: "Session"
54
56
  ) -> tuple[dict[str, list[dict[str, models.RSEFileAssociation]]],
@@ -116,12 +118,12 @@ def apply_rule_grouping(
116
118
 
117
119
  @transactional_session
118
120
  def repair_stuck_locks_and_apply_rule_grouping(
119
- datasetfiles: Sequence[dict[str, Any]],
120
- locks: dict[tuple[InternalScope, str], models.ReplicaLock],
121
- replicas: dict[tuple[InternalScope, str], Any],
122
- source_replicas: dict[tuple[InternalScope, str], Any],
123
- rseselector: RSESelector, rule: models.ReplicationRule,
124
- source_rses: Sequence[str],
121
+ datasetfiles: "Sequence[dict[str, Any]]",
122
+ locks: dict[tuple["InternalScope", str], models.ReplicaLock],
123
+ replicas: dict[tuple["InternalScope", str], Any],
124
+ source_replicas: dict[tuple["InternalScope", str], Any],
125
+ rseselector: "RSESelector", rule: models.ReplicationRule,
126
+ source_rses: "Sequence[str]",
125
127
  *,
126
128
  session: "Session"
127
129
  ) -> tuple[dict[str, list[dict[str, models.RSEFileAssociation]]],
@@ -228,14 +230,14 @@ def create_transfer_dict(dest_rse_id, request_type, scope, name, rule, lock=None
228
230
 
229
231
  @transactional_session
230
232
  def __apply_rule_to_files_none_grouping(
231
- datasetfiles: Sequence[dict[str, Any]],
232
- locks: dict[tuple[InternalScope, str], Sequence[models.ReplicaLock]],
233
- replicas: dict[tuple[InternalScope, str], Sequence[models.CollectionReplica]],
234
- source_replicas: dict[tuple[InternalScope, str], Sequence[models.CollectionReplica]],
235
- rseselector: RSESelector,
233
+ datasetfiles: "Sequence[dict[str, Any]]",
234
+ locks: dict[tuple["InternalScope", str], "Sequence[models.ReplicaLock]"],
235
+ replicas: dict[tuple["InternalScope", str], "Sequence[models.CollectionReplica]"],
236
+ source_replicas: dict[tuple["InternalScope", str], "Sequence[models.CollectionReplica]"],
237
+ rseselector: "RSESelector",
236
238
  rule: models.ReplicationRule,
237
- preferred_rse_ids: Optional[Sequence[str]] = None,
238
- source_rses: Optional[Sequence[str]] = None,
239
+ preferred_rse_ids: Optional["Sequence[str]"] = None,
240
+ source_rses: Optional["Sequence[str]"] = None,
239
241
  *,
240
242
  session: "Session"
241
243
  ) -> tuple[dict[str, list[dict[str, models.RSEFileAssociation]]],
@@ -329,14 +331,14 @@ def __apply_rule_to_files_none_grouping(
329
331
 
330
332
  @transactional_session
331
333
  def __apply_rule_to_files_all_grouping(
332
- datasetfiles: Sequence[dict[str, Any]],
333
- locks: dict[tuple[InternalScope, str], Sequence[models.ReplicaLock]],
334
- replicas: dict[tuple[InternalScope, str], Sequence[models.CollectionReplica]],
335
- source_replicas: dict[tuple[InternalScope, str], Sequence[models.CollectionReplica]],
336
- rseselector: RSESelector,
334
+ datasetfiles: "Sequence[dict[str, Any]]",
335
+ locks: dict[tuple["InternalScope", str], "Sequence[models.ReplicaLock]"],
336
+ replicas: dict[tuple["InternalScope", str], "Sequence[models.CollectionReplica]"],
337
+ source_replicas: dict[tuple["InternalScope", str], "Sequence[models.CollectionReplica]"],
338
+ rseselector: "RSESelector",
337
339
  rule: models.ReplicationRule,
338
- preferred_rse_ids: Optional[Sequence[str]] = None,
339
- source_rses: Optional[Sequence[str]] = None,
340
+ preferred_rse_ids: Optional["Sequence[str]"] = None,
341
+ source_rses: Optional["Sequence[str]"] = None,
340
342
  *,
341
343
  session: "Session"
342
344
  ) -> tuple[dict[str, list[dict[str, models.RSEFileAssociation]]],
@@ -480,14 +482,14 @@ def __apply_rule_to_files_all_grouping(
480
482
 
481
483
  @transactional_session
482
484
  def __apply_rule_to_files_dataset_grouping(
483
- datasetfiles: Sequence[dict[str, Any]],
484
- locks: dict[tuple[InternalScope, str], Sequence[models.ReplicaLock]],
485
- replicas: dict[tuple[InternalScope, str], Sequence[models.CollectionReplica]],
486
- source_replicas: dict[tuple[InternalScope, str], Sequence[models.CollectionReplica]],
487
- rseselector: RSESelector,
485
+ datasetfiles: "Sequence[dict[str, Any]]",
486
+ locks: dict[tuple["InternalScope", str], "Sequence[models.ReplicaLock]"],
487
+ replicas: dict[tuple["InternalScope", str], "Sequence[models.CollectionReplica]"],
488
+ source_replicas: dict[tuple["InternalScope", str], "Sequence[models.CollectionReplica]"],
489
+ rseselector: "RSESelector",
488
490
  rule: models.ReplicationRule,
489
- preferred_rse_ids: Optional[Sequence[str]] = None,
490
- source_rses: Optional[Sequence[str]] = None,
491
+ preferred_rse_ids: Optional["Sequence[str]"] = None,
492
+ source_rses: Optional["Sequence[str]"] = None,
491
493
  *,
492
494
  session: "Session"
493
495
  ) -> tuple[dict[str, list[dict[str, models.RSEFileAssociation]]],
@@ -1446,7 +1448,7 @@ def apply_rule(did, rule, rses, source_rses, rseselector, *, session: "Session",
1446
1448
  for ds_scope, ds_name in datasets:
1447
1449
  ds = rucio.core.did.get_did(scope=ds_scope, name=ds_name, dynamic_depth=DIDType.FILE, session=session) # this will be retrieved again later on -> could be optimized
1448
1450
  nbytes += ds['bytes']
1449
- one_rse_coverage = rucio.core.replica.get_RSEcoverage_of_dataset(scope=ds_scope, name=ds_name, session=session)
1451
+ one_rse_coverage = rucio.core.replica.get_rse_coverage_of_dataset(scope=ds_scope, name=ds_name, session=session)
1450
1452
  for rse_id, bytes_ in one_rse_coverage.items():
1451
1453
  rse_coverage[rse_id] = bytes_ + rse_coverage.get(rse_id, 0)
1452
1454
 
@@ -1472,7 +1474,7 @@ def apply_rule(did, rule, rses, source_rses, rseselector, *, session: "Session",
1472
1474
 
1473
1475
  if rule.grouping == RuleGrouping.DATASET:
1474
1476
  # calculate target RSEs
1475
- rse_coverage = rucio.core.replica.get_RSEcoverage_of_dataset(scope=ds_scope, name=ds_name, session=session)
1477
+ rse_coverage = rucio.core.replica.get_rse_coverage_of_dataset(scope=ds_scope, name=ds_name, session=session)
1476
1478
  # prnt(rse_coverage)
1477
1479
  preferred_rse_ids = [x[0] for x in sorted(rse_coverage.items(), key=lambda tup: tup[1], reverse=True)]
1478
1480
  # prnt(preferred_rse_ids)
@@ -1531,7 +1533,7 @@ def apply_rule(did, rule, rses, source_rses, rseselector, *, session: "Session",
1531
1533
  # prnt(rse_tuples)
1532
1534
  # keep track of used RSEs
1533
1535
  for rt in rse_tuples:
1534
- if not rt[0] in used_rse_ids:
1536
+ if rt[0] not in used_rse_ids:
1535
1537
  used_rse_ids.append(rt[0])
1536
1538
 
1537
1539
  for rse_id, staging_area, availability_write in rse_tuples:
rucio/core/scope.py CHANGED
@@ -20,7 +20,6 @@ from sqlalchemy import and_, select
20
20
  from sqlalchemy.exc import IntegrityError
21
21
 
22
22
  from rucio.common.exception import AccountNotFound, Duplicate, RucioException, VONotFound
23
- from rucio.common.types import InternalScope
24
23
  from rucio.core.vo import vo_exists
25
24
  from rucio.db.sqla import models
26
25
  from rucio.db.sqla.constants import AccountStatus, ScopeStatus
@@ -29,6 +28,8 @@ from rucio.db.sqla.session import read_session, transactional_session
29
28
  if TYPE_CHECKING:
30
29
  from sqlalchemy.orm import Session
31
30
 
31
+ from rucio.common.types import InternalScope
32
+
32
33
 
33
34
  @transactional_session
34
35
  def add_scope(scope, account, *, session: "Session"):
@@ -69,7 +70,7 @@ def add_scope(scope, account, *, session: "Session"):
69
70
 
70
71
 
71
72
  @read_session
72
- def bulk_add_scopes(scopes, account, skipExisting=False, *, session: "Session"):
73
+ def bulk_add_scopes(scopes, account, skip_existing=False, *, session: "Session"):
73
74
  """ add a group of scopes, this call should not be exposed to users.
74
75
 
75
76
  :param scopes: a list of scopes to be added.
@@ -81,12 +82,12 @@ def bulk_add_scopes(scopes, account, skipExisting=False, *, session: "Session"):
81
82
  try:
82
83
  add_scope(scope, account, session=session)
83
84
  except Duplicate:
84
- if not skipExisting:
85
+ if not skip_existing:
85
86
  raise
86
87
 
87
88
 
88
89
  @read_session
89
- def list_scopes(filter_: Optional[dict[str, Any]] = None, *, session: "Session") -> list[InternalScope]:
90
+ def list_scopes(filter_: Optional[dict[str, Any]] = None, *, session: "Session") -> list["InternalScope"]:
90
91
  """
91
92
  Lists all scopes.
92
93
  :param filter_: Dictionary of attributes by which the input data should be filtered
@@ -81,7 +81,6 @@ def add_subscription(name: str,
81
81
  except (NoOptionError, NoSectionError, RuntimeError):
82
82
  keep_history = False
83
83
 
84
- SubscriptionHistory = models.SubscriptionHistory
85
84
  retroactive = bool(retroactive) # Force boolean type, necessary for strict SQL
86
85
  state = SubscriptionState.ACTIVE
87
86
  if retroactive:
@@ -99,18 +98,18 @@ def add_subscription(name: str,
99
98
  retroactive=retroactive,
100
99
  policyid=priority, comments=comments)
101
100
  if keep_history:
102
- subscription_history = SubscriptionHistory(id=new_subscription.id,
103
- name=new_subscription.name,
104
- filter=new_subscription.filter,
105
- account=new_subscription.account,
106
- replication_rules=new_subscription.replication_rules,
107
- state=new_subscription.state,
108
- lifetime=new_subscription.lifetime,
109
- retroactive=new_subscription.retroactive,
110
- policyid=new_subscription.policyid,
111
- comments=new_subscription.comments,
112
- created_at=datetime.datetime.utcnow(),
113
- updated_at=datetime.datetime.utcnow())
101
+ subscription_history = models.SubscriptionHistory(id=new_subscription.id,
102
+ name=new_subscription.name,
103
+ filter=new_subscription.filter,
104
+ account=new_subscription.account,
105
+ replication_rules=new_subscription.replication_rules,
106
+ state=new_subscription.state,
107
+ lifetime=new_subscription.lifetime,
108
+ retroactive=new_subscription.retroactive,
109
+ policyid=new_subscription.policyid,
110
+ comments=new_subscription.comments,
111
+ created_at=datetime.datetime.utcnow(),
112
+ updated_at=datetime.datetime.utcnow())
114
113
  try:
115
114
  new_subscription.save(session=session)
116
115
  if keep_history:
@@ -171,7 +170,6 @@ def update_subscription(name: str,
171
170
  values['state'] = SubscriptionState.INACTIVE
172
171
  values['expired_at'] = datetime.datetime.utcnow()
173
172
 
174
- SubscriptionHistory = models.SubscriptionHistory
175
173
  try:
176
174
  stmt = select(
177
175
  models.Subscription
@@ -191,20 +189,20 @@ def update_subscription(name: str,
191
189
 
192
190
  subscription.update(values)
193
191
  if keep_history and current_subscription_state != new_subscription_state:
194
- subscription_history = SubscriptionHistory(id=subscription.id,
195
- name=subscription.name,
196
- filter=subscription.filter,
197
- account=subscription.account,
198
- replication_rules=subscription.replication_rules,
199
- state=subscription.state,
200
- lifetime=subscription.lifetime,
201
- retroactive=subscription.retroactive,
202
- policyid=subscription.policyid,
203
- comments=subscription.comments,
204
- last_processed=subscription.last_processed,
205
- expired_at=subscription.expired_at,
206
- updated_at=datetime.datetime.utcnow(),
207
- created_at=subscription.created_at)
192
+ subscription_history = models.SubscriptionHistory(id=subscription.id,
193
+ name=subscription.name,
194
+ filter=subscription.filter,
195
+ account=subscription.account,
196
+ replication_rules=subscription.replication_rules,
197
+ state=subscription.state,
198
+ lifetime=subscription.lifetime,
199
+ retroactive=subscription.retroactive,
200
+ policyid=subscription.policyid,
201
+ comments=subscription.comments,
202
+ last_processed=subscription.last_processed,
203
+ expired_at=subscription.expired_at,
204
+ updated_at=datetime.datetime.utcnow(),
205
+ created_at=subscription.created_at)
208
206
  subscription_history.save(session=session)
209
207
  except NoResultFound:
210
208
  raise SubscriptionNotFound(f"Subscription for account '{account}' named '{name}' not found")