rucio 37.4.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 might be problematic. Click here for more details.
- rucio/client/downloadclient.py +1 -1
- rucio/client/requestclient.py +6 -5
- rucio/common/constants.py +14 -17
- rucio/common/utils.py +18 -2
- rucio/core/permission/generic.py +3 -0
- rucio/core/replica.py +1 -1
- rucio/core/request.py +2 -2
- rucio/core/transfer.py +4 -5
- rucio/daemons/conveyor/throttler.py +2 -1
- rucio/db/sqla/constants.py +3 -3
- rucio/db/sqla/migrate_repo/versions/13d4f70c66a9_introduce_transfer_limits.py +1 -1
- rucio/db/sqla/models.py +1 -1
- rucio/gateway/request.py +13 -12
- rucio/rse/rsemanager.py +2 -2
- rucio/vcsversion.py +3 -3
- rucio/web/rest/flaskapi/v1/accountlimits.py +22 -22
- rucio/web/rest/flaskapi/v1/accounts.py +157 -157
- rucio/web/rest/flaskapi/v1/archives.py +10 -10
- rucio/web/rest/flaskapi/v1/auth.py +106 -106
- rucio/web/rest/flaskapi/v1/config.py +37 -37
- rucio/web/rest/flaskapi/v1/credentials.py +25 -25
- rucio/web/rest/flaskapi/v1/dids.py +381 -381
- rucio/web/rest/flaskapi/v1/dirac.py +8 -8
- rucio/web/rest/flaskapi/v1/export.py +6 -6
- rucio/web/rest/flaskapi/v1/heartbeats.py +14 -14
- rucio/web/rest/flaskapi/v1/identities.py +25 -25
- rucio/web/rest/flaskapi/v1/import.py +19 -19
- rucio/web/rest/flaskapi/v1/lifetime_exceptions.py +54 -54
- rucio/web/rest/flaskapi/v1/locks.py +60 -60
- rucio/web/rest/flaskapi/v1/meta_conventions.py +29 -29
- rucio/web/rest/flaskapi/v1/nongrid_traces.py +4 -4
- rucio/web/rest/flaskapi/v1/ping.py +4 -4
- rucio/web/rest/flaskapi/v1/redirect.py +16 -16
- rucio/web/rest/flaskapi/v1/replicas.py +281 -281
- rucio/web/rest/flaskapi/v1/requests.py +274 -270
- rucio/web/rest/flaskapi/v1/rses.py +427 -427
- rucio/web/rest/flaskapi/v1/rules.py +129 -129
- rucio/web/rest/flaskapi/v1/scopes.py +21 -21
- rucio/web/rest/flaskapi/v1/subscriptions.py +113 -113
- rucio/web/rest/flaskapi/v1/traces.py +18 -18
- rucio/web/rest/flaskapi/v1/vos.py +32 -32
- {rucio-37.4.0.data → rucio-37.5.0.data}/data/rucio/requirements.server.txt +1 -1
- {rucio-37.4.0.dist-info → rucio-37.5.0.dist-info}/METADATA +1 -1
- {rucio-37.4.0.dist-info → rucio-37.5.0.dist-info}/RECORD +102 -102
- {rucio-37.4.0.dist-info → rucio-37.5.0.dist-info}/WHEEL +1 -1
- {rucio-37.4.0.data → rucio-37.5.0.data}/data/rucio/etc/alembic.ini.template +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/data/rucio/etc/alembic_offline.ini.template +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/data/rucio/etc/globus-config.yml.template +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/data/rucio/etc/ldap.cfg.template +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/data/rucio/etc/mail_templates/rule_approval_request.tmpl +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/data/rucio/etc/mail_templates/rule_approved_admin.tmpl +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/data/rucio/etc/mail_templates/rule_approved_user.tmpl +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/data/rucio/etc/mail_templates/rule_denied_admin.tmpl +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/data/rucio/etc/mail_templates/rule_denied_user.tmpl +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/data/rucio/etc/mail_templates/rule_ok_notification.tmpl +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/data/rucio/etc/rse-accounts.cfg.template +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/data/rucio/etc/rucio.cfg.atlas.client.template +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/data/rucio/etc/rucio.cfg.template +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/data/rucio/etc/rucio_multi_vo.cfg.template +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/data/rucio/tools/bootstrap.py +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/data/rucio/tools/merge_rucio_configs.py +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/data/rucio/tools/reset_database.py +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/scripts/rucio +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/scripts/rucio-abacus-account +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/scripts/rucio-abacus-collection-replica +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/scripts/rucio-abacus-rse +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/scripts/rucio-admin +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/scripts/rucio-atropos +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/scripts/rucio-auditor +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/scripts/rucio-automatix +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/scripts/rucio-bb8 +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/scripts/rucio-cache-client +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/scripts/rucio-cache-consumer +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/scripts/rucio-conveyor-finisher +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/scripts/rucio-conveyor-poller +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/scripts/rucio-conveyor-preparer +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/scripts/rucio-conveyor-receiver +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/scripts/rucio-conveyor-stager +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/scripts/rucio-conveyor-submitter +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/scripts/rucio-conveyor-throttler +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/scripts/rucio-dark-reaper +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/scripts/rucio-dumper +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/scripts/rucio-follower +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/scripts/rucio-hermes +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/scripts/rucio-judge-cleaner +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/scripts/rucio-judge-evaluator +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/scripts/rucio-judge-injector +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/scripts/rucio-judge-repairer +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/scripts/rucio-kronos +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/scripts/rucio-minos +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/scripts/rucio-minos-temporary-expiration +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/scripts/rucio-necromancer +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/scripts/rucio-oauth-manager +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/scripts/rucio-reaper +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/scripts/rucio-replica-recoverer +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/scripts/rucio-rse-decommissioner +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/scripts/rucio-storage-consistency-actions +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/scripts/rucio-transmogrifier +0 -0
- {rucio-37.4.0.data → rucio-37.5.0.data}/scripts/rucio-undertaker +0 -0
- {rucio-37.4.0.dist-info → rucio-37.5.0.dist-info}/licenses/AUTHORS.rst +0 -0
- {rucio-37.4.0.dist-info → rucio-37.5.0.dist-info}/licenses/LICENSE +0 -0
- {rucio-37.4.0.dist-info → rucio-37.5.0.dist-info}/top_level.txt +0 -0
rucio/client/downloadclient.py
CHANGED
rucio/client/requestclient.py
CHANGED
|
@@ -19,8 +19,8 @@ from urllib.parse import quote_plus
|
|
|
19
19
|
from requests.status_codes import codes
|
|
20
20
|
|
|
21
21
|
from rucio.client.baseclient import BaseClient, choice
|
|
22
|
+
from rucio.common.constants import TransferLimitDirection
|
|
22
23
|
from rucio.common.utils import build_url
|
|
23
|
-
from rucio.db.sqla.constants import TransferLimitDirection
|
|
24
24
|
|
|
25
25
|
if TYPE_CHECKING:
|
|
26
26
|
from collections.abc import Iterator, Sequence
|
|
@@ -192,14 +192,15 @@ class RequestClient(BaseClient):
|
|
|
192
192
|
:param strategy: defines how to handle datasets: `fifo` (each file released separately) or `grouped_fifo` (wait for the entire dataset to fit)
|
|
193
193
|
:param transfers: Current number of active transfers
|
|
194
194
|
:param waitings: Current number of waiting transfers
|
|
195
|
-
|
|
195
|
+
|
|
196
196
|
:returns: True if the transfer limit was deleted
|
|
197
197
|
"""
|
|
198
198
|
path = '/'.join([self.REQUEST_BASEURL, 'transfer_limits'])
|
|
199
199
|
url = build_url(choice(self.list_hosts), path=path)
|
|
200
|
-
data = dumps({'rse_expression': rse_expression, 'activity': activity,
|
|
201
|
-
|
|
202
|
-
|
|
200
|
+
data = dumps({'rse_expression': rse_expression, 'activity': activity,
|
|
201
|
+
'direction': direction.value, 'max_transfers': max_transfers,
|
|
202
|
+
'volume': volume, 'deadline': deadline, 'strategy': strategy,
|
|
203
|
+
'transfers': transfers, 'waitings': waitings})
|
|
203
204
|
r = self._send_request(url, type_='PUT', data=data)
|
|
204
205
|
|
|
205
206
|
if r.status_code == codes.created:
|
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
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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/core/permission/generic.py
CHANGED
|
@@ -1126,6 +1126,7 @@ def perm_export(issuer: "InternalAccount", kwargs: dict[str, Any], *, session: "
|
|
|
1126
1126
|
"""
|
|
1127
1127
|
return _is_root(issuer)
|
|
1128
1128
|
|
|
1129
|
+
|
|
1129
1130
|
def perm_list_transfer_limits(issuer: "InternalAccount", kwargs: dict[str, Any], *, session: "Optional[Session]" = None) -> bool:
|
|
1130
1131
|
"""
|
|
1131
1132
|
Checks if an account can list transfer limits.
|
|
@@ -1137,6 +1138,7 @@ def perm_list_transfer_limits(issuer: "InternalAccount", kwargs: dict[str, Any],
|
|
|
1137
1138
|
"""
|
|
1138
1139
|
return _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session)
|
|
1139
1140
|
|
|
1141
|
+
|
|
1140
1142
|
def perm_set_transfer_limit(issuer: "InternalAccount", kwargs: dict[str, Any], *, session: "Optional[Session]" = None) -> bool:
|
|
1141
1143
|
"""
|
|
1142
1144
|
Checks if an account can set transfer limits.
|
|
@@ -1148,6 +1150,7 @@ def perm_set_transfer_limit(issuer: "InternalAccount", kwargs: dict[str, Any], *
|
|
|
1148
1150
|
"""
|
|
1149
1151
|
return _is_root(issuer) or has_account_attribute(account=issuer, key='admin', session=session)
|
|
1150
1152
|
|
|
1153
|
+
|
|
1151
1154
|
def perm_delete_transfer_limit(issuer: "InternalAccount", kwargs: dict[str, Any], *, session: "Optional[Session]" = None) -> bool:
|
|
1152
1155
|
"""
|
|
1153
1156
|
Checks if an account can delete transfer limits.
|
rucio/core/replica.py
CHANGED
|
@@ -402,7 +402,7 @@ def __declare_bad_file_replicas(
|
|
|
402
402
|
if f"{pfn} Unknown replica" not in unknown_replicas:
|
|
403
403
|
unknown_replicas.append('%s %s' % (pfn, 'Unknown replica'))
|
|
404
404
|
elif scope or name:
|
|
405
|
-
unknown_replicas.append(f"{(scope,name)} Unknown replica")
|
|
405
|
+
unknown_replicas.append(f"{(scope, name)} Unknown replica")
|
|
406
406
|
|
|
407
407
|
if status == BadFilesStatus.BAD:
|
|
408
408
|
# For BAD file, we modify the replica state, not for suspicious
|
rucio/core/request.py
CHANGED
|
@@ -31,7 +31,7 @@ from sqlalchemy.orm import aliased
|
|
|
31
31
|
from sqlalchemy.sql.expression import asc, false, func, null, true
|
|
32
32
|
|
|
33
33
|
from rucio.common.config import config_get_bool, config_get_int
|
|
34
|
-
from rucio.common.constants import RseAttr
|
|
34
|
+
from rucio.common.constants import RseAttr, TransferLimitDirection
|
|
35
35
|
from rucio.common.exception import InvalidRSEExpression, RequestNotFound, RucioException, UnsupportedOperation
|
|
36
36
|
from rucio.common.types import FilterDict, InternalAccount, InternalScope, LoggerFunction, RequestDict
|
|
37
37
|
from rucio.common.utils import chunks, generate_uuid
|
|
@@ -41,7 +41,7 @@ from rucio.core.monitor import MetricManager
|
|
|
41
41
|
from rucio.core.rse import RseCollection, RseData, get_rse_attribute, get_rse_name, get_rse_vo
|
|
42
42
|
from rucio.core.rse_expression_parser import parse_expression
|
|
43
43
|
from rucio.db.sqla import filter_thread_work, models
|
|
44
|
-
from rucio.db.sqla.constants import LockState, ReplicaState, RequestErrMsg, RequestState, RequestType
|
|
44
|
+
from rucio.db.sqla.constants import LockState, ReplicaState, RequestErrMsg, RequestState, RequestType
|
|
45
45
|
from rucio.db.sqla.session import read_session, stream_session, transactional_session
|
|
46
46
|
from rucio.db.sqla.util import temp_table_mngr
|
|
47
47
|
|
rucio/core/transfer.py
CHANGED
|
@@ -27,11 +27,10 @@ from dogpile.cache.api import NoValue
|
|
|
27
27
|
from sqlalchemy import select, update
|
|
28
28
|
from sqlalchemy.exc import IntegrityError
|
|
29
29
|
|
|
30
|
-
from rucio.common import constants
|
|
31
30
|
from rucio.common.config import config_get, config_get_list
|
|
32
|
-
from rucio.common.constants import SUPPORTED_PROTOCOLS, RseAttr
|
|
31
|
+
from rucio.common.constants import SUPPORTED_PROTOCOLS, RseAttr, TransferLimitDirection
|
|
33
32
|
from rucio.common.exception import InvalidRSEExpression, RequestNotFound, RSEProtocolNotSupported, RucioException, UnsupportedOperation
|
|
34
|
-
from rucio.common.utils import construct_non_deterministic_pfn
|
|
33
|
+
from rucio.common.utils import construct_non_deterministic_pfn, get_transfer_schemas
|
|
35
34
|
from rucio.core import did
|
|
36
35
|
from rucio.core import message as message_core
|
|
37
36
|
from rucio.core import request as request_core
|
|
@@ -40,7 +39,7 @@ from rucio.core.monitor import MetricManager
|
|
|
40
39
|
from rucio.core.request import DirectTransfer, RequestSource, RequestWithSources, TransferDestination, transition_request_state
|
|
41
40
|
from rucio.core.rse_expression_parser import parse_expression
|
|
42
41
|
from rucio.db.sqla import models
|
|
43
|
-
from rucio.db.sqla.constants import DIDType, RequestState, RequestType
|
|
42
|
+
from rucio.db.sqla.constants import DIDType, RequestState, RequestType
|
|
44
43
|
from rucio.db.sqla.session import read_session, stream_session, transactional_session
|
|
45
44
|
from rucio.rse import rsemanager as rsemgr
|
|
46
45
|
from rucio.transfertool.bittorrent import BittorrentTransfertool
|
|
@@ -1331,7 +1330,7 @@ def __add_compatible_schemes(schemes, allowed_schemes):
|
|
|
1331
1330
|
for scheme in schemes:
|
|
1332
1331
|
if scheme in allowed_schemes:
|
|
1333
1332
|
return_schemes.append(scheme)
|
|
1334
|
-
for scheme_map_scheme in
|
|
1333
|
+
for scheme_map_scheme in get_transfer_schemas().get(scheme, []):
|
|
1335
1334
|
if scheme_map_scheme not in allowed_schemes:
|
|
1336
1335
|
continue
|
|
1337
1336
|
else:
|
|
@@ -26,13 +26,14 @@ from sqlalchemy import null
|
|
|
26
26
|
|
|
27
27
|
import rucio.db.sqla.util
|
|
28
28
|
from rucio.common import exception
|
|
29
|
+
from rucio.common.constants import TransferLimitDirection
|
|
29
30
|
from rucio.common.logging import setup_logging
|
|
30
31
|
from rucio.core.monitor import MetricManager
|
|
31
32
|
from rucio.core.request import get_request_stats, re_sync_all_transfer_limits, release_all_waiting_requests, release_waiting_requests_fifo, release_waiting_requests_grouped_fifo, reset_stale_waiting_requests, set_transfer_limit_stats
|
|
32
33
|
from rucio.core.rse import RseCollection, RseData
|
|
33
34
|
from rucio.core.transfer import applicable_rse_transfer_limits
|
|
34
35
|
from rucio.daemons.common import ProducerConsumerDaemon, db_workqueue
|
|
35
|
-
from rucio.db.sqla.constants import RequestState
|
|
36
|
+
from rucio.db.sqla.constants import RequestState
|
|
36
37
|
|
|
37
38
|
if TYPE_CHECKING:
|
|
38
39
|
from collections.abc import Iterator
|
rucio/db/sqla/constants.py
CHANGED
|
@@ -196,9 +196,9 @@ class SubscriptionState(Enum):
|
|
|
196
196
|
BROKEN = 'B'
|
|
197
197
|
|
|
198
198
|
|
|
199
|
-
class TransferLimitDirection(Enum):
|
|
200
|
-
SOURCE = 'S'
|
|
201
|
-
DESTINATION = 'D'
|
|
199
|
+
#class TransferLimitDirection(Enum):
|
|
200
|
+
# SOURCE = 'S'
|
|
201
|
+
# DESTINATION = 'D'
|
|
202
202
|
|
|
203
203
|
|
|
204
204
|
class DatabaseOperationType(Enum):
|
|
@@ -19,7 +19,7 @@ import sqlalchemy as sa
|
|
|
19
19
|
from alembic import context
|
|
20
20
|
from alembic.op import create_check_constraint, create_foreign_key, create_index, create_primary_key, create_table, drop_table
|
|
21
21
|
|
|
22
|
-
from rucio.
|
|
22
|
+
from rucio.common.constants import TransferLimitDirection
|
|
23
23
|
from rucio.db.sqla.types import GUID
|
|
24
24
|
|
|
25
25
|
# Alembic revision identifiers
|
rucio/db/sqla/models.py
CHANGED
|
@@ -29,6 +29,7 @@ from sqlalchemy.types import LargeBinary
|
|
|
29
29
|
# and it must be renamed to avoid conflicts with the policy package schema modules
|
|
30
30
|
from rucio.common import schema as common_schema
|
|
31
31
|
from rucio.common import utils
|
|
32
|
+
from rucio.common.constants import TransferLimitDirection
|
|
32
33
|
from rucio.common.types import InternalAccount, InternalScope # noqa: TCH001 (types are needed by SQLAlchemy)
|
|
33
34
|
from rucio.db.sqla.constants import (
|
|
34
35
|
AccountStatus,
|
|
@@ -51,7 +52,6 @@ from rucio.db.sqla.constants import (
|
|
|
51
52
|
RuleState,
|
|
52
53
|
ScopeStatus,
|
|
53
54
|
SubscriptionState,
|
|
54
|
-
TransferLimitDirection,
|
|
55
55
|
)
|
|
56
56
|
from rucio.db.sqla.session import BASE
|
|
57
57
|
from rucio.db.sqla.types import GUID, JSON, BooleanString, InternalAccountString, InternalScopeString
|
rucio/gateway/request.py
CHANGED
|
@@ -19,11 +19,12 @@ Interface for the requests abstraction layer
|
|
|
19
19
|
from typing import TYPE_CHECKING, Any, Optional
|
|
20
20
|
|
|
21
21
|
from rucio.common import exception
|
|
22
|
+
from rucio.common.constants import TransferLimitDirection
|
|
22
23
|
from rucio.common.types import InternalAccount, InternalScope, RequestGatewayDict
|
|
23
24
|
from rucio.common.utils import gateway_update_return_dict
|
|
24
25
|
from rucio.core import request
|
|
25
26
|
from rucio.core.rse import get_rse_id
|
|
26
|
-
from rucio.db.sqla.constants import DatabaseOperationType
|
|
27
|
+
from rucio.db.sqla.constants import DatabaseOperationType
|
|
27
28
|
from rucio.db.sqla.session import db_session
|
|
28
29
|
from rucio.gateway import permission
|
|
29
30
|
|
|
@@ -364,14 +365,14 @@ def set_transfer_limit(
|
|
|
364
365
|
raise exception.AccessDenied(f'{issuer} cannot set transfer limits. {auth_result.message}')
|
|
365
366
|
|
|
366
367
|
request.set_transfer_limit(rse_expression=rse_expression,
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
368
|
+
activity=activity,
|
|
369
|
+
direction=direction,
|
|
370
|
+
max_transfers=max_transfers,
|
|
371
|
+
volume=volume,
|
|
372
|
+
deadline=deadline,
|
|
373
|
+
strategy=strategy,
|
|
374
|
+
transfers=transfers,
|
|
375
|
+
waitings=waitings)
|
|
375
376
|
|
|
376
377
|
|
|
377
378
|
def delete_transfer_limit(
|
|
@@ -398,6 +399,6 @@ def delete_transfer_limit(
|
|
|
398
399
|
raise exception.AccessDenied(f'{issuer} cannot delete transfer limits. {auth_result.message}')
|
|
399
400
|
|
|
400
401
|
request.delete_transfer_limit(rse_expression=rse_expression,
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
402
|
+
activity=activity,
|
|
403
|
+
direction=direction,
|
|
404
|
+
session=session)
|
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
|
|
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.
|
|
7
|
+
'version': '37.5.0',
|
|
8
8
|
'branch_nick': 'release-37',
|
|
9
|
-
'revision_id': '
|
|
10
|
-
'revno':
|
|
9
|
+
'revision_id': '092cfe864848019a987a3a167120cf5cf7df2f61',
|
|
10
|
+
'revno': 13761
|
|
11
11
|
}
|
|
@@ -35,13 +35,13 @@ class LocalAccountLimit(ErrorHandlingMethodView):
|
|
|
35
35
|
parameters:
|
|
36
36
|
- name: account
|
|
37
37
|
in: path
|
|
38
|
-
description: The account for the accountlimit.
|
|
38
|
+
description: "The account for the accountlimit."
|
|
39
39
|
schema:
|
|
40
40
|
type: string
|
|
41
41
|
style: simple
|
|
42
42
|
- name: rse
|
|
43
43
|
in: path
|
|
44
|
-
description: The rse for the accountlimit.
|
|
44
|
+
description: "The rse for the accountlimit."
|
|
45
45
|
schema:
|
|
46
46
|
type: string
|
|
47
47
|
style: simple
|
|
@@ -54,20 +54,20 @@ class LocalAccountLimit(ErrorHandlingMethodView):
|
|
|
54
54
|
- bytes
|
|
55
55
|
properties:
|
|
56
56
|
bytes:
|
|
57
|
-
description: The new limit in bytes.
|
|
57
|
+
description: "The new limit in bytes."
|
|
58
58
|
type: integer
|
|
59
59
|
responses:
|
|
60
60
|
201:
|
|
61
|
-
description: OK
|
|
61
|
+
description: "OK"
|
|
62
62
|
content:
|
|
63
63
|
application/json:
|
|
64
64
|
schema:
|
|
65
65
|
type: string
|
|
66
66
|
enum: ['Created']
|
|
67
67
|
401:
|
|
68
|
-
description: Invalid Auth Token
|
|
68
|
+
description: "Invalid Auth Token"
|
|
69
69
|
404:
|
|
70
|
-
description: No RSE or account found for the given id.
|
|
70
|
+
description: "No RSE or account found for the given id."
|
|
71
71
|
"""
|
|
72
72
|
parameters = json_parameters()
|
|
73
73
|
bytes_param = param_get(parameters, 'bytes')
|
|
@@ -89,23 +89,23 @@ class LocalAccountLimit(ErrorHandlingMethodView):
|
|
|
89
89
|
parameters:
|
|
90
90
|
- name: account
|
|
91
91
|
in: path
|
|
92
|
-
description: The account for the accountlimit.
|
|
92
|
+
description: "The account for the accountlimit."
|
|
93
93
|
schema:
|
|
94
94
|
type: string
|
|
95
95
|
style: simple
|
|
96
96
|
- name: rse
|
|
97
97
|
in: path
|
|
98
|
-
description: The rse for the accountlimit.
|
|
98
|
+
description: "The rse for the accountlimit."
|
|
99
99
|
schema:
|
|
100
100
|
type: string
|
|
101
101
|
style: simple
|
|
102
102
|
responses:
|
|
103
103
|
200:
|
|
104
|
-
description: OK
|
|
104
|
+
description: "OK"
|
|
105
105
|
401:
|
|
106
|
-
description: Invalid Auth Token
|
|
106
|
+
description: "Invalid Auth Token"
|
|
107
107
|
404:
|
|
108
|
-
description: No RSE or account found for the given id.
|
|
108
|
+
description: "No RSE or account found for the given id."
|
|
109
109
|
"""
|
|
110
110
|
try:
|
|
111
111
|
delete_local_account_limit(account=account, rse=rse, issuer=request.environ.get('issuer'), vo=request.environ.get('vo'))
|
|
@@ -127,13 +127,13 @@ class GlobalAccountLimit(ErrorHandlingMethodView):
|
|
|
127
127
|
parameters:
|
|
128
128
|
- name: account
|
|
129
129
|
in: path
|
|
130
|
-
description: The account for the accountlimit.
|
|
130
|
+
description: "The account for the accountlimit."
|
|
131
131
|
schema:
|
|
132
132
|
type: string
|
|
133
133
|
style: simple
|
|
134
134
|
- name: rse_expression
|
|
135
135
|
in: path
|
|
136
|
-
description: The rse expression for the accountlimit.
|
|
136
|
+
description: "The rse expression for the accountlimit."
|
|
137
137
|
schema:
|
|
138
138
|
type: string
|
|
139
139
|
style: simple
|
|
@@ -146,20 +146,20 @@ class GlobalAccountLimit(ErrorHandlingMethodView):
|
|
|
146
146
|
- bytes
|
|
147
147
|
properties:
|
|
148
148
|
bytes:
|
|
149
|
-
description: The new limit in bytes.
|
|
149
|
+
description: "The new limit in bytes."
|
|
150
150
|
type: integer
|
|
151
151
|
responses:
|
|
152
152
|
201:
|
|
153
|
-
description: OK
|
|
153
|
+
description: "OK"
|
|
154
154
|
content:
|
|
155
155
|
application/json:
|
|
156
156
|
schema:
|
|
157
157
|
type: string
|
|
158
158
|
enum: ['Created']
|
|
159
159
|
401:
|
|
160
|
-
description: Invalid Auth Token
|
|
160
|
+
description: "Invalid Auth Token"
|
|
161
161
|
404:
|
|
162
|
-
description: No RSE or account found for the given id.
|
|
162
|
+
description: "No RSE or account found for the given id."
|
|
163
163
|
"""
|
|
164
164
|
parameters = json_parameters()
|
|
165
165
|
bytes_param = param_get(parameters, 'bytes')
|
|
@@ -187,23 +187,23 @@ class GlobalAccountLimit(ErrorHandlingMethodView):
|
|
|
187
187
|
parameters:
|
|
188
188
|
- name: account
|
|
189
189
|
in: path
|
|
190
|
-
description: The account for the accountlimit.
|
|
190
|
+
description: "The account for the accountlimit."
|
|
191
191
|
schema:
|
|
192
192
|
type: string
|
|
193
193
|
style: simple
|
|
194
194
|
- name: rse_expression
|
|
195
195
|
in: path
|
|
196
|
-
description: The rse expression for the accountlimit.
|
|
196
|
+
description: "The rse expression for the accountlimit."
|
|
197
197
|
schema:
|
|
198
198
|
type: string
|
|
199
199
|
style: simple
|
|
200
200
|
responses:
|
|
201
201
|
200:
|
|
202
|
-
description: OK
|
|
202
|
+
description: "OK"
|
|
203
203
|
401:
|
|
204
|
-
description: Invalid Auth Token
|
|
204
|
+
description: "Invalid Auth Token"
|
|
205
205
|
404:
|
|
206
|
-
description: No RSE or account found for the given id.
|
|
206
|
+
description: "No RSE or account found for the given id."
|
|
207
207
|
"""
|
|
208
208
|
try:
|
|
209
209
|
delete_global_account_limit(account=account, rse_expression=rse_expression, issuer=request.environ.get('issuer'), vo=request.environ.get('vo'))
|