rucio-clients 32.8.6__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 (88) hide show
  1. rucio/__init__.py +18 -0
  2. rucio/alembicrevision.py +16 -0
  3. rucio/client/__init__.py +16 -0
  4. rucio/client/accountclient.py +413 -0
  5. rucio/client/accountlimitclient.py +155 -0
  6. rucio/client/baseclient.py +929 -0
  7. rucio/client/client.py +77 -0
  8. rucio/client/configclient.py +113 -0
  9. rucio/client/credentialclient.py +54 -0
  10. rucio/client/didclient.py +691 -0
  11. rucio/client/diracclient.py +48 -0
  12. rucio/client/downloadclient.py +1674 -0
  13. rucio/client/exportclient.py +44 -0
  14. rucio/client/fileclient.py +51 -0
  15. rucio/client/importclient.py +42 -0
  16. rucio/client/lifetimeclient.py +74 -0
  17. rucio/client/lockclient.py +99 -0
  18. rucio/client/metaclient.py +137 -0
  19. rucio/client/pingclient.py +45 -0
  20. rucio/client/replicaclient.py +444 -0
  21. rucio/client/requestclient.py +109 -0
  22. rucio/client/rseclient.py +664 -0
  23. rucio/client/ruleclient.py +287 -0
  24. rucio/client/scopeclient.py +88 -0
  25. rucio/client/subscriptionclient.py +161 -0
  26. rucio/client/touchclient.py +78 -0
  27. rucio/client/uploadclient.py +871 -0
  28. rucio/common/__init__.py +14 -0
  29. rucio/common/cache.py +74 -0
  30. rucio/common/config.py +796 -0
  31. rucio/common/constants.py +92 -0
  32. rucio/common/constraints.py +18 -0
  33. rucio/common/didtype.py +187 -0
  34. rucio/common/exception.py +1092 -0
  35. rucio/common/extra.py +37 -0
  36. rucio/common/logging.py +404 -0
  37. rucio/common/pcache.py +1387 -0
  38. rucio/common/policy.py +84 -0
  39. rucio/common/schema/__init__.py +143 -0
  40. rucio/common/schema/atlas.py +411 -0
  41. rucio/common/schema/belleii.py +406 -0
  42. rucio/common/schema/cms.py +478 -0
  43. rucio/common/schema/domatpc.py +399 -0
  44. rucio/common/schema/escape.py +424 -0
  45. rucio/common/schema/generic.py +431 -0
  46. rucio/common/schema/generic_multi_vo.py +410 -0
  47. rucio/common/schema/icecube.py +404 -0
  48. rucio/common/schema/lsst.py +423 -0
  49. rucio/common/stomp_utils.py +160 -0
  50. rucio/common/stopwatch.py +56 -0
  51. rucio/common/test_rucio_server.py +148 -0
  52. rucio/common/types.py +158 -0
  53. rucio/common/utils.py +1946 -0
  54. rucio/rse/__init__.py +97 -0
  55. rucio/rse/protocols/__init__.py +14 -0
  56. rucio/rse/protocols/cache.py +123 -0
  57. rucio/rse/protocols/dummy.py +112 -0
  58. rucio/rse/protocols/gfal.py +701 -0
  59. rucio/rse/protocols/globus.py +243 -0
  60. rucio/rse/protocols/gsiftp.py +93 -0
  61. rucio/rse/protocols/http_cache.py +83 -0
  62. rucio/rse/protocols/mock.py +124 -0
  63. rucio/rse/protocols/ngarc.py +210 -0
  64. rucio/rse/protocols/posix.py +251 -0
  65. rucio/rse/protocols/protocol.py +530 -0
  66. rucio/rse/protocols/rclone.py +365 -0
  67. rucio/rse/protocols/rfio.py +137 -0
  68. rucio/rse/protocols/srm.py +339 -0
  69. rucio/rse/protocols/ssh.py +414 -0
  70. rucio/rse/protocols/storm.py +207 -0
  71. rucio/rse/protocols/webdav.py +547 -0
  72. rucio/rse/protocols/xrootd.py +295 -0
  73. rucio/rse/rsemanager.py +752 -0
  74. rucio/vcsversion.py +11 -0
  75. rucio/version.py +46 -0
  76. rucio_clients-32.8.6.data/data/etc/rse-accounts.cfg.template +25 -0
  77. rucio_clients-32.8.6.data/data/etc/rucio.cfg.atlas.client.template +42 -0
  78. rucio_clients-32.8.6.data/data/etc/rucio.cfg.template +257 -0
  79. rucio_clients-32.8.6.data/data/requirements.txt +55 -0
  80. rucio_clients-32.8.6.data/data/rucio_client/merge_rucio_configs.py +147 -0
  81. rucio_clients-32.8.6.data/scripts/rucio +2540 -0
  82. rucio_clients-32.8.6.data/scripts/rucio-admin +2434 -0
  83. rucio_clients-32.8.6.dist-info/METADATA +50 -0
  84. rucio_clients-32.8.6.dist-info/RECORD +88 -0
  85. rucio_clients-32.8.6.dist-info/WHEEL +5 -0
  86. rucio_clients-32.8.6.dist-info/licenses/AUTHORS.rst +94 -0
  87. rucio_clients-32.8.6.dist-info/licenses/LICENSE +201 -0
  88. rucio_clients-32.8.6.dist-info/top_level.txt +1 -0
@@ -0,0 +1,148 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright European Organization for Nuclear Research (CERN) since 2012
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ import unittest
17
+ from os import remove
18
+ from os.path import basename
19
+
20
+ from rucio.common.utils import generate_uuid as uuid, execute
21
+
22
+
23
+ def file_generator(size=2048, namelen=10):
24
+ """ Create a bogus file and returns it's name.
25
+ :param size: size in bytes
26
+ :returns: The name of the generated file.
27
+ """
28
+ fn = '/tmp/rucio_testfile_' + uuid()
29
+ execute('dd if=/dev/urandom of={0} count={1} bs=1'.format(fn, size))
30
+ return fn
31
+
32
+
33
+ def get_scope_and_rses():
34
+ """
35
+ Check if xrd containers rses for xrootd are available in the testing environment.
36
+
37
+ :return: A tuple (scope, rses) for the rucio client where scope is mock/test and rses is a list or (None, [None]) if no suitable rse exists.
38
+ """
39
+ cmd = "rucio list-rses --rses 'test_container_xrd=True'"
40
+ print(cmd)
41
+ exitcode, out, err = execute(cmd)
42
+ print(out, err)
43
+ rses = out.split()
44
+ if len(rses) == 0:
45
+ return None, [None]
46
+ return 'test', rses
47
+
48
+
49
+ def delete_rules(did):
50
+ # get the rules for the file
51
+ print('Deleting rules')
52
+ cmd = "rucio list-rules {0} | grep {0} | cut -f1 -d\\ ".format(did)
53
+ print(cmd)
54
+ exitcode, out, err = execute(cmd)
55
+ print(out, err)
56
+ rules = out.split()
57
+ # delete the rules for the file
58
+ for rule in rules:
59
+ cmd = "rucio delete-rule {0}".format(rule)
60
+ print(cmd)
61
+ exitcode, out, err = execute(cmd)
62
+
63
+
64
+ class TestRucioServer(unittest.TestCase):
65
+
66
+ def setUp(self):
67
+ self.marker = '$ > '
68
+ self.scope, self.rses = get_scope_and_rses()
69
+ self.rse = self.rses[0]
70
+ self.generated_dids = []
71
+
72
+ def tearDown(self):
73
+ for did in self.generated_dids:
74
+ delete_rules(did)
75
+ self.generated_dids = []
76
+
77
+ def test_ping(self):
78
+ """CLIENT (USER): rucio ping"""
79
+ cmd = 'rucio ping'
80
+ print(self.marker + cmd)
81
+ exitcode, out, err = execute(cmd)
82
+ print(out, err)
83
+ self.assertEqual(exitcode, 0)
84
+
85
+ def test_whoami(self):
86
+ """CLIENT (USER): rucio whoami"""
87
+ cmd = 'rucio whoami'
88
+ print(self.marker + cmd)
89
+ exitcode, out, err = execute(cmd)
90
+ print(out, err)
91
+ self.assertEqual(exitcode, 0)
92
+
93
+ def test_upload_download(self):
94
+ """CLIENT(USER): rucio upload files to dataset/download dataset"""
95
+ if self.rse is None:
96
+ return
97
+
98
+ tmp_file1 = file_generator()
99
+ tmp_file2 = file_generator()
100
+ tmp_file3 = file_generator()
101
+ tmp_dsn = 'tests.rucio_client_test_server_' + uuid()
102
+
103
+ # Adding files to a new dataset
104
+ cmd = 'rucio upload --rse {0} --scope {1} {2} {3} {4} {1}:{5}'.format(self.rse, self.scope, tmp_file1, tmp_file2, tmp_file3, tmp_dsn)
105
+ print(self.marker + cmd)
106
+ exitcode, out, err = execute(cmd)
107
+ print(out)
108
+ print(err)
109
+ remove(tmp_file1)
110
+ remove(tmp_file2)
111
+ remove(tmp_file3)
112
+ self.assertEqual(exitcode, 0)
113
+
114
+ # List the files
115
+ cmd = 'rucio list-files {0}:{1}'.format(self.scope, tmp_dsn)
116
+ print(self.marker + cmd)
117
+ exitcode, out, err = execute(cmd)
118
+ print(out)
119
+ print(err)
120
+ self.assertEqual(exitcode, 0)
121
+
122
+ # List the replicas
123
+ cmd = 'rucio list-file-replicas {0}:{1}'.format(self.scope, tmp_dsn)
124
+ print(self.marker + cmd)
125
+ exitcode, out, err = execute(cmd)
126
+ print(out)
127
+ print(err)
128
+ self.assertEqual(exitcode, 0)
129
+
130
+ # Downloading dataset
131
+ cmd = 'rucio download --dir /tmp/ {0}:{1}'.format(self.scope, tmp_dsn)
132
+ print(self.marker + cmd)
133
+ exitcode, out, err = execute(cmd)
134
+ print(out)
135
+ print(err)
136
+ # The files should be there
137
+ cmd = 'ls /tmp/{0}/rucio_testfile_*'.format(tmp_dsn)
138
+ print(self.marker + cmd)
139
+ exitcode, out, err = execute(cmd)
140
+ print(err, out)
141
+ self.assertEqual(exitcode, 0)
142
+
143
+ # cleaning
144
+ remove('/tmp/{0}/'.format(tmp_dsn) + basename(tmp_file1))
145
+ remove('/tmp/{0}/'.format(tmp_dsn) + basename(tmp_file2))
146
+ remove('/tmp/{0}/'.format(tmp_dsn) + basename(tmp_file3))
147
+ added_dids = ['{0}:{1}'.format(self.scope, did) for did in (basename(tmp_file1), basename(tmp_file2), basename(tmp_file3), tmp_dsn)]
148
+ self.generated_dids += added_dids
rucio/common/types.py ADDED
@@ -0,0 +1,158 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright European Organization for Nuclear Research (CERN) since 2012
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ from typing import Any, Optional, TypedDict, Union
17
+
18
+
19
+ class InternalType(object):
20
+ '''
21
+ Base for Internal representations of string types
22
+ '''
23
+ def __init__(self, value, vo='def', fromExternal=True):
24
+ if value is None:
25
+ self.external = None
26
+ self.internal = None
27
+ self.vo = vo
28
+ elif not isinstance(value, str):
29
+ raise TypeError('Expected value to be string type, got %s' % type(value))
30
+ elif fromExternal:
31
+ self.external = value
32
+ self.vo = vo
33
+ self.internal = self._calc_internal()
34
+ else:
35
+ self.internal = value
36
+ vo, external = self._calc_external()
37
+ self.external = external
38
+ self.vo = vo
39
+
40
+ def __repr__(self):
41
+ return self.internal
42
+
43
+ def __str__(self):
44
+ return self.external
45
+
46
+ def __eq__(self, other):
47
+ if isinstance(other, self.__class__):
48
+ return self.internal == other.internal
49
+ return NotImplemented
50
+
51
+ def __ne__(self, other):
52
+ val = self == other
53
+ if val is NotImplemented:
54
+ return NotImplemented
55
+ return not val
56
+
57
+ def __le__(self, other):
58
+ val = self.external <= other.external
59
+ if val is NotImplemented:
60
+ return NotImplemented
61
+ return val
62
+
63
+ def __lt__(self, other):
64
+ val = self.external < other.external
65
+ if val is NotImplemented:
66
+ return NotImplemented
67
+ return val
68
+
69
+ def __hash__(self):
70
+ return hash(self.internal)
71
+
72
+ def _calc_external(self):
73
+ ''' Utility to convert between internal and external representations'''
74
+ split = self.internal.split('@', 1)
75
+ if len(split) == 1: # if cannot convert, vo is '' and this is single vo
76
+ vo = 'def'
77
+ external = split[0]
78
+ else:
79
+ vo = split[1]
80
+ external = split[0]
81
+ return vo, external
82
+
83
+ def _calc_internal(self):
84
+ ''' Utility to convert between internal and external representations'''
85
+ if self.vo == 'def':
86
+ return self.external
87
+ internal = '{}@{}'.format(self.external, self.vo)
88
+ return internal
89
+
90
+
91
+ class InternalAccount(InternalType):
92
+ '''
93
+ Internal representation of an account
94
+ '''
95
+ def __init__(self, account, vo='def', fromExternal=True):
96
+ super(InternalAccount, self).__init__(value=account, vo=vo, fromExternal=fromExternal)
97
+
98
+
99
+ class InternalScope(InternalType):
100
+ '''
101
+ Internal representation of a scope
102
+ '''
103
+ def __init__(self, scope, vo='def', fromExternal=True):
104
+ super(InternalScope, self).__init__(value=scope, vo=vo, fromExternal=fromExternal)
105
+
106
+
107
+ class RSEDomainLANDict(TypedDict):
108
+ read: Optional[int]
109
+ write: Optional[int]
110
+ delete: Optional[int]
111
+
112
+
113
+ class RSEDomainWANDict(TypedDict):
114
+ read: Optional[int]
115
+ write: Optional[int]
116
+ delete: Optional[int]
117
+ third_party_copy_read: Optional[int]
118
+ third_party_copy_write: Optional[int]
119
+
120
+
121
+ class RSEDomainsDict(TypedDict):
122
+ lan: RSEDomainLANDict
123
+ wan: RSEDomainWANDict
124
+
125
+
126
+ class RSEProtocolDict(TypedDict):
127
+ auth_token: Optional[str] # FIXME: typing.NotRequired
128
+ hostname: str
129
+ scheme: str
130
+ port: int
131
+ prefix: str
132
+ impl: str
133
+ domains: RSEDomainsDict
134
+ extended_attributes: Optional[Union[str, dict[str, Any]]]
135
+
136
+
137
+ class RSESettingsDict(TypedDict):
138
+ availability_delete: bool
139
+ availability_read: bool
140
+ availability_write: bool
141
+ credentials: Optional[dict[str, Any]]
142
+ lfn2pfn_algorithm: str
143
+ qos_class: Optional[str]
144
+ staging_area: bool
145
+ rse_type: str
146
+ sign_url: Optional[str]
147
+ read_protocol: int
148
+ write_protocol: int
149
+ delete_protocol: int
150
+ third_party_copy_read_protocol: int
151
+ third_party_copy_write_protocol: int
152
+ id: str
153
+ rse: str
154
+ volatile: bool
155
+ verify_checksum: bool
156
+ deterministic: bool
157
+ domain: list[str]
158
+ protocols: list[RSEProtocolDict]