rucio-clients 37.5.0__py3-none-any.whl → 37.7.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.
- rucio/cli/bin_legacy/rucio.py +41 -22
- rucio/cli/bin_legacy/rucio_admin.py +1 -1
- rucio/cli/did.py +2 -2
- rucio/cli/rse.py +2 -3
- rucio/cli/rule.py +9 -5
- rucio/cli/subscription.py +1 -1
- rucio/client/baseclient.py +9 -4
- rucio/client/didclient.py +16 -16
- rucio/client/downloadclient.py +16 -15
- rucio/client/exportclient.py +45 -4
- rucio/client/lockclient.py +3 -3
- rucio/client/pingclient.py +35 -4
- rucio/client/replicaclient.py +2 -2
- rucio/client/touchclient.py +3 -2
- rucio/client/uploadclient.py +728 -183
- rucio/common/cache.py +1 -2
- rucio/common/client.py +4 -30
- rucio/common/config.py +27 -3
- rucio/common/constants.py +5 -1
- rucio/common/didtype.py +2 -2
- rucio/common/pcache.py +20 -25
- rucio/common/plugins.py +12 -19
- rucio/common/policy.py +3 -2
- rucio/common/schema/__init__.py +11 -8
- rucio/common/types.py +7 -5
- rucio/common/utils.py +1 -1
- rucio/rse/__init__.py +7 -6
- rucio/rse/protocols/ngarc.py +2 -2
- rucio/rse/protocols/srm.py +1 -1
- rucio/rse/protocols/webdav.py +8 -1
- rucio/rse/rsemanager.py +5 -4
- rucio/rse/translation.py +2 -2
- rucio/vcsversion.py +3 -3
- {rucio_clients-37.5.0.dist-info → rucio_clients-37.7.0.dist-info}/METADATA +1 -1
- {rucio_clients-37.5.0.dist-info → rucio_clients-37.7.0.dist-info}/RECORD +46 -46
- {rucio_clients-37.5.0.data → rucio_clients-37.7.0.data}/data/etc/rse-accounts.cfg.template +0 -0
- {rucio_clients-37.5.0.data → rucio_clients-37.7.0.data}/data/etc/rucio.cfg.atlas.client.template +0 -0
- {rucio_clients-37.5.0.data → rucio_clients-37.7.0.data}/data/etc/rucio.cfg.template +0 -0
- {rucio_clients-37.5.0.data → rucio_clients-37.7.0.data}/data/requirements.client.txt +0 -0
- {rucio_clients-37.5.0.data → rucio_clients-37.7.0.data}/data/rucio_client/merge_rucio_configs.py +0 -0
- {rucio_clients-37.5.0.data → rucio_clients-37.7.0.data}/scripts/rucio +0 -0
- {rucio_clients-37.5.0.data → rucio_clients-37.7.0.data}/scripts/rucio-admin +0 -0
- {rucio_clients-37.5.0.dist-info → rucio_clients-37.7.0.dist-info}/WHEEL +0 -0
- {rucio_clients-37.5.0.dist-info → rucio_clients-37.7.0.dist-info}/licenses/AUTHORS.rst +0 -0
- {rucio_clients-37.5.0.dist-info → rucio_clients-37.7.0.dist-info}/licenses/LICENSE +0 -0
- {rucio_clients-37.5.0.dist-info → rucio_clients-37.7.0.dist-info}/top_level.txt +0 -0
rucio/common/cache.py
CHANGED
|
@@ -16,8 +16,7 @@ from typing import TYPE_CHECKING, Optional
|
|
|
16
16
|
|
|
17
17
|
from dogpile.cache.region import CacheRegion
|
|
18
18
|
|
|
19
|
-
from rucio.common.
|
|
20
|
-
from rucio.common.config import config_get
|
|
19
|
+
from rucio.common.config import config_get, is_client
|
|
21
20
|
|
|
22
21
|
if TYPE_CHECKING:
|
|
23
22
|
from collections.abc import Callable
|
rucio/common/client.py
CHANGED
|
@@ -17,44 +17,18 @@ import socket
|
|
|
17
17
|
from configparser import NoOptionError, NoSectionError
|
|
18
18
|
from typing import TYPE_CHECKING
|
|
19
19
|
|
|
20
|
-
from rucio.common.config import config_get
|
|
21
|
-
from rucio.common.
|
|
20
|
+
from rucio.common.config import config_get
|
|
21
|
+
from rucio.common.constants import DEFAULT_VO
|
|
22
22
|
|
|
23
23
|
if TYPE_CHECKING:
|
|
24
24
|
from rucio.common.types import IPWithLocationDict
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
def is_client() -> bool:
|
|
28
|
-
""""
|
|
29
|
-
Checks if the function is called from a client or from a server/daemon
|
|
30
|
-
|
|
31
|
-
:returns client_mode: True if is called from a client, False if it is called from a server/daemon
|
|
32
|
-
"""
|
|
33
|
-
if 'RUCIO_CLIENT_MODE' not in os.environ:
|
|
34
|
-
try:
|
|
35
|
-
if config_has_section('database'):
|
|
36
|
-
client_mode = False
|
|
37
|
-
elif config_has_section('client'):
|
|
38
|
-
client_mode = True
|
|
39
|
-
else:
|
|
40
|
-
client_mode = False
|
|
41
|
-
except (RuntimeError, ConfigNotFound):
|
|
42
|
-
# If no configuration file is found the default value should be True
|
|
43
|
-
client_mode = True
|
|
44
|
-
else:
|
|
45
|
-
if os.environ['RUCIO_CLIENT_MODE']:
|
|
46
|
-
client_mode = True
|
|
47
|
-
else:
|
|
48
|
-
client_mode = False
|
|
49
|
-
|
|
50
|
-
return client_mode
|
|
51
|
-
|
|
52
|
-
|
|
53
27
|
def get_client_vo() -> str:
|
|
54
28
|
"""
|
|
55
29
|
Get the client VO from the environment or the configuration file.
|
|
56
30
|
|
|
57
|
-
:returns vo: The client VO as a string; default =
|
|
31
|
+
:returns vo: The client VO as a string; default = DEFAULT_VO.
|
|
58
32
|
"""
|
|
59
33
|
if 'RUCIO_VO' in os.environ:
|
|
60
34
|
vo = os.environ['RUCIO_VO']
|
|
@@ -62,7 +36,7 @@ def get_client_vo() -> str:
|
|
|
62
36
|
try:
|
|
63
37
|
vo = str(config_get('client', 'vo'))
|
|
64
38
|
except (NoOptionError, NoSectionError):
|
|
65
|
-
vo =
|
|
39
|
+
vo = DEFAULT_VO
|
|
66
40
|
return vo
|
|
67
41
|
|
|
68
42
|
|
rucio/common/config.py
CHANGED
|
@@ -32,7 +32,6 @@ if TYPE_CHECKING:
|
|
|
32
32
|
from sqlalchemy.orm import Session
|
|
33
33
|
|
|
34
34
|
|
|
35
|
-
|
|
36
35
|
def convert_to_any_type(value: str) -> Union[bool, int, float, str]:
|
|
37
36
|
if value.lower() in ['true', 'yes', 'on']:
|
|
38
37
|
return True
|
|
@@ -42,7 +41,7 @@ def convert_to_any_type(value: str) -> Union[bool, int, float, str]:
|
|
|
42
41
|
for conv in (int, float):
|
|
43
42
|
try:
|
|
44
43
|
return conv(value)
|
|
45
|
-
except:
|
|
44
|
+
except Exception:
|
|
46
45
|
pass
|
|
47
46
|
|
|
48
47
|
return value
|
|
@@ -58,6 +57,32 @@ def _convert_to_boolean(value: Union[str, bool]) -> bool:
|
|
|
58
57
|
raise ValueError('Not a boolean: %s' % value)
|
|
59
58
|
|
|
60
59
|
|
|
60
|
+
def is_client() -> bool:
|
|
61
|
+
""""
|
|
62
|
+
Checks if the function is called from a client or from a server/daemon
|
|
63
|
+
|
|
64
|
+
:returns client_mode: True if is called from a client, False if it is called from a server/daemon
|
|
65
|
+
"""
|
|
66
|
+
if 'RUCIO_CLIENT_MODE' not in os.environ:
|
|
67
|
+
try:
|
|
68
|
+
if config_has_section('database'):
|
|
69
|
+
client_mode = False
|
|
70
|
+
elif config_has_section('client'):
|
|
71
|
+
client_mode = True
|
|
72
|
+
else:
|
|
73
|
+
client_mode = False
|
|
74
|
+
except (RuntimeError, ConfigNotFound):
|
|
75
|
+
# If no configuration file is found the default value should be True
|
|
76
|
+
client_mode = True
|
|
77
|
+
else:
|
|
78
|
+
if os.environ['RUCIO_CLIENT_MODE']:
|
|
79
|
+
client_mode = True
|
|
80
|
+
else:
|
|
81
|
+
client_mode = False
|
|
82
|
+
|
|
83
|
+
return client_mode
|
|
84
|
+
|
|
85
|
+
|
|
61
86
|
@overload
|
|
62
87
|
def config_get(
|
|
63
88
|
section: str,
|
|
@@ -193,7 +218,6 @@ def config_get(
|
|
|
193
218
|
return convert_type_fnc(get_config().get(section, option))
|
|
194
219
|
except (configparser.NoOptionError, configparser.NoSectionError, ConfigNotFound) as err:
|
|
195
220
|
|
|
196
|
-
from rucio.common.client import is_client
|
|
197
221
|
client_mode = is_client()
|
|
198
222
|
|
|
199
223
|
if not client_mode and check_config_table:
|
rucio/common/constants.py
CHANGED
|
@@ -27,6 +27,8 @@ RESERVED_KEYS = ['scope', 'name', 'account', 'did_type', 'is_open', 'monotonic',
|
|
|
27
27
|
# collection_keys =
|
|
28
28
|
# file_keys =
|
|
29
29
|
|
|
30
|
+
DEFAULT_VO = 'def'
|
|
31
|
+
|
|
30
32
|
KEY_TYPES = ['ALL', 'COLLECTION', 'FILE', 'DERIVED']
|
|
31
33
|
# all(container, dataset, file), collection(dataset or container), file, derived(compute from file for collection)
|
|
32
34
|
|
|
@@ -69,11 +71,13 @@ FTS_JOB_TYPE = namedtuple('FTS_JOB_TYPE', ['MULTIPLE_REPLICA', 'MULTI_HOP', 'SES
|
|
|
69
71
|
|
|
70
72
|
MAX_MESSAGE_LENGTH = 4000
|
|
71
73
|
|
|
74
|
+
|
|
72
75
|
@enum.unique
|
|
73
76
|
class TransferLimitDirection(enum.Enum):
|
|
74
77
|
SOURCE = 'S'
|
|
75
78
|
DESTINATION = 'D'
|
|
76
79
|
|
|
80
|
+
|
|
77
81
|
@enum.unique
|
|
78
82
|
class SuspiciousAvailability(enum.Enum):
|
|
79
83
|
ALL = 0
|
|
@@ -211,4 +215,4 @@ RSE_ATTRS_BOOL = Literal[
|
|
|
211
215
|
]
|
|
212
216
|
|
|
213
217
|
SUPPORTED_SIGN_URL_SERVICES_LITERAL = Literal['gcs', 's3', 'swift']
|
|
214
|
-
SUPPORTED_SIGN_URL_SERVICES = list(get_args(SUPPORTED_SIGN_URL_SERVICES_LITERAL))
|
|
218
|
+
SUPPORTED_SIGN_URL_SERVICES = list(get_args(SUPPORTED_SIGN_URL_SERVICES_LITERAL))
|
rucio/common/didtype.py
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
"""
|
|
16
|
-
DID type to represent a
|
|
16
|
+
DID type to represent a DID and to simplify operations on it
|
|
17
17
|
"""
|
|
18
18
|
|
|
19
19
|
from typing import Any, Union
|
|
@@ -25,7 +25,7 @@ class DID:
|
|
|
25
25
|
|
|
26
26
|
"""
|
|
27
27
|
Class used to store a DID
|
|
28
|
-
Given an object
|
|
28
|
+
Given an object DID of type DID
|
|
29
29
|
scope is stored in did.scope
|
|
30
30
|
name is stored in did.name
|
|
31
31
|
"""
|
rucio/common/pcache.py
CHANGED
|
@@ -66,7 +66,7 @@ def run_cmd(args: "subprocess._CMD", timeout: int = 0) -> tuple[int, Optional[by
|
|
|
66
66
|
stdout=subprocess.PIPE,
|
|
67
67
|
stderr=subprocess.STDOUT)
|
|
68
68
|
|
|
69
|
-
except:
|
|
69
|
+
except Exception:
|
|
70
70
|
return (-2, None)
|
|
71
71
|
|
|
72
72
|
# Set the timer if a timeout value was given
|
|
@@ -620,7 +620,7 @@ class Pcache:
|
|
|
620
620
|
f.write(self.src + '\n')
|
|
621
621
|
f.close()
|
|
622
622
|
self.chmod(fname, 0o666)
|
|
623
|
-
except:
|
|
623
|
+
except Exception:
|
|
624
624
|
pass
|
|
625
625
|
|
|
626
626
|
# Record GUID if given
|
|
@@ -631,7 +631,7 @@ class Pcache:
|
|
|
631
631
|
f.write(self.guid + '\n')
|
|
632
632
|
f.close()
|
|
633
633
|
self.chmod(fname, 0o666)
|
|
634
|
-
except:
|
|
634
|
+
except Exception:
|
|
635
635
|
pass
|
|
636
636
|
|
|
637
637
|
# Try to transfer the file up the the number of retries allowed
|
|
@@ -857,7 +857,7 @@ class Pcache:
|
|
|
857
857
|
self.log(ERROR, "rename %s %s", xfer_file, cache_file)
|
|
858
858
|
try:
|
|
859
859
|
os.unlink(xfer_file)
|
|
860
|
-
except:
|
|
860
|
+
except Exception:
|
|
861
861
|
pass
|
|
862
862
|
self.fail(104)
|
|
863
863
|
|
|
@@ -904,12 +904,12 @@ class Pcache:
|
|
|
904
904
|
try:
|
|
905
905
|
stat_info = os.stat(src)
|
|
906
906
|
self.log(INFO, "stat(%s) = %s", src, stat_info)
|
|
907
|
-
except:
|
|
907
|
+
except Exception:
|
|
908
908
|
self.log(INFO, "cannot stat %s", src)
|
|
909
909
|
try:
|
|
910
910
|
stat_info = os.stat(dst)
|
|
911
911
|
self.log(INFO, "stat(%s) = %s", dst, stat_info)
|
|
912
|
-
except:
|
|
912
|
+
except Exception:
|
|
913
913
|
self.log(INFO, "cannot stat %s", dst)
|
|
914
914
|
return ret
|
|
915
915
|
|
|
@@ -933,7 +933,7 @@ class Pcache:
|
|
|
933
933
|
f = open(filename, 'r')
|
|
934
934
|
data = int(f.read().strip())
|
|
935
935
|
f.close()
|
|
936
|
-
except:
|
|
936
|
+
except Exception:
|
|
937
937
|
data = 0
|
|
938
938
|
return data
|
|
939
939
|
|
|
@@ -948,9 +948,9 @@ class Pcache:
|
|
|
948
948
|
for f in os.listdir(stats_dir):
|
|
949
949
|
try:
|
|
950
950
|
os.unlink(os.path.join(stats_dir, f))
|
|
951
|
-
except:
|
|
951
|
+
except Exception:
|
|
952
952
|
pass
|
|
953
|
-
except:
|
|
953
|
+
except Exception:
|
|
954
954
|
pass
|
|
955
955
|
# XXXX error handling
|
|
956
956
|
pass
|
|
@@ -965,7 +965,7 @@ class Pcache:
|
|
|
965
965
|
data = f.read()
|
|
966
966
|
f.close()
|
|
967
967
|
value = int(data)
|
|
968
|
-
except:
|
|
968
|
+
except Exception:
|
|
969
969
|
# XXXX
|
|
970
970
|
value = 0
|
|
971
971
|
value += delta
|
|
@@ -974,7 +974,7 @@ class Pcache:
|
|
|
974
974
|
f.write("%s\n" % value)
|
|
975
975
|
f.close()
|
|
976
976
|
self.chmod(stats_file, 0o666)
|
|
977
|
-
except:
|
|
977
|
+
except Exception:
|
|
978
978
|
pass
|
|
979
979
|
# XXX
|
|
980
980
|
self.unlock_dir(stats_dir)
|
|
@@ -993,7 +993,7 @@ class Pcache:
|
|
|
993
993
|
f = open(filename)
|
|
994
994
|
data = f.read()
|
|
995
995
|
size = int(data)
|
|
996
|
-
except:
|
|
996
|
+
except Exception:
|
|
997
997
|
pass
|
|
998
998
|
|
|
999
999
|
# If we could not fetch the size, do a reinventory
|
|
@@ -1034,7 +1034,7 @@ class Pcache:
|
|
|
1034
1034
|
f.write("%s\n" % size)
|
|
1035
1035
|
f.close()
|
|
1036
1036
|
self.chmod(filename, 0o666)
|
|
1037
|
-
except:
|
|
1037
|
+
except Exception:
|
|
1038
1038
|
pass # XXXX
|
|
1039
1039
|
|
|
1040
1040
|
self.unlock_file(inventory_lock)
|
|
@@ -1066,16 +1066,16 @@ class Pcache:
|
|
|
1066
1066
|
maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1]
|
|
1067
1067
|
if (maxfd == resource.RLIM_INFINITY):
|
|
1068
1068
|
maxfd = MAXFD
|
|
1069
|
-
except:
|
|
1069
|
+
except Exception:
|
|
1070
1070
|
try:
|
|
1071
1071
|
maxfd = os.sysconf("SC_OPEN_MAX")
|
|
1072
|
-
except:
|
|
1072
|
+
except Exception:
|
|
1073
1073
|
maxfd = MAXFD # use default value
|
|
1074
1074
|
|
|
1075
1075
|
for fd in range(0, maxfd + 1):
|
|
1076
1076
|
try:
|
|
1077
1077
|
os.close(fd)
|
|
1078
|
-
except:
|
|
1078
|
+
except Exception:
|
|
1079
1079
|
pass
|
|
1080
1080
|
|
|
1081
1081
|
# Panda server callback functions
|
|
@@ -1103,7 +1103,7 @@ class Pcache:
|
|
|
1103
1103
|
url, retry, data, ret)
|
|
1104
1104
|
if ret == "True":
|
|
1105
1105
|
break
|
|
1106
|
-
except:
|
|
1106
|
+
except Exception:
|
|
1107
1107
|
exc, msg, tb = sys.exc_info()
|
|
1108
1108
|
self.log(ERROR, "post to %s, data=%s, error=%s", url, data, msg)
|
|
1109
1109
|
retry += 1
|
|
@@ -1181,11 +1181,6 @@ class Pcache:
|
|
|
1181
1181
|
return
|
|
1182
1182
|
|
|
1183
1183
|
# XXXX does this create a possible race condition?
|
|
1184
|
-
if 0:
|
|
1185
|
-
try:
|
|
1186
|
-
os.unlink(name)
|
|
1187
|
-
except:
|
|
1188
|
-
pass
|
|
1189
1184
|
status = fcntl.lockf(f, fcntl.LOCK_UN)
|
|
1190
1185
|
f.close()
|
|
1191
1186
|
del self.locks[name]
|
|
@@ -1196,7 +1191,7 @@ class Pcache:
|
|
|
1196
1191
|
try:
|
|
1197
1192
|
f.close()
|
|
1198
1193
|
os.unlink(filename)
|
|
1199
|
-
except:
|
|
1194
|
+
except Exception:
|
|
1200
1195
|
pass
|
|
1201
1196
|
|
|
1202
1197
|
# Cleanup functions
|
|
@@ -1276,7 +1271,7 @@ class Pcache:
|
|
|
1276
1271
|
def cleanup_failed_transfer(self) -> None:
|
|
1277
1272
|
try:
|
|
1278
1273
|
os.unlink(self.pcache_dir + 'xfer')
|
|
1279
|
-
except:
|
|
1274
|
+
except Exception:
|
|
1280
1275
|
pass
|
|
1281
1276
|
|
|
1282
1277
|
def empty_dir(self, d: str) -> None:
|
|
@@ -1295,7 +1290,7 @@ class Pcache:
|
|
|
1295
1290
|
try:
|
|
1296
1291
|
guid = open(fullname).read().strip()
|
|
1297
1292
|
self.deleted_guids.append(guid)
|
|
1298
|
-
except:
|
|
1293
|
+
except Exception:
|
|
1299
1294
|
pass # XXXX
|
|
1300
1295
|
elif name == "mru" and os.path.islink(fullname):
|
|
1301
1296
|
try:
|
rucio/common/plugins.py
CHANGED
|
@@ -21,47 +21,40 @@ from typing import TYPE_CHECKING, Any, TypeVar
|
|
|
21
21
|
from packaging.specifiers import SpecifierSet
|
|
22
22
|
|
|
23
23
|
from rucio.common import config
|
|
24
|
-
from rucio.common.client import get_client_vo
|
|
24
|
+
from rucio.common.client import get_client_vo
|
|
25
25
|
from rucio.common.exception import InvalidAlgorithmName, PolicyPackageIsNotVersioned, PolicyPackageVersionError
|
|
26
26
|
from rucio.version import current_version
|
|
27
27
|
|
|
28
28
|
if TYPE_CHECKING:
|
|
29
29
|
from collections.abc import Callable
|
|
30
|
+
from types import ModuleType
|
|
30
31
|
|
|
31
32
|
from rucio.common.types import LoggerFunction
|
|
32
33
|
|
|
33
34
|
PolicyPackageAlgorithmsT = TypeVar('PolicyPackageAlgorithmsT', bound='PolicyPackageAlgorithms')
|
|
34
35
|
|
|
35
36
|
|
|
36
|
-
def
|
|
37
|
+
def check_policy_module_version(module: 'ModuleType', logger: 'LoggerFunction' = logging.log) -> None:
|
|
37
38
|
|
|
38
39
|
'''
|
|
39
|
-
Checks that the Rucio version supported by the policy
|
|
40
|
+
Checks that the Rucio version supported by the policy module is compatible
|
|
40
41
|
with this version. Raises an exception if not.
|
|
41
|
-
:param
|
|
42
|
+
:param module: the top level module of the policy package
|
|
42
43
|
'''
|
|
43
44
|
try:
|
|
44
|
-
supported_versionset = _get_supported_versions_from_policy_package(
|
|
45
|
-
except ImportError:
|
|
46
|
-
logger(logging.DEBUG, 'Policy package %s not found' % package)
|
|
47
|
-
return
|
|
45
|
+
supported_versionset = _get_supported_versions_from_policy_package(module)
|
|
48
46
|
except PolicyPackageIsNotVersioned:
|
|
49
|
-
logger(logging.DEBUG, 'Policy package %s does not include information about which Rucio versions it supports' %
|
|
47
|
+
logger(logging.DEBUG, 'Policy package %s does not include information about which Rucio versions it supports' % module.__name__)
|
|
50
48
|
return
|
|
51
49
|
|
|
52
50
|
rucio_version = current_version()
|
|
53
51
|
if rucio_version not in supported_versionset:
|
|
54
|
-
raise PolicyPackageVersionError(rucio_version=rucio_version, supported_versionset=str(supported_versionset), package=
|
|
55
|
-
|
|
52
|
+
raise PolicyPackageVersionError(rucio_version=rucio_version, supported_versionset=str(supported_versionset), package=module.__name__)
|
|
56
53
|
|
|
57
|
-
def _get_supported_versions_from_policy_package(package: str) -> SpecifierSet:
|
|
58
|
-
try:
|
|
59
|
-
module = importlib.import_module(package)
|
|
60
|
-
except ImportError as e:
|
|
61
|
-
raise e
|
|
62
54
|
|
|
55
|
+
def _get_supported_versions_from_policy_package(module: 'ModuleType') -> SpecifierSet:
|
|
63
56
|
if not hasattr(module, 'SUPPORTED_VERSION'):
|
|
64
|
-
raise PolicyPackageIsNotVersioned(
|
|
57
|
+
raise PolicyPackageIsNotVersioned(module.__name__)
|
|
65
58
|
|
|
66
59
|
supported_versionset = module.SUPPORTED_VERSION
|
|
67
60
|
|
|
@@ -139,7 +132,7 @@ class PolicyPackageAlgorithms:
|
|
|
139
132
|
cls._try_importing_policy()
|
|
140
133
|
else:
|
|
141
134
|
# on client, only register algorithms for selected VO
|
|
142
|
-
if is_client():
|
|
135
|
+
if config.is_client():
|
|
143
136
|
vo = get_client_vo()
|
|
144
137
|
cls._try_importing_policy(vo)
|
|
145
138
|
# on server, list all VOs and register their algorithms
|
|
@@ -160,8 +153,8 @@ class PolicyPackageAlgorithms:
|
|
|
160
153
|
if not package:
|
|
161
154
|
package = str(config.config_get('policy', 'package' + ('' if not vo else '-' + vo)))
|
|
162
155
|
|
|
163
|
-
check_policy_package_version(package)
|
|
164
156
|
module = importlib.import_module(package)
|
|
157
|
+
check_policy_module_version(module)
|
|
165
158
|
|
|
166
159
|
if hasattr(module, 'get_algorithms'):
|
|
167
160
|
all_algorithms = module.get_algorithms()
|
rucio/common/policy.py
CHANGED
|
@@ -23,6 +23,7 @@ from dogpile.cache import make_region
|
|
|
23
23
|
from dogpile.cache.api import NoValue
|
|
24
24
|
|
|
25
25
|
from rucio.common.config import config_get
|
|
26
|
+
from rucio.common.constants import DEFAULT_VO
|
|
26
27
|
from rucio.common.exception import UndefinedPolicy
|
|
27
28
|
|
|
28
29
|
if TYPE_CHECKING:
|
|
@@ -41,8 +42,8 @@ def get_policy(logger: 'LoggerFunction' = logging.log) -> str:
|
|
|
41
42
|
try:
|
|
42
43
|
policy = config_get('permission', 'policy')
|
|
43
44
|
except (NoOptionError, NoSectionError):
|
|
44
|
-
policy =
|
|
45
|
-
logger(logging.WARNING, "Policy not specified, falling back to
|
|
45
|
+
policy = DEFAULT_VO
|
|
46
|
+
logger(logging.WARNING, "Policy not specified, falling back to DEFAULT_VO")
|
|
46
47
|
policy = os.environ.get('POLICY', policy)
|
|
47
48
|
REGION.set('policy', policy)
|
|
48
49
|
return policy
|
rucio/common/schema/__init__.py
CHANGED
|
@@ -22,7 +22,8 @@ from typing import TYPE_CHECKING, Any
|
|
|
22
22
|
from jsonschema import ValidationError, validate
|
|
23
23
|
|
|
24
24
|
from rucio.common import config, exception
|
|
25
|
-
from rucio.common.
|
|
25
|
+
from rucio.common.constants import DEFAULT_VO
|
|
26
|
+
from rucio.common.plugins import check_policy_module_version
|
|
26
27
|
|
|
27
28
|
if TYPE_CHECKING:
|
|
28
29
|
from types import ModuleType
|
|
@@ -64,9 +65,10 @@ if not _is_multivo():
|
|
|
64
65
|
policy = environ['RUCIO_POLICY_PACKAGE']
|
|
65
66
|
else:
|
|
66
67
|
policy = config.config_get('policy', 'package', check_config_table=False)
|
|
67
|
-
|
|
68
|
+
package_module = importlib.import_module(policy)
|
|
69
|
+
check_policy_module_version(package_module)
|
|
68
70
|
policy = policy + ".schema"
|
|
69
|
-
except (NoOptionError, NoSectionError):
|
|
71
|
+
except (NoOptionError, NoSectionError, ModuleNotFoundError):
|
|
70
72
|
# fall back to old system for now
|
|
71
73
|
try:
|
|
72
74
|
policy = config.config_get('policy', 'schema', check_config_table=False)
|
|
@@ -93,7 +95,7 @@ if not _is_multivo():
|
|
|
93
95
|
except ImportError:
|
|
94
96
|
raise exception.ErrorLoadingPolicyPackage(policy)
|
|
95
97
|
|
|
96
|
-
schema_modules[
|
|
98
|
+
schema_modules[DEFAULT_VO] = module
|
|
97
99
|
if hasattr(module, 'SCOPE_NAME_REGEXP'):
|
|
98
100
|
scope_name_regexps.append(module.SCOPE_NAME_REGEXP)
|
|
99
101
|
|
|
@@ -107,9 +109,10 @@ def load_schema_for_vo(vo: str) -> None:
|
|
|
107
109
|
policy = environ[env_name]
|
|
108
110
|
else:
|
|
109
111
|
policy = config.config_get('policy', 'package-' + vo, check_config_table=False)
|
|
110
|
-
|
|
112
|
+
package_module = importlib.import_module(policy)
|
|
113
|
+
check_policy_module_version(package_module)
|
|
111
114
|
policy = policy + ".schema"
|
|
112
|
-
except (NoOptionError, NoSectionError):
|
|
115
|
+
except (NoOptionError, NoSectionError, ModuleNotFoundError):
|
|
113
116
|
# fall back to old system for now
|
|
114
117
|
try:
|
|
115
118
|
policy = config.config_get('policy', 'schema', check_config_table=False)
|
|
@@ -139,7 +142,7 @@ def load_schema_for_vo(vo: str) -> None:
|
|
|
139
142
|
schema_modules[vo] = module
|
|
140
143
|
|
|
141
144
|
|
|
142
|
-
def validate_schema(name: str, obj: Any, vo: str =
|
|
145
|
+
def validate_schema(name: str, obj: Any, vo: str = DEFAULT_VO) -> None:
|
|
143
146
|
if obj:
|
|
144
147
|
if vo not in schema_modules:
|
|
145
148
|
load_schema_for_vo(vo)
|
|
@@ -154,7 +157,7 @@ def validate_schema(name: str, obj: Any, vo: str = 'def') -> None:
|
|
|
154
157
|
raise exception.InvalidObject(f'Problem validating {name}: {error}')
|
|
155
158
|
|
|
156
159
|
|
|
157
|
-
def get_schema_value(key: str, vo: str =
|
|
160
|
+
def get_schema_value(key: str, vo: str = DEFAULT_VO) -> Any:
|
|
158
161
|
if vo not in schema_modules:
|
|
159
162
|
load_schema_for_vo(vo)
|
|
160
163
|
if not hasattr(schema_modules[vo], key):
|
rucio/common/types.py
CHANGED
|
@@ -16,6 +16,8 @@ import sys
|
|
|
16
16
|
from collections.abc import Callable
|
|
17
17
|
from os import PathLike
|
|
18
18
|
|
|
19
|
+
from rucio.common.constants import DEFAULT_VO
|
|
20
|
+
|
|
19
21
|
if sys.version_info < (3, 11): # pragma: no cover
|
|
20
22
|
from typing_extensions import TYPE_CHECKING, Any, Literal, NotRequired, Optional, TypedDict, TypeGuard, Union # noqa: UP035
|
|
21
23
|
PathTypeAlias = Union[PathLike, str]
|
|
@@ -35,7 +37,7 @@ class InternalType:
|
|
|
35
37
|
'''
|
|
36
38
|
Base for Internal representations of string types
|
|
37
39
|
'''
|
|
38
|
-
def __init__(self, value: Optional[str], vo: str =
|
|
40
|
+
def __init__(self, value: Optional[str], vo: str = DEFAULT_VO, from_external: bool = True):
|
|
39
41
|
if value is None:
|
|
40
42
|
self.external = None
|
|
41
43
|
self.internal = None
|
|
@@ -87,7 +89,7 @@ class _RepresentationCalculator:
|
|
|
87
89
|
"""
|
|
88
90
|
split = internal.split('@', 1)
|
|
89
91
|
if len(split) == 1: # if cannot convert, vo is '' and this is single vo
|
|
90
|
-
vo =
|
|
92
|
+
vo = DEFAULT_VO
|
|
91
93
|
external = split[0]
|
|
92
94
|
else:
|
|
93
95
|
vo = split[1]
|
|
@@ -104,7 +106,7 @@ class _RepresentationCalculator:
|
|
|
104
106
|
|
|
105
107
|
:returns: internal representation
|
|
106
108
|
"""
|
|
107
|
-
if vo ==
|
|
109
|
+
if vo == DEFAULT_VO:
|
|
108
110
|
return external
|
|
109
111
|
internal = '{}@{}'.format(external, vo)
|
|
110
112
|
return internal
|
|
@@ -114,7 +116,7 @@ class InternalAccount(InternalType):
|
|
|
114
116
|
'''
|
|
115
117
|
Internal representation of an account
|
|
116
118
|
'''
|
|
117
|
-
def __init__(self, account: Optional[str], vo: str =
|
|
119
|
+
def __init__(self, account: Optional[str], vo: str = DEFAULT_VO, from_external: bool = True):
|
|
118
120
|
super(InternalAccount, self).__init__(value=account, vo=vo, from_external=from_external)
|
|
119
121
|
|
|
120
122
|
|
|
@@ -122,7 +124,7 @@ class InternalScope(InternalType):
|
|
|
122
124
|
'''
|
|
123
125
|
Internal representation of a scope
|
|
124
126
|
'''
|
|
125
|
-
def __init__(self, scope: Optional[str], vo: str =
|
|
127
|
+
def __init__(self, scope: Optional[str], vo: str = DEFAULT_VO, from_external: bool = True):
|
|
126
128
|
super(InternalScope, self).__init__(value=scope, vo=vo, from_external=from_external)
|
|
127
129
|
|
|
128
130
|
|
rucio/common/utils.py
CHANGED
|
@@ -961,7 +961,7 @@ def parse_did_filter_from_string_fe(
|
|
|
961
961
|
|
|
962
962
|
:param input_string: String containing the filter options.
|
|
963
963
|
:param name: DID name.
|
|
964
|
-
:param type: The type of the
|
|
964
|
+
:param type: The type of the DID: all(container, dataset, file), collection(dataset or container), dataset, container.
|
|
965
965
|
:param omit_name: omit addition of name to filters.
|
|
966
966
|
:return: list of dictionaries with each dictionary as a separate OR expression.
|
|
967
967
|
"""
|
rucio/rse/__init__.py
CHANGED
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
|
|
15
15
|
from dogpile.cache import make_region
|
|
16
16
|
|
|
17
|
-
from rucio.common.
|
|
17
|
+
from rucio.common.config import is_client
|
|
18
|
+
from rucio.common.constants import DEFAULT_VO
|
|
18
19
|
from rucio.rse import rsemanager
|
|
19
20
|
|
|
20
21
|
if is_client():
|
|
@@ -25,7 +26,7 @@ else:
|
|
|
25
26
|
setattr(rsemanager, 'SERVER_MODE', True)
|
|
26
27
|
|
|
27
28
|
|
|
28
|
-
def get_rse_client(rse, vo=
|
|
29
|
+
def get_rse_client(rse, vo=DEFAULT_VO, **kwarg):
|
|
29
30
|
'''
|
|
30
31
|
get_rse_client
|
|
31
32
|
'''
|
|
@@ -34,7 +35,7 @@ def get_rse_client(rse, vo='def', **kwarg):
|
|
|
34
35
|
return client.get_rse(rse)
|
|
35
36
|
|
|
36
37
|
|
|
37
|
-
def get_signed_url_client(rse, service, op, url, vo=
|
|
38
|
+
def get_signed_url_client(rse, service, op, url, vo=DEFAULT_VO):
|
|
38
39
|
'''
|
|
39
40
|
get_signed_url_client
|
|
40
41
|
'''
|
|
@@ -42,7 +43,7 @@ def get_signed_url_client(rse, service, op, url, vo='def'):
|
|
|
42
43
|
return CredentialClient(vo=vo).get_signed_url(rse, service, op, url)
|
|
43
44
|
|
|
44
45
|
|
|
45
|
-
def get_signed_url_server(rse, service, op, url, vo=
|
|
46
|
+
def get_signed_url_server(rse, service, op, url, vo=DEFAULT_VO):
|
|
46
47
|
'''
|
|
47
48
|
get_signed_url_server
|
|
48
49
|
'''
|
|
@@ -57,7 +58,7 @@ def rse_key_generator(namespace, fn, **kwargs):
|
|
|
57
58
|
'''
|
|
58
59
|
Key generator for RSE
|
|
59
60
|
'''
|
|
60
|
-
def generate_key(rse, vo=
|
|
61
|
+
def generate_key(rse, vo=DEFAULT_VO, session=None):
|
|
61
62
|
'''
|
|
62
63
|
generate_key
|
|
63
64
|
'''
|
|
@@ -81,7 +82,7 @@ if rsemanager.SERVER_MODE: # pylint:disable=no-member
|
|
|
81
82
|
from rucio.core.rse import get_rse_id, get_rse_protocols
|
|
82
83
|
from rucio.core.vo import map_vo
|
|
83
84
|
|
|
84
|
-
def tmp_rse_info(rse=None, vo=
|
|
85
|
+
def tmp_rse_info(rse=None, vo=DEFAULT_VO, rse_id=None, session=None):
|
|
85
86
|
if rse_id is None:
|
|
86
87
|
# This can be called directly by client tools if they're co-located on a server
|
|
87
88
|
# i.e. running rucio cli on a server and during the test suite.
|
rucio/rse/protocols/ngarc.py
CHANGED
|
@@ -20,7 +20,7 @@ from rucio.rse.protocols import protocol
|
|
|
20
20
|
|
|
21
21
|
try:
|
|
22
22
|
import arc # pylint: disable=import-error
|
|
23
|
-
except:
|
|
23
|
+
except Exception:
|
|
24
24
|
pass
|
|
25
25
|
|
|
26
26
|
|
|
@@ -59,7 +59,7 @@ class Default(protocol.RSEProtocol):
|
|
|
59
59
|
self.cfg = arc.UserConfig()
|
|
60
60
|
try:
|
|
61
61
|
self.cfg.ProxyPath(os.environ['X509_USER_PROXY'])
|
|
62
|
-
except:
|
|
62
|
+
except Exception:
|
|
63
63
|
pass
|
|
64
64
|
|
|
65
65
|
def path2pfn(self, path):
|
rucio/rse/protocols/srm.py
CHANGED
rucio/rse/protocols/webdav.py
CHANGED
|
@@ -253,8 +253,15 @@ class Default(protocol.RSEProtocol):
|
|
|
253
253
|
:raise ServiceUnavailable, RSEAccessDenied
|
|
254
254
|
"""
|
|
255
255
|
path = self.path2pfn(pfn)
|
|
256
|
+
|
|
257
|
+
using_presigned_urls = self.rse['sign_url'] is not None
|
|
258
|
+
|
|
256
259
|
try:
|
|
257
|
-
|
|
260
|
+
# use GET instead of HEAD for presigned urls
|
|
261
|
+
if not using_presigned_urls:
|
|
262
|
+
result = self.session.request('HEAD', path, verify=False, timeout=self.timeout, cert=self.cert)
|
|
263
|
+
else:
|
|
264
|
+
result = self.session.request('GET', path, verify=False, timeout=self.timeout, cert=self.cert)
|
|
258
265
|
if result.status_code == 200:
|
|
259
266
|
return True
|
|
260
267
|
elif result.status_code in [401, ]:
|