rucio 37.2.0__py3-none-any.whl → 37.4.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.
- rucio/cli/rule.py +1 -1
- rucio/client/accountclient.py +205 -60
- rucio/client/accountlimitclient.py +84 -25
- rucio/client/baseclient.py +85 -48
- rucio/client/client.py +49 -41
- rucio/client/configclient.py +36 -13
- rucio/client/credentialclient.py +16 -6
- rucio/client/didclient.py +321 -133
- rucio/client/diracclient.py +13 -6
- rucio/client/downloadclient.py +435 -165
- rucio/client/exportclient.py +8 -2
- rucio/client/fileclient.py +10 -3
- rucio/client/importclient.py +4 -1
- rucio/client/lifetimeclient.py +48 -31
- rucio/client/lockclient.py +22 -7
- rucio/client/metaconventionsclient.py +59 -21
- rucio/client/pingclient.py +3 -1
- rucio/client/replicaclient.py +213 -96
- rucio/client/requestclient.py +123 -16
- rucio/client/rseclient.py +385 -160
- rucio/client/ruleclient.py +147 -51
- rucio/client/scopeclient.py +35 -10
- rucio/client/subscriptionclient.py +60 -27
- rucio/client/touchclient.py +16 -7
- rucio/common/plugins.py +1 -1
- rucio/core/did.py +2 -3
- rucio/core/permission/generic.py +37 -1
- rucio/core/replica.py +6 -6
- rucio/core/rule.py +5 -3
- rucio/daemons/judge/evaluator.py +1 -1
- rucio/db/sqla/util.py +1 -1
- rucio/gateway/authentication.py +58 -88
- rucio/gateway/config.py +63 -75
- rucio/gateway/did.py +245 -329
- rucio/gateway/dirac.py +33 -34
- rucio/gateway/exporter.py +27 -30
- rucio/gateway/importer.py +12 -14
- rucio/gateway/lifetime_exception.py +16 -24
- rucio/gateway/lock.py +27 -40
- rucio/gateway/replica.py +334 -249
- rucio/gateway/request.py +176 -103
- rucio/gateway/rse.py +191 -218
- rucio/gateway/rule.py +115 -146
- rucio/gateway/scope.py +18 -25
- rucio/gateway/subscription.py +90 -108
- rucio/gateway/trace.py +48 -0
- rucio/vcsversion.py +3 -3
- rucio/web/rest/flaskapi/v1/accounts.py +2 -2
- rucio/web/rest/flaskapi/v1/auth.py +15 -0
- rucio/web/rest/flaskapi/v1/common.py +3 -0
- rucio/web/rest/flaskapi/v1/config.py +7 -7
- rucio/web/rest/flaskapi/v1/dids.py +55 -55
- rucio/web/rest/flaskapi/v1/dirac.py +2 -2
- rucio/web/rest/flaskapi/v1/export.py +1 -1
- rucio/web/rest/flaskapi/v1/import.py +1 -1
- rucio/web/rest/flaskapi/v1/lifetime_exceptions.py +5 -5
- rucio/web/rest/flaskapi/v1/locks.py +4 -4
- rucio/web/rest/flaskapi/v1/main.py +17 -10
- rucio/web/rest/flaskapi/v1/redirect.py +1 -1
- rucio/web/rest/flaskapi/v1/replicas.py +30 -29
- rucio/web/rest/flaskapi/v1/requests.py +211 -20
- rucio/web/rest/flaskapi/v1/rses.py +37 -37
- rucio/web/rest/flaskapi/v1/rules.py +15 -15
- rucio/web/rest/flaskapi/v1/scopes.py +3 -3
- rucio/web/rest/flaskapi/v1/subscriptions.py +9 -9
- rucio/web/rest/flaskapi/v1/traces.py +75 -77
- {rucio-37.2.0.data → rucio-37.4.0.data}/data/rucio/etc/rucio.cfg.template +0 -1
- {rucio-37.2.0.data → rucio-37.4.0.data}/data/rucio/etc/rucio_multi_vo.cfg.template +0 -1
- {rucio-37.2.0.dist-info → rucio-37.4.0.dist-info}/METADATA +1 -1
- {rucio-37.2.0.dist-info → rucio-37.4.0.dist-info}/RECORD +127 -126
- {rucio-37.2.0.dist-info → rucio-37.4.0.dist-info}/WHEEL +1 -1
- {rucio-37.2.0.data → rucio-37.4.0.data}/data/rucio/etc/alembic.ini.template +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/data/rucio/etc/alembic_offline.ini.template +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/data/rucio/etc/globus-config.yml.template +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/data/rucio/etc/ldap.cfg.template +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/data/rucio/etc/mail_templates/rule_approval_request.tmpl +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/data/rucio/etc/mail_templates/rule_approved_admin.tmpl +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/data/rucio/etc/mail_templates/rule_approved_user.tmpl +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/data/rucio/etc/mail_templates/rule_denied_admin.tmpl +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/data/rucio/etc/mail_templates/rule_denied_user.tmpl +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/data/rucio/etc/mail_templates/rule_ok_notification.tmpl +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/data/rucio/etc/rse-accounts.cfg.template +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/data/rucio/etc/rucio.cfg.atlas.client.template +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/data/rucio/requirements.server.txt +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/data/rucio/tools/bootstrap.py +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/data/rucio/tools/merge_rucio_configs.py +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/data/rucio/tools/reset_database.py +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-abacus-account +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-abacus-collection-replica +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-abacus-rse +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-admin +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-atropos +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-auditor +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-automatix +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-bb8 +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-cache-client +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-cache-consumer +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-conveyor-finisher +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-conveyor-poller +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-conveyor-preparer +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-conveyor-receiver +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-conveyor-stager +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-conveyor-submitter +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-conveyor-throttler +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-dark-reaper +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-dumper +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-follower +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-hermes +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-judge-cleaner +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-judge-evaluator +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-judge-injector +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-judge-repairer +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-kronos +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-minos +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-minos-temporary-expiration +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-necromancer +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-oauth-manager +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-reaper +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-replica-recoverer +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-rse-decommissioner +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-storage-consistency-actions +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-transmogrifier +0 -0
- {rucio-37.2.0.data → rucio-37.4.0.data}/scripts/rucio-undertaker +0 -0
- {rucio-37.2.0.dist-info → rucio-37.4.0.dist-info}/licenses/AUTHORS.rst +0 -0
- {rucio-37.2.0.dist-info → rucio-37.4.0.dist-info}/licenses/LICENSE +0 -0
- {rucio-37.2.0.dist-info → rucio-37.4.0.dist-info}/top_level.txt +0 -0
rucio/client/ruleclient.py
CHANGED
|
@@ -54,27 +54,52 @@ class RuleClient(BaseClient):
|
|
|
54
54
|
weight: Optional[int] = None,
|
|
55
55
|
) -> Any:
|
|
56
56
|
"""
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
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
|
-
|
|
101
|
-
|
|
102
|
-
:
|
|
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
|
-
|
|
122
|
-
|
|
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
|
-
|
|
136
|
-
|
|
137
|
-
:
|
|
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
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
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
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
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
|
-
|
|
201
|
-
|
|
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
|
-
|
|
216
|
-
|
|
217
|
-
:
|
|
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
|
-
|
|
239
|
-
|
|
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
|
-
|
|
254
|
-
|
|
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
|
-
|
|
269
|
-
|
|
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
|
-
|
|
283
|
-
|
|
284
|
-
:
|
|
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 + '/'
|
rucio/client/scopeclient.py
CHANGED
|
@@ -35,11 +35,23 @@ class ScopeClient(BaseClient):
|
|
|
35
35
|
"""
|
|
36
36
|
Sends the request to add a new scope.
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
:
|
|
41
|
-
|
|
42
|
-
|
|
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
|
-
|
|
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
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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
|
-
|
|
86
|
-
|
|
87
|
-
:
|
|
88
|
-
|
|
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
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
:
|
|
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
|
-
|
|
163
|
-
|
|
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'])
|
rucio/client/touchclient.py
CHANGED
|
@@ -40,13 +40,22 @@ class TouchClient(BaseClient):
|
|
|
40
40
|
"""
|
|
41
41
|
Sends a touch trace for a given file or dataset.
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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/plugins.py
CHANGED
|
@@ -156,7 +156,7 @@ class PolicyPackageAlgorithms:
|
|
|
156
156
|
# import from utils here to avoid circular import
|
|
157
157
|
|
|
158
158
|
env_name = 'RUCIO_POLICY_PACKAGE' + ('' if not vo else '_' + vo.upper())
|
|
159
|
-
package =
|
|
159
|
+
package = os.getenv(env_name, "")
|
|
160
160
|
if not package:
|
|
161
161
|
package = str(config.config_get('policy', 'package' + ('' if not vo else '-' + vo)))
|
|
162
162
|
|
rucio/core/did.py
CHANGED
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
import logging
|
|
16
16
|
import random
|
|
17
17
|
from datetime import datetime, timedelta
|
|
18
|
-
from enum import Enum
|
|
19
18
|
from hashlib import md5
|
|
20
19
|
from re import match
|
|
21
20
|
from typing import TYPE_CHECKING, Any, Literal, Optional, Union
|
|
@@ -1349,7 +1348,7 @@ def list_new_dids(
|
|
|
1349
1348
|
select_stmt = select_stmt.where(
|
|
1350
1349
|
models.DataIdentifier.did_type == DIDType[did_type]
|
|
1351
1350
|
)
|
|
1352
|
-
elif isinstance(did_type,
|
|
1351
|
+
elif isinstance(did_type, DIDType):
|
|
1353
1352
|
select_stmt = select_stmt.where(
|
|
1354
1353
|
models.DataIdentifier.did_type == did_type
|
|
1355
1354
|
)
|
|
@@ -2297,7 +2296,7 @@ def set_status(
|
|
|
2297
2296
|
@read_session
|
|
2298
2297
|
def list_dids(
|
|
2299
2298
|
scope: "InternalScope",
|
|
2300
|
-
filters: "
|
|
2299
|
+
filters: "Iterable[dict[Any, Any]]",
|
|
2301
2300
|
did_type: Literal['all', 'collection', 'dataset', 'container', 'file'] = 'collection',
|
|
2302
2301
|
ignore_case: bool = False,
|
|
2303
2302
|
limit: Optional[int] = None,
|
rucio/core/permission/generic.py
CHANGED
|
@@ -121,7 +121,10 @@ def has_permission(issuer: "InternalAccount", action: str, kwargs: dict[str, Any
|
|
|
121
121
|
'del_identity': perm_del_identity,
|
|
122
122
|
'remove_did_from_followed': perm_remove_did_from_followed,
|
|
123
123
|
'remove_dids_from_followed': perm_remove_dids_from_followed,
|
|
124
|
-
'export': perm_export
|
|
124
|
+
'export': perm_export,
|
|
125
|
+
'list_transfer_limits': perm_list_transfer_limits,
|
|
126
|
+
'set_transfer_limit': perm_set_transfer_limit,
|
|
127
|
+
'delete_transfer_limit': perm_delete_transfer_limit}
|
|
125
128
|
|
|
126
129
|
return perm.get(action, perm_default)(issuer=issuer, kwargs=kwargs, session=session)
|
|
127
130
|
|
|
@@ -1122,3 +1125,36 @@ def perm_export(issuer: "InternalAccount", kwargs: dict[str, Any], *, session: "
|
|
|
1122
1125
|
:returns: True if account is allowed, otherwise False
|
|
1123
1126
|
"""
|
|
1124
1127
|
return _is_root(issuer)
|
|
1128
|
+
|
|
1129
|
+
def perm_list_transfer_limits(issuer: "InternalAccount", kwargs: dict[str, Any], *, session: "Optional[Session]" = None) -> bool:
|
|
1130
|
+
"""
|
|
1131
|
+
Checks if an account can list transfer limits.
|
|
1132
|
+
|
|
1133
|
+
:param issuer: Account identifier which issues the command.
|
|
1134
|
+
:param kwargs: List of arguments for the action.
|
|
1135
|
+
:param session: The DB session to use
|
|
1136
|
+
:returns: True if account is allowed, otherwise False
|
|
1137
|
+
"""
|
|
1138
|
+
return _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session)
|
|
1139
|
+
|
|
1140
|
+
def perm_set_transfer_limit(issuer: "InternalAccount", kwargs: dict[str, Any], *, session: "Optional[Session]" = None) -> bool:
|
|
1141
|
+
"""
|
|
1142
|
+
Checks if an account can set transfer limits.
|
|
1143
|
+
|
|
1144
|
+
:param issuer: Account identifier which issues the command.
|
|
1145
|
+
:param kwargs: List of arguments for the action.
|
|
1146
|
+
:param session: The DB session to use
|
|
1147
|
+
:returns: True if account is allowed, otherwise False
|
|
1148
|
+
"""
|
|
1149
|
+
return _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session)
|
|
1150
|
+
|
|
1151
|
+
def perm_delete_transfer_limit(issuer: "InternalAccount", kwargs: dict[str, Any], *, session: "Optional[Session]" = None) -> bool:
|
|
1152
|
+
"""
|
|
1153
|
+
Checks if an account can delete transfer limits.
|
|
1154
|
+
|
|
1155
|
+
:param issuer: Account identifier which issues the command.
|
|
1156
|
+
:param kwargs: List of arguments for the action.
|
|
1157
|
+
:param session: The DB session to use
|
|
1158
|
+
:returns: True if account is allowed, otherwise False
|
|
1159
|
+
"""
|
|
1160
|
+
return _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session)
|
rucio/core/replica.py
CHANGED
|
@@ -42,7 +42,7 @@ from rucio.common import exception
|
|
|
42
42
|
from rucio.common.cache import MemcacheRegion
|
|
43
43
|
from rucio.common.config import config_get, config_get_bool
|
|
44
44
|
from rucio.common.constants import RseAttr, SuspiciousAvailability
|
|
45
|
-
from rucio.common.types import InternalAccount, InternalScope, LFNDict, is_str_list
|
|
45
|
+
from rucio.common.types import InternalAccount, InternalScope, IPDict, LFNDict, is_str_list
|
|
46
46
|
from rucio.common.utils import add_url_query, chunks, clean_pfns, str_to_date
|
|
47
47
|
from rucio.core.credential import get_signed_url
|
|
48
48
|
from rucio.core.message import add_messages
|
|
@@ -243,7 +243,7 @@ def __exist_replicas(
|
|
|
243
243
|
|
|
244
244
|
@read_session
|
|
245
245
|
def list_bad_replicas_status(
|
|
246
|
-
state: BadFilesStatus = BadFilesStatus.BAD,
|
|
246
|
+
state: Optional[BadFilesStatus] = BadFilesStatus.BAD,
|
|
247
247
|
rse_id: Optional[str] = None,
|
|
248
248
|
younger_than: Optional[datetime] = None,
|
|
249
249
|
older_than: Optional[datetime] = None,
|
|
@@ -943,7 +943,7 @@ def _build_list_replicas_pfn(
|
|
|
943
943
|
path: str,
|
|
944
944
|
sign_urls: bool,
|
|
945
945
|
signature_lifetime: Optional[int],
|
|
946
|
-
client_location: Optional[
|
|
946
|
+
client_location: Optional[IPDict],
|
|
947
947
|
logger: "LoggerFunction" = logging.log,
|
|
948
948
|
*,
|
|
949
949
|
session: "Session",
|
|
@@ -1024,7 +1024,7 @@ def _list_replicas(
|
|
|
1024
1024
|
show_pfns: bool,
|
|
1025
1025
|
schemes: Optional[list[str]],
|
|
1026
1026
|
files_wo_replica: "Iterable[dict[str, Any]]",
|
|
1027
|
-
client_location: Optional[
|
|
1027
|
+
client_location: Optional[IPDict],
|
|
1028
1028
|
domain: Optional[str],
|
|
1029
1029
|
sign_urls: bool,
|
|
1030
1030
|
signature_lifetime: Optional[int],
|
|
@@ -1200,7 +1200,7 @@ def list_replicas(
|
|
|
1200
1200
|
all_states: bool = False,
|
|
1201
1201
|
pfns: bool = True,
|
|
1202
1202
|
rse_expression: Optional[str] = None,
|
|
1203
|
-
client_location: Optional[
|
|
1203
|
+
client_location: Optional[IPDict] = None,
|
|
1204
1204
|
domain: Optional[str] = None,
|
|
1205
1205
|
sign_urls: bool = False,
|
|
1206
1206
|
signature_lifetime: "Optional[int]" = None,
|
|
@@ -4176,7 +4176,7 @@ def get_replicas_state(
|
|
|
4176
4176
|
|
|
4177
4177
|
@read_session
|
|
4178
4178
|
def get_suspicious_files(
|
|
4179
|
-
rse_expression: str,
|
|
4179
|
+
rse_expression: Optional[str],
|
|
4180
4180
|
available_elsewhere: int,
|
|
4181
4181
|
filter_: Optional[dict[str, Any]] = None,
|
|
4182
4182
|
logger: "LoggerFunction" = logging.log,
|
rucio/core/rule.py
CHANGED
|
@@ -2056,7 +2056,8 @@ def re_evaluate_did(
|
|
|
2056
2056
|
name: str,
|
|
2057
2057
|
rule_evaluation_action: DIDReEvaluation,
|
|
2058
2058
|
*,
|
|
2059
|
-
session: "Session"
|
|
2059
|
+
session: "Session",
|
|
2060
|
+
logger: LoggerFunction = logging.log
|
|
2060
2061
|
) -> None:
|
|
2061
2062
|
"""
|
|
2062
2063
|
Re-Evaluates a did.
|
|
@@ -2065,6 +2066,7 @@ def re_evaluate_did(
|
|
|
2065
2066
|
:param name: The name of the did to be re-evaluated.
|
|
2066
2067
|
:param rule_evaluation_action: The Rule evaluation action.
|
|
2067
2068
|
:param session: The database session in use.
|
|
2069
|
+
:param logger: Optional decorated logger that can be passed from the calling daemons or servers.
|
|
2068
2070
|
:raises: DataIdentifierNotFound
|
|
2069
2071
|
"""
|
|
2070
2072
|
|
|
@@ -2080,9 +2082,9 @@ def re_evaluate_did(
|
|
|
2080
2082
|
raise DataIdentifierNotFound() from exc
|
|
2081
2083
|
|
|
2082
2084
|
if rule_evaluation_action == DIDReEvaluation.ATTACH:
|
|
2083
|
-
__evaluate_did_attach(did, session=session)
|
|
2085
|
+
__evaluate_did_attach(did, session=session, logger=logger)
|
|
2084
2086
|
else:
|
|
2085
|
-
__evaluate_did_detach(did, session=session)
|
|
2087
|
+
__evaluate_did_detach(did, session=session, logger=logger)
|
|
2086
2088
|
|
|
2087
2089
|
# Update size and length of did
|
|
2088
2090
|
if session.bind.dialect.name == 'oracle':
|