rucio-clients 37.3.0__py3-none-any.whl → 37.5.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-clients might be problematic. Click here for more details.

Files changed (41) hide show
  1. rucio/cli/rule.py +1 -1
  2. rucio/client/accountclient.py +205 -60
  3. rucio/client/accountlimitclient.py +84 -25
  4. rucio/client/baseclient.py +85 -48
  5. rucio/client/client.py +49 -41
  6. rucio/client/configclient.py +36 -13
  7. rucio/client/credentialclient.py +16 -6
  8. rucio/client/didclient.py +321 -133
  9. rucio/client/diracclient.py +13 -6
  10. rucio/client/downloadclient.py +435 -165
  11. rucio/client/exportclient.py +8 -2
  12. rucio/client/fileclient.py +10 -3
  13. rucio/client/importclient.py +4 -1
  14. rucio/client/lifetimeclient.py +48 -31
  15. rucio/client/lockclient.py +22 -7
  16. rucio/client/metaconventionsclient.py +59 -21
  17. rucio/client/pingclient.py +3 -1
  18. rucio/client/replicaclient.py +213 -96
  19. rucio/client/requestclient.py +124 -16
  20. rucio/client/rseclient.py +385 -160
  21. rucio/client/ruleclient.py +147 -51
  22. rucio/client/scopeclient.py +35 -10
  23. rucio/client/subscriptionclient.py +60 -27
  24. rucio/client/touchclient.py +16 -7
  25. rucio/common/constants.py +14 -17
  26. rucio/common/utils.py +18 -2
  27. rucio/rse/rsemanager.py +2 -2
  28. rucio/vcsversion.py +3 -3
  29. {rucio_clients-37.3.0.data → rucio_clients-37.5.0.data}/data/etc/rucio.cfg.template +0 -1
  30. {rucio_clients-37.3.0.dist-info → rucio_clients-37.5.0.dist-info}/METADATA +1 -1
  31. {rucio_clients-37.3.0.dist-info → rucio_clients-37.5.0.dist-info}/RECORD +41 -41
  32. {rucio_clients-37.3.0.dist-info → rucio_clients-37.5.0.dist-info}/WHEEL +1 -1
  33. {rucio_clients-37.3.0.data → rucio_clients-37.5.0.data}/data/etc/rse-accounts.cfg.template +0 -0
  34. {rucio_clients-37.3.0.data → rucio_clients-37.5.0.data}/data/etc/rucio.cfg.atlas.client.template +0 -0
  35. {rucio_clients-37.3.0.data → rucio_clients-37.5.0.data}/data/requirements.client.txt +0 -0
  36. {rucio_clients-37.3.0.data → rucio_clients-37.5.0.data}/data/rucio_client/merge_rucio_configs.py +0 -0
  37. {rucio_clients-37.3.0.data → rucio_clients-37.5.0.data}/scripts/rucio +0 -0
  38. {rucio_clients-37.3.0.data → rucio_clients-37.5.0.data}/scripts/rucio-admin +0 -0
  39. {rucio_clients-37.3.0.dist-info → rucio_clients-37.5.0.dist-info}/licenses/AUTHORS.rst +0 -0
  40. {rucio_clients-37.3.0.dist-info → rucio_clients-37.5.0.dist-info}/licenses/LICENSE +0 -0
  41. {rucio_clients-37.3.0.dist-info → rucio_clients-37.5.0.dist-info}/top_level.txt +0 -0
@@ -54,27 +54,52 @@ class RuleClient(BaseClient):
54
54
  weight: Optional[int] = None,
55
55
  ) -> Any:
56
56
  """
57
- :param dids: The data identifier set.
58
- :param copies: The number of replicas.
59
- :param rse_expression: Boolean string expression to give the list of RSEs.
60
- :param priority: Priority of the transfers.
61
- :param lifetime: The lifetime of the replication rules (in seconds).
62
- :param grouping: ALL - All files will be replicated to the same RSE.
63
- DATASET - All files in the same dataset will be replicated to the same RSE.
64
- NONE - Files will be completely spread over all allowed RSEs without any grouping considerations at all.
65
- :param notify: Notification setting for the rule (Y, N, C).
66
- :param source_replica_expression: RSE Expression for RSEs to be considered for source replicas.
67
- :param activity: Transfer Activity to be passed to FTS.
68
- :param account: The account owning the rule.
69
- :param meta: Metadata, as dictionary.
70
- :param ignore_availability: Option to ignore the availability of RSEs.
71
- :param purge_replicas: When the rule gets deleted purge the associated replicas immediately.
72
- :param ask_approval: Ask for approval of this replication rule.
73
- :param asynchronous: Create rule asynchronously by judge-injector.
74
- :param locked: If the rule is locked, it cannot be deleted.
75
- :param delay_injection:
76
- :param comment: Comment about the rule.
77
- :param weight: If the weighting option of the replication rule is used, the choice of RSEs takes their weight into account.
57
+ Add a replication rule.
58
+
59
+ Parameters
60
+ ----------
61
+ dids :
62
+ The data identifier set.
63
+ copies :
64
+ The number of replicas.
65
+ rse_expression :
66
+ Boolean string expression to give the list of RSEs.
67
+ priority :
68
+ Priority of the transfers. Default is 3.
69
+ lifetime :
70
+ The lifetime of the replication rules (in seconds).
71
+ grouping :
72
+ ALL - All files will be replicated to the same RSE.
73
+ DATASET - All files in the same dataset will be replicated to the same RSE.
74
+ NONE - Files will be completely spread over all allowed RSEs without any grouping considerations at all.
75
+ Default is 'DATASET'.
76
+ notify :
77
+ Notification setting for the rule (Y, N, C). Default is 'N'.
78
+ source_replica_expression :
79
+ RSE Expression for RSEs to be considered for source replicas.
80
+ activity :
81
+ Transfer Activity to be passed to FTS.
82
+ account :
83
+ The account owning the rule.
84
+ meta :
85
+ Metadata, as dictionary.
86
+ ignore_availability :
87
+ Option to ignore the availability of RSEs. Default is False.
88
+ purge_replicas :
89
+ When the rule gets deleted purge the associated replicas immediately. Default is False.
90
+ ask_approval :
91
+ Ask for approval of this replication rule. Default is False.
92
+ asynchronous :
93
+ Create rule asynchronously by judge-injector. Default is False.
94
+ locked :
95
+ If the rule is locked, it cannot be deleted. Default is False.
96
+ delay_injection :
97
+ Delay the rule injection.
98
+ comment :
99
+ Comment about the rule.
100
+ weight :
101
+ If the weighting option of the replication rule is used, the choice of RSEs takes their weight into account.
102
+
78
103
  """
79
104
  path = self.RULE_BASEURL + '/'
80
105
  url = build_url(choice(self.list_hosts), path=path)
@@ -97,9 +122,17 @@ class RuleClient(BaseClient):
97
122
  """
98
123
  Deletes a replication rule and all associated locks.
99
124
 
100
- :param rule_id: The id of the rule to be deleted
101
- :param purge_replicas: Immediately delete the replicas.
102
- :raises: RuleNotFound, AccessDenied
125
+ Parameters
126
+ ----------
127
+ rule_id :
128
+ The id of the rule to be deleted.
129
+ purge_replicas :
130
+ Immediate delete the replicas
131
+
132
+ Raises
133
+ -------
134
+ RuleNotFound
135
+ AccessDenied
103
136
  """
104
137
 
105
138
  path = self.RULE_BASEURL + '/' + rule_id
@@ -118,8 +151,14 @@ class RuleClient(BaseClient):
118
151
  """
119
152
  Get a replication rule.
120
153
 
121
- :param rule_id: The id of the rule to be retrieved.
122
- :raises: RuleNotFound
154
+ Parameters
155
+ ----------
156
+ rule_id :
157
+ The id of the rule to be retrieved.
158
+
159
+ Raises
160
+ -------
161
+ RuleNotFound
123
162
  """
124
163
  path = self.RULE_BASEURL + '/' + rule_id
125
164
  url = build_url(choice(self.list_hosts), path=path)
@@ -132,9 +171,16 @@ class RuleClient(BaseClient):
132
171
 
133
172
  def update_replication_rule(self, rule_id: str, options: dict[str, Any]) -> Literal[True]:
134
173
  """
135
- :param rule_id: The id of the rule to be retrieved.
136
- :param options: Options dictionary.
137
- :raises: RuleNotFound
174
+ Parameters
175
+ ----------
176
+ rule_id :
177
+ The id of the rule to be retrieved.
178
+ options :
179
+ Options dictionary.
180
+
181
+ Raises
182
+ -------
183
+ RuleNotFound
138
184
  """
139
185
  path = self.RULE_BASEURL + '/' + rule_id
140
186
  url = build_url(choice(self.list_hosts), path=path)
@@ -152,10 +198,19 @@ class RuleClient(BaseClient):
152
198
  exclude_expression: Optional[str] = None
153
199
  ) -> Any:
154
200
  """
155
- :param rule_id: Rule to be reduced.
156
- :param copies: Number of copies of the new rule.
157
- :param exclude_expression: RSE Expression of RSEs to exclude.
158
- :raises: RuleReplaceFailed, RuleNotFound
201
+ Parameters
202
+ ----------
203
+ rule_id :
204
+ The id of the rule to be reduced.
205
+ copies :
206
+ Number of copies of the new rule.
207
+ exclude_expression :
208
+ RSE Expression of RSEs to exclude.
209
+
210
+ Raises
211
+ -------
212
+ RuleNotFound
213
+ RuleReplaceFailed
159
214
  """
160
215
 
161
216
  path = self.RULE_BASEURL + '/' + rule_id + '/reduce'
@@ -176,10 +231,18 @@ class RuleClient(BaseClient):
176
231
  """
177
232
  Move a replication rule to another RSE and, once done, delete the original one.
178
233
 
179
- :param rule_id: Rule to be moved.
180
- :param rse_expression: RSE expression of the new rule.
181
- :param override: Configurations to update for the new rule.
182
- :raises: RuleNotFound, RuleReplaceFailed
234
+ Parameters
235
+ ----------
236
+ rule_id :
237
+ Rule to be moved.
238
+ rse_expression :
239
+ RSE expression of the new rule.
240
+ override :
241
+ Configurations to update for the new rule.
242
+ Raises
243
+ -------
244
+ RuleNotFound
245
+ RuleReplaceFailed
183
246
  """
184
247
 
185
248
  path = self.RULE_BASEURL + '/' + rule_id + '/move'
@@ -197,8 +260,14 @@ class RuleClient(BaseClient):
197
260
 
198
261
  def approve_replication_rule(self, rule_id: str) -> Literal[True]:
199
262
  """
200
- :param rule_id: Rule to be approved.
201
- :raises: RuleNotFound
263
+ Parameters
264
+ ----------
265
+ rule_id :
266
+ Rule to be approved.
267
+
268
+ Raises
269
+ -------
270
+ RuleNotFound
202
271
  """
203
272
 
204
273
  path = self.RULE_BASEURL + '/' + rule_id
@@ -212,9 +281,17 @@ class RuleClient(BaseClient):
212
281
 
213
282
  def deny_replication_rule(self, rule_id: str, reason: Optional[str] = None) -> Literal[True]:
214
283
  """
215
- :param rule_id: Rule to be denied.
216
- :param reason: Reason for denying the rule.
217
- :raises: RuleNotFound
284
+ Parameters
285
+ ----------
286
+ rule_id :
287
+ Rule to be denied.
288
+ reason :
289
+ Reason for denying the rule.
290
+
291
+ Raises
292
+ -------
293
+ RuleNotFound
294
+
218
295
  """
219
296
 
220
297
  path = self.RULE_BASEURL + '/' + rule_id
@@ -235,8 +312,12 @@ class RuleClient(BaseClient):
235
312
  """
236
313
  List the rule history of a DID.
237
314
 
238
- :param scope: The scope of the DID.
239
- :param name: The name of the DID.
315
+ Parameters
316
+ ----------
317
+ scope :
318
+ The scope of the DID.
319
+ name :
320
+ The name of the DID.
240
321
  """
241
322
  path = '/'.join([self.RULE_BASEURL, quote_plus(scope), quote_plus(name), 'history'])
242
323
  url = build_url(choice(self.list_hosts), path=path)
@@ -250,8 +331,13 @@ class RuleClient(BaseClient):
250
331
  """
251
332
  Examine a replication rule for errors during transfer.
252
333
 
253
- :param rule_id: Rule to be denied.
254
- :raises: RuleNotFound
334
+ Parameters
335
+ ----------
336
+ rule_id :
337
+ The rule to be denied
338
+ Raises
339
+ -------
340
+ RuleNotFound
255
341
  """
256
342
  path = self.RULE_BASEURL + '/' + rule_id + '/analysis'
257
343
  url = build_url(choice(self.list_hosts), path=path)
@@ -265,8 +351,13 @@ class RuleClient(BaseClient):
265
351
  """
266
352
  List details of all replica locks for a rule.
267
353
 
268
- :param rule_id: Rule to be denied.
269
- :raises: RuleNotFound
354
+ Parameters
355
+ ----------
356
+ rule_id :
357
+ The rule to be denied
358
+ Raises
359
+ -------
360
+ RuleNotFound
270
361
  """
271
362
  path = self.RULE_BASEURL + '/' + rule_id + '/locks'
272
363
  url = build_url(choice(self.list_hosts), path=path)
@@ -279,9 +370,14 @@ class RuleClient(BaseClient):
279
370
  def list_replication_rules(self, filters: Optional[dict[str, Any]] = None) -> "Iterator[dict[str, Any]]":
280
371
  """
281
372
  List all replication rules which match a filter
282
- :param filters: dictionary of attributes by which the rules should be filtered
283
-
284
- :returns: True if successful, otherwise false.
373
+ Parameters
374
+ ----------
375
+ filers:
376
+ dictionary of attributes by which the rules should be filtered
377
+
378
+ Returns
379
+ -------
380
+ True if successful, otherwise false.
285
381
  """
286
382
  filters = filters or {}
287
383
  path = self.RULE_BASEURL + '/'
@@ -35,11 +35,23 @@ class ScopeClient(BaseClient):
35
35
  """
36
36
  Sends the request to add a new scope.
37
37
 
38
- :param account: the name of the account to add the scope to.
39
- :param scope: the name of the new scope.
40
- :return: True if scope was created successfully.
41
- :raises Duplicate: if scope already exists.
42
- :raises AccountNotFound: if account doesn't exist.
38
+ Parameters
39
+ ----------
40
+ account :
41
+ The name of the account to add the scope to.
42
+ scope :
43
+ The name of the new scope.
44
+
45
+ Returns
46
+ -------
47
+ True if scope was created successfully.
48
+
49
+ Raises
50
+ ------
51
+ Duplicate
52
+ If scope already exists.
53
+ AccountNotFound
54
+ If account doesn't exist.
43
55
  """
44
56
 
45
57
  path = '/'.join([self.SCOPE_BASEURL, account, 'scopes', quote_plus(scope)])
@@ -55,7 +67,9 @@ class ScopeClient(BaseClient):
55
67
  """
56
68
  Sends the request to list all scopes.
57
69
 
58
- :return: a list containing the names of all scopes.
70
+ Returns
71
+ -------
72
+ A list containing the names of all scopes.
59
73
  """
60
74
 
61
75
  path = '/'.join(['scopes/'])
@@ -72,10 +86,21 @@ class ScopeClient(BaseClient):
72
86
  """
73
87
  Sends the request to list all scopes for a rucio account.
74
88
 
75
- :param account: the rucio account to list scopes for.
76
- :return: a list containing the names of all scopes for a rucio account.
77
- :raises AccountNotFound: if account doesn't exist.
78
- :raises ScopeNotFound: if no scopes exist for account.
89
+ Parameters
90
+ ----------
91
+ account :
92
+ The rucio account to list scopes for.
93
+
94
+ Returns
95
+ -------
96
+ A list containing the names of all scopes for a rucio account.
97
+
98
+ Raises
99
+ ------
100
+ AccountNotFound
101
+ If account doesn't exist.
102
+ ScopeNotFound
103
+ If no scopes exist for account.
79
104
  """
80
105
 
81
106
  path = '/'.join([self.SCOPE_BASEURL, account, 'scopes/'])
@@ -45,16 +45,28 @@ class SubscriptionClient(BaseClient):
45
45
  """
46
46
  Adds a new subscription which will be verified against every new added file and dataset
47
47
 
48
- :param name: Name of the subscription
49
- :param account: Account identifier
50
- :param filter_: Dictionary of attributes by which the input data should be filtered
51
- **Example**: ``{'dsn': 'data11_hi*.express_express.*,data11_hi*physics_MinBiasOverlay*', 'account': 'tzero'}``
52
- :param replication_rules: Replication rules to be set : Dictionary with keys copies, rse_expression, weight, rse_expression
53
- :param comments: Comments for the subscription
54
- :param lifetime: Subscription's lifetime (days); False if subscription has no lifetime
55
- :param retroactive: Flag to know if the subscription should be applied on previous data
56
- :param dry_run: Just print the subscriptions actions without actually executing them (Useful if retroactive flag is set)
57
- :param priority: The priority of the subscription (3 by default)
48
+ Parameters
49
+ ----------
50
+ name :
51
+ Name of the subscription
52
+ account :
53
+ Account identifier
54
+ filter_ :
55
+ Dictionary of attributes by which the input data should be filtered
56
+ Example: `{'dsn': 'data11_hi*.express_express.*,data11_hi*physics_MinBiasOverlay*', 'account': 'tzero'}`
57
+ replication_rules :
58
+ Replication rules to be set. Dictionary with keys copies, rse_expression, weight, rse_expression
59
+ comments :
60
+ Comments for the subscription
61
+ lifetime :
62
+ Subscription's lifetime (days); False if subscription has no lifetime
63
+ retroactive :
64
+ Flag to know if the subscription should be applied on previous data
65
+ dry_run :
66
+ Just print the subscriptions actions without actually executing them (Useful if retroactive flag is set)
67
+ priority :
68
+ The priority of the subscription (3 by default)
69
+
58
70
  """
59
71
  path = self.SUB_BASEURL + '/' + account + '/' + name
60
72
  url = build_url(choice(self.list_hosts), path=path)
@@ -82,10 +94,21 @@ class SubscriptionClient(BaseClient):
82
94
  Returns a dictionary with the subscription information :
83
95
  Examples: ``{'status': 'INACTIVE/ACTIVE/BROKEN', 'last_modified_date': ...}``
84
96
 
85
- :param name: Name of the subscription
86
- :param account: Account identifier
87
- :returns: Dictionary containing subscription parameter
88
- :raises: exception.NotFound if subscription is not found
97
+ Parameters
98
+ ----------
99
+ name :
100
+ Name of the subscription
101
+ account :
102
+ Account identifier
103
+
104
+ Returns
105
+ -------
106
+ Dictionary with the subscription information
107
+
108
+ Raises
109
+ -------
110
+ NotFound
111
+ If subscription is not found
89
112
  """
90
113
  path = self.SUB_BASEURL
91
114
  if account:
@@ -120,17 +143,23 @@ class SubscriptionClient(BaseClient):
120
143
  """
121
144
  Updates a subscription
122
145
 
123
- :param name: Name of the subscription
124
- :param account: Account identifier
125
- :param filter_: Dictionary of attributes by which the input data should be filtered
126
- **Example**: ``{'dsn': 'data11_hi*.express_express.*,data11_hi*physics_MinBiasOverlay*', 'account': 'tzero'}``
127
- :param replication_rules: Replication rules to be set : Dictionary with keys copies, rse_expression, weight, rse_expression
128
- :param comments: Comments for the subscription
129
- :param lifetime: Subscription's lifetime (days); False if subscription has no lifetime
130
- :param retroactive: Flag to know if the subscription should be applied on previous data
131
- :param dry_run: Just print the subscriptions actions without actually executing them (Useful if retroactive flag is set)
132
- :param priority: The priority of the subscription
133
- :raises: exception.NotFound if subscription is not found
146
+ Parameters
147
+ ----------
148
+ name : Name of the subscription
149
+ account : Account identifier
150
+ filter_ : Dictionary of attributes by which the input data should be filtered
151
+ Example: `{'dsn': 'data11_hi*.express_express.*,data11_hi*physics_MinBiasOverlay*', 'account': 'tzero'}`
152
+ replication_rules : Replication rules to be set. Dictionary with keys copies, rse_expression, weight, rse_expression
153
+ comments : Comments for the subscription
154
+ lifetime : Subscription's lifetime (days); False if subscription has no lifetime
155
+ retroactive : Flag to know if the subscription should be applied on previous data
156
+ dry_run : Just print the subscriptions actions without actually executing them (Useful if retroactive flag is set)
157
+ priority : The priority of the subscription
158
+
159
+ Raises
160
+ ------
161
+ NotFound
162
+ If subscription is not found
134
163
  """
135
164
  if not account:
136
165
  account = self.account
@@ -159,8 +188,12 @@ class SubscriptionClient(BaseClient):
159
188
  """
160
189
  List the associated rules of a subscription.
161
190
 
162
- :param account: Account of the subscription.
163
- :param name: Name of the subscription.
191
+ Parameters
192
+ ----------
193
+ account :
194
+ Account of the subscription.
195
+ name :
196
+ Name of the subscription.
164
197
  """
165
198
 
166
199
  path = '/'.join([self.SUB_BASEURL, account, name, 'rules'])
@@ -40,13 +40,22 @@ class TouchClient(BaseClient):
40
40
  """
41
41
  Sends a touch trace for a given file or dataset.
42
42
 
43
- :param scope: the scope of the file/dataset to update.
44
- :param name: the name of file/dataset to update.
45
- :param rse: optional parameter if a specific replica should be touched.
46
- :raises DataIdentifierNotFound: if given dids does not exist.
47
- :raises RSENotFound: if rse is not None and given rse does not exist.
48
- :raises UnsupportedDIDType: if type of the given DID is not FILE or DATASET.
49
- :raises RucioException: if trace could not be sent successfully.
43
+ Parameters
44
+ ----------
45
+ scope : The scope of the file/dataset to update.
46
+ name : The name of file/dataset to update.
47
+ rse : Optional parameter if a specific replica should be touched.
48
+
49
+ Raises
50
+ ------
51
+ DataIdentifierNotFound
52
+ If given dids does not exist.
53
+ RSENotFound
54
+ If rse is not None and given rse does not exist.
55
+ UnsupportedDIDType
56
+ If type of the given DID is not FILE or DATASET.
57
+ RucioException
58
+ If trace could not be sent successfully.
50
59
  """
51
60
 
52
61
  trace = {}
rucio/common/constants.py CHANGED
@@ -16,8 +16,6 @@ import enum
16
16
  from collections import namedtuple
17
17
  from typing import Literal, get_args
18
18
 
19
- from rucio.common.config import config_get_bool
20
-
21
19
  """
22
20
  Constants.
23
21
 
@@ -32,21 +30,16 @@ RESERVED_KEYS = ['scope', 'name', 'account', 'did_type', 'is_open', 'monotonic',
32
30
  KEY_TYPES = ['ALL', 'COLLECTION', 'FILE', 'DERIVED']
33
31
  # all(container, dataset, file), collection(dataset or container), file, derived(compute from file for collection)
34
32
 
35
- SCHEME_MAP = {'srm': ['srm', 'gsiftp'],
36
- 'gsiftp': ['srm', 'gsiftp'],
37
- 'https': ['https', 'davs', 'srm+https', 'cs3s'],
38
- 'davs': ['https', 'davs', 'srm+https', 'cs3s'],
39
- 'srm+https': ['https', 'davs', 'srm+https', 'cs3s'],
40
- 'cs3s': ['https', 'davs', 'srm+https', 'cs3s'],
41
- 'root': ['root'],
42
- 'scp': ['scp'],
43
- 'rsync': ['rsync'],
44
- 'rclone': ['rclone']}
45
- if config_get_bool('transfers', 'srm_https_compatibility', raise_exception=False, default=False):
46
- SCHEME_MAP['srm'].append('https')
47
- SCHEME_MAP['https'].append('srm')
48
- SCHEME_MAP['srm'].append('davs')
49
- SCHEME_MAP['davs'].append('srm')
33
+ BASE_SCHEME_MAP = {'srm': ['srm', 'gsiftp'],
34
+ 'gsiftp': ['srm', 'gsiftp'],
35
+ 'https': ['https', 'davs', 'srm+https', 'cs3s'],
36
+ 'davs': ['https', 'davs', 'srm+https', 'cs3s'],
37
+ 'srm+https': ['https', 'davs', 'srm+https', 'cs3s'],
38
+ 'cs3s': ['https', 'davs', 'srm+https', 'cs3s'],
39
+ 'root': ['root'],
40
+ 'scp': ['scp'],
41
+ 'rsync': ['rsync'],
42
+ 'rclone': ['rclone']}
50
43
 
51
44
  SORTING_ALGORITHMS_LITERAL = Literal['geoip', 'custom_table', 'random']
52
45
  SORTING_ALGORITHMS = list(get_args(SORTING_ALGORITHMS_LITERAL))
@@ -76,6 +69,10 @@ FTS_JOB_TYPE = namedtuple('FTS_JOB_TYPE', ['MULTIPLE_REPLICA', 'MULTI_HOP', 'SES
76
69
 
77
70
  MAX_MESSAGE_LENGTH = 4000
78
71
 
72
+ @enum.unique
73
+ class TransferLimitDirection(enum.Enum):
74
+ SOURCE = 'S'
75
+ DESTINATION = 'D'
79
76
 
80
77
  @enum.unique
81
78
  class SuspiciousAvailability(enum.Enum):
rucio/common/utils.py CHANGED
@@ -32,7 +32,7 @@ import threading
32
32
  import time
33
33
  from collections import OrderedDict
34
34
  from enum import Enum
35
- from functools import wraps
35
+ from functools import cache, wraps
36
36
  from io import StringIO
37
37
  from itertools import zip_longest
38
38
  from typing import TYPE_CHECKING, Any, Optional, TypeVar, Union
@@ -42,7 +42,8 @@ from xml.etree import ElementTree
42
42
 
43
43
  import requests
44
44
 
45
- from rucio.common.config import config_get
45
+ from rucio.common.config import config_get, config_get_bool
46
+ from rucio.common.constants import BASE_SCHEME_MAP
46
47
  from rucio.common.exception import DIDFilterSyntaxError, DuplicateCriteriaInDIDFilter, InputValidationError, InvalidType, MetalinkJsonParsingError, MissingModuleException, RucioException
47
48
  from rucio.common.extra import import_extras
48
49
  from rucio.common.plugins import PolicyPackageAlgorithms
@@ -1690,3 +1691,18 @@ def is_method_overridden(obj, base_cls, method_name):
1690
1691
  if getattr(type(obj), method_name, None) is getattr(base_cls, method_name, None): # Caring for bound/unbound cases
1691
1692
  return False
1692
1693
  return True
1694
+
1695
+
1696
+ @cache
1697
+ def get_transfer_schemas() -> dict[str, list[str]]:
1698
+ """
1699
+ Extend base schema map based on SRM HTTPS compatibility.
1700
+ """
1701
+ scheme_map = BASE_SCHEME_MAP
1702
+ if config_get_bool('transfers', 'srm_https_compatibility', raise_exception=False, default=False):
1703
+ scheme_map['srm'].append('https')
1704
+ scheme_map['https'].append('srm')
1705
+ scheme_map['srm'].append('davs')
1706
+ scheme_map['davs'].append('srm')
1707
+
1708
+ return scheme_map
rucio/rse/rsemanager.py CHANGED
@@ -24,7 +24,7 @@ from rucio.common.checksum import GLOBALLY_SUPPORTED_CHECKSUMS
24
24
  from rucio.common.config import config_get_int
25
25
  from rucio.common.constraints import STRING_TYPES
26
26
  from rucio.common.logging import formatted_logger
27
- from rucio.common.utils import make_valid_did
27
+ from rucio.common.utils import get_transfer_schemas, make_valid_did
28
28
 
29
29
  if TYPE_CHECKING:
30
30
  from collections.abc import Callable
@@ -875,7 +875,7 @@ def __check_compatible_scheme(
875
875
 
876
876
  if dest_scheme == src_scheme:
877
877
  return True
878
- if src_scheme in constants.SCHEME_MAP.get(dest_scheme, []):
878
+ if src_scheme in get_transfer_schemas().get(dest_scheme, []):
879
879
  return True
880
880
 
881
881
  return False
rucio/vcsversion.py CHANGED
@@ -4,8 +4,8 @@ This file is automatically generated; Do not edit it. :)
4
4
  '''
5
5
  VERSION_INFO = {
6
6
  'final': True,
7
- 'version': '37.3.0',
7
+ 'version': '37.5.0',
8
8
  'branch_nick': 'release-37',
9
- 'revision_id': '874ee3e820d3ff64ab941ccfe8a02906b5540066',
10
- 'revno': 13716
9
+ 'revision_id': '092cfe864848019a987a3a167120cf5cf7df2f61',
10
+ 'revno': 13761
11
11
  }
@@ -116,7 +116,6 @@ metrics_port = 8080
116
116
  [conveyor]
117
117
  scheme = srm,gsiftp,root,http,https
118
118
  transfertool = fts3
119
- ftshosts = https://fts3-pilot.cern.ch:8446, https://fts3-pilot.cern.ch:8446
120
119
  cacert = /opt/rucio/etc/web/ca.crt
121
120
  usercert = /opt/rucio/tools/x509up
122
121
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rucio-clients
3
- Version: 37.3.0
3
+ Version: 37.5.0
4
4
  Summary: Rucio Client Lite Package
5
5
  Home-page: https://rucio.cern.ch/
6
6
  Author: Rucio