rucio-clients 37.0.0rc1__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 (104) hide show
  1. rucio/__init__.py +17 -0
  2. rucio/alembicrevision.py +15 -0
  3. rucio/cli/__init__.py +14 -0
  4. rucio/cli/account.py +216 -0
  5. rucio/cli/bin_legacy/__init__.py +13 -0
  6. rucio/cli/bin_legacy/rucio.py +2825 -0
  7. rucio/cli/bin_legacy/rucio_admin.py +2500 -0
  8. rucio/cli/command.py +272 -0
  9. rucio/cli/config.py +72 -0
  10. rucio/cli/did.py +191 -0
  11. rucio/cli/download.py +128 -0
  12. rucio/cli/lifetime_exception.py +33 -0
  13. rucio/cli/replica.py +162 -0
  14. rucio/cli/rse.py +293 -0
  15. rucio/cli/rule.py +158 -0
  16. rucio/cli/scope.py +40 -0
  17. rucio/cli/subscription.py +73 -0
  18. rucio/cli/upload.py +60 -0
  19. rucio/cli/utils.py +226 -0
  20. rucio/client/__init__.py +15 -0
  21. rucio/client/accountclient.py +432 -0
  22. rucio/client/accountlimitclient.py +183 -0
  23. rucio/client/baseclient.py +983 -0
  24. rucio/client/client.py +120 -0
  25. rucio/client/configclient.py +126 -0
  26. rucio/client/credentialclient.py +59 -0
  27. rucio/client/didclient.py +868 -0
  28. rucio/client/diracclient.py +56 -0
  29. rucio/client/downloadclient.py +1783 -0
  30. rucio/client/exportclient.py +44 -0
  31. rucio/client/fileclient.py +50 -0
  32. rucio/client/importclient.py +42 -0
  33. rucio/client/lifetimeclient.py +90 -0
  34. rucio/client/lockclient.py +109 -0
  35. rucio/client/metaconventionsclient.py +140 -0
  36. rucio/client/pingclient.py +44 -0
  37. rucio/client/replicaclient.py +452 -0
  38. rucio/client/requestclient.py +125 -0
  39. rucio/client/richclient.py +317 -0
  40. rucio/client/rseclient.py +746 -0
  41. rucio/client/ruleclient.py +294 -0
  42. rucio/client/scopeclient.py +90 -0
  43. rucio/client/subscriptionclient.py +173 -0
  44. rucio/client/touchclient.py +82 -0
  45. rucio/client/uploadclient.py +969 -0
  46. rucio/common/__init__.py +13 -0
  47. rucio/common/bittorrent.py +234 -0
  48. rucio/common/cache.py +111 -0
  49. rucio/common/checksum.py +168 -0
  50. rucio/common/client.py +122 -0
  51. rucio/common/config.py +788 -0
  52. rucio/common/constants.py +217 -0
  53. rucio/common/constraints.py +17 -0
  54. rucio/common/didtype.py +237 -0
  55. rucio/common/exception.py +1208 -0
  56. rucio/common/extra.py +31 -0
  57. rucio/common/logging.py +420 -0
  58. rucio/common/pcache.py +1409 -0
  59. rucio/common/plugins.py +185 -0
  60. rucio/common/policy.py +93 -0
  61. rucio/common/schema/__init__.py +200 -0
  62. rucio/common/schema/generic.py +416 -0
  63. rucio/common/schema/generic_multi_vo.py +395 -0
  64. rucio/common/stomp_utils.py +423 -0
  65. rucio/common/stopwatch.py +55 -0
  66. rucio/common/test_rucio_server.py +154 -0
  67. rucio/common/types.py +483 -0
  68. rucio/common/utils.py +1688 -0
  69. rucio/rse/__init__.py +96 -0
  70. rucio/rse/protocols/__init__.py +13 -0
  71. rucio/rse/protocols/bittorrent.py +194 -0
  72. rucio/rse/protocols/cache.py +111 -0
  73. rucio/rse/protocols/dummy.py +100 -0
  74. rucio/rse/protocols/gfal.py +708 -0
  75. rucio/rse/protocols/globus.py +243 -0
  76. rucio/rse/protocols/http_cache.py +82 -0
  77. rucio/rse/protocols/mock.py +123 -0
  78. rucio/rse/protocols/ngarc.py +209 -0
  79. rucio/rse/protocols/posix.py +250 -0
  80. rucio/rse/protocols/protocol.py +361 -0
  81. rucio/rse/protocols/rclone.py +365 -0
  82. rucio/rse/protocols/rfio.py +145 -0
  83. rucio/rse/protocols/srm.py +338 -0
  84. rucio/rse/protocols/ssh.py +414 -0
  85. rucio/rse/protocols/storm.py +195 -0
  86. rucio/rse/protocols/webdav.py +594 -0
  87. rucio/rse/protocols/xrootd.py +302 -0
  88. rucio/rse/rsemanager.py +881 -0
  89. rucio/rse/translation.py +260 -0
  90. rucio/vcsversion.py +11 -0
  91. rucio/version.py +45 -0
  92. rucio_clients-37.0.0rc1.data/data/etc/rse-accounts.cfg.template +25 -0
  93. rucio_clients-37.0.0rc1.data/data/etc/rucio.cfg.atlas.client.template +43 -0
  94. rucio_clients-37.0.0rc1.data/data/etc/rucio.cfg.template +241 -0
  95. rucio_clients-37.0.0rc1.data/data/requirements.client.txt +19 -0
  96. rucio_clients-37.0.0rc1.data/data/rucio_client/merge_rucio_configs.py +144 -0
  97. rucio_clients-37.0.0rc1.data/scripts/rucio +133 -0
  98. rucio_clients-37.0.0rc1.data/scripts/rucio-admin +97 -0
  99. rucio_clients-37.0.0rc1.dist-info/METADATA +54 -0
  100. rucio_clients-37.0.0rc1.dist-info/RECORD +104 -0
  101. rucio_clients-37.0.0rc1.dist-info/WHEEL +5 -0
  102. rucio_clients-37.0.0rc1.dist-info/licenses/AUTHORS.rst +100 -0
  103. rucio_clients-37.0.0rc1.dist-info/licenses/LICENSE +201 -0
  104. rucio_clients-37.0.0rc1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,302 @@
1
+ # Copyright European Organization for Nuclear Research (CERN) since 2012
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import logging
16
+ import os
17
+
18
+ from rucio.common import exception
19
+ from rucio.common.checksum import PREFERRED_CHECKSUM
20
+ from rucio.common.utils import execute
21
+ from rucio.rse.protocols import protocol
22
+
23
+
24
+ class Default(protocol.RSEProtocol):
25
+ """ Implementing access to RSEs using the XRootD protocol using GSI authentication."""
26
+
27
+ @property
28
+ def _auth_env(self):
29
+ if self.auth_token:
30
+ return f"XrdSecPROTOCOL=ztn BEARER_TOKEN='{self.auth_token}'"
31
+ else:
32
+ return 'XrdSecPROTOCOL=gsi'
33
+
34
+ def __init__(self, protocol_attr, rse_settings, logger=logging.log):
35
+ """ Initializes the object with information about the referred RSE.
36
+
37
+ :param props: Properties derived from the RSE Repository
38
+ """
39
+ super(Default, self).__init__(protocol_attr, rse_settings, logger=logger)
40
+
41
+ self.scheme = self.attributes['scheme']
42
+ self.hostname = self.attributes['hostname']
43
+ self.port = str(self.attributes['port'])
44
+ self.logger = logger
45
+
46
+ def path2pfn(self, path):
47
+ """
48
+ Returns a fully qualified PFN for the file referred by path.
49
+
50
+ :param path: The path to the file.
51
+
52
+ :returns: Fully qualified PFN.
53
+
54
+ """
55
+ self.logger(logging.DEBUG, 'xrootd.path2pfn: path: {}'.format(path))
56
+ if not path.startswith('xroot') and not path.startswith('root'):
57
+ if path.startswith('/'):
58
+ return '%s://%s:%s/%s' % (self.scheme, self.hostname, self.port, path)
59
+ else:
60
+ return '%s://%s:%s//%s' % (self.scheme, self.hostname, self.port, path)
61
+ else:
62
+ return path
63
+
64
+ def exists(self, pfn):
65
+ """ Checks if the requested file is known by the referred RSE.
66
+
67
+ :param pfn: Physical file name
68
+
69
+ :returns: True if the file exists, False if it doesn't
70
+
71
+ :raise ServiceUnavailable
72
+ """
73
+ self.logger(logging.DEBUG, 'xrootd.exists: pfn: {}'.format(pfn))
74
+ try:
75
+ path = self.pfn2path(pfn)
76
+ cmd = f'{self._auth_env} xrdfs {self.hostname}:{self.port} stat {path}'
77
+ self.logger(logging.DEBUG, 'xrootd.exists: cmd: {}'.format(cmd))
78
+ status, out, err = execute(cmd)
79
+ if status != 0:
80
+ return False
81
+ except Exception as e:
82
+ raise exception.ServiceUnavailable(e)
83
+
84
+ return True
85
+
86
+ def stat(self, path):
87
+ """
88
+ Returns the stats of a file.
89
+
90
+ :param path: path to file
91
+
92
+ :raises ServiceUnavailable: if some generic error occurred in the library.
93
+
94
+ :returns: a dict with two keys, filesize and an element of GLOBALLY_SUPPORTED_CHECKSUMS.
95
+ """
96
+ self.logger(logging.DEBUG, f'xrootd.stat: path: {path}')
97
+ ret = {}
98
+ chsum = None
99
+ if path.startswith('root:'):
100
+ path = self.pfn2path(path)
101
+
102
+ try:
103
+ # xrdfs stat for getting filesize
104
+ cmd = f'{self._auth_env} xrdfs {self.hostname}:{self.port} stat {path}'
105
+ self.logger(logging.DEBUG, 'xrootd.stat: filesize cmd: {}'.format(cmd))
106
+ status_stat, out, err = execute(cmd)
107
+ if status_stat == 0:
108
+ for line in out.split('\n'):
109
+ if line and ':' in line:
110
+ k, v = line.split(':', maxsplit=1)
111
+ if k.strip().lower() == 'size':
112
+ ret['filesize'] = v.strip()
113
+ break
114
+
115
+ # xrdfs query checksum for getting checksum
116
+ cmd = f'{self._auth_env} xrdfs {self.hostname}:{self.port} query checksum {path}'
117
+ self.logger(logging.DEBUG, 'xrootd.stat: checksum cmd: {}'.format(cmd))
118
+ status_query, out, err = execute(cmd)
119
+ if status_query == 0:
120
+ chsum, value = out.strip('\n').split()
121
+ ret[chsum] = value
122
+
123
+ except Exception as e:
124
+ raise exception.ServiceUnavailable(e)
125
+
126
+ if 'filesize' not in ret:
127
+ raise exception.ServiceUnavailable('Filesize could not be retrieved.')
128
+ if PREFERRED_CHECKSUM != chsum or not chsum:
129
+ msg = '{} does not match with {}'.format(chsum, PREFERRED_CHECKSUM)
130
+ raise exception.RSEChecksumUnavailable(msg)
131
+
132
+ return ret
133
+
134
+ def pfn2path(self, pfn):
135
+ """
136
+ Returns the path of a file given the pfn, i.e. scheme and hostname are subtracted from the pfn.
137
+
138
+ :param path: pfn of a file
139
+
140
+ :returns: path.
141
+ """
142
+ self.logger(logging.DEBUG, 'xrootd.pfn2path: pfn: {}'.format(pfn))
143
+ if pfn.startswith('//'):
144
+ return pfn
145
+ elif pfn.startswith('/'):
146
+ return '/' + pfn
147
+ else:
148
+ prefix = self.attributes['prefix']
149
+ path = pfn.partition(self.attributes['prefix'])[2]
150
+ path = prefix + path
151
+ return path
152
+
153
+ def lfns2pfns(self, lfns):
154
+ """
155
+ Returns a fully qualified PFN for the file referred by path.
156
+
157
+ :param path: The path to the file.
158
+
159
+ :returns: Fully qualified PFN.
160
+ """
161
+ self.logger(logging.DEBUG, 'xrootd.lfns2pfns: lfns: {}'.format(lfns))
162
+ pfns = {}
163
+ prefix = self.attributes['prefix']
164
+
165
+ if not prefix.startswith('/'):
166
+ prefix = ''.join(['/', prefix])
167
+ if not prefix.endswith('/'):
168
+ prefix = ''.join([prefix, '/'])
169
+
170
+ lfns = [lfns] if isinstance(lfns, dict) else lfns
171
+ for lfn in lfns:
172
+ scope, name = lfn['scope'], lfn['name']
173
+ if 'path' in lfn and lfn['path'] is not None:
174
+ pfns['%s:%s' % (scope, name)] = ''.join([self.attributes['scheme'], '://', self.attributes['hostname'], ':', str(self.attributes['port']), prefix, lfn['path']])
175
+ else:
176
+ pfns['%s:%s' % (scope, name)] = ''.join([self.attributes['scheme'], '://', self.attributes['hostname'], ':', str(self.attributes['port']), prefix, self._get_path(scope=scope, name=name)])
177
+ return pfns
178
+
179
+ def connect(self):
180
+ """ Establishes the actual connection to the referred RSE.
181
+
182
+ :param credentials: Provides information to establish a connection
183
+ to the referred storage system. For S3 connections these are
184
+ access_key, secretkey, host_base, host_bucket, progress_meter
185
+ and skip_existing.
186
+
187
+ :raises RSEAccessDenied
188
+ """
189
+ self.logger(logging.DEBUG, 'xrootd.connect: port: {}, hostname {}'.format(self.port, self.hostname))
190
+ try:
191
+ # The query stats call is not implemented on some xroot doors.
192
+ # Workaround: fail, if server does not reply within 10 seconds for static config query
193
+ cmd = f'{self._auth_env} XRD_REQUESTTIMEOUT=10 xrdfs {self.hostname}:{self.port} query config {self.hostname}:{self.port}'
194
+ self.logger(logging.DEBUG, 'xrootd.connect: cmd: {}'.format(cmd))
195
+ status, out, err = execute(cmd)
196
+ if status != 0:
197
+ raise exception.RSEAccessDenied(err)
198
+ except Exception as e:
199
+ raise exception.RSEAccessDenied(e)
200
+
201
+ def close(self):
202
+ """ Closes the connection to RSE."""
203
+ pass
204
+
205
+ def get(self, pfn, dest, transfer_timeout=None):
206
+ """ Provides access to files stored inside connected the RSE.
207
+
208
+ :param pfn: Physical file name of requested file
209
+ :param dest: Name and path of the files when stored at the client
210
+ :param transfer_timeout: Transfer timeout (in seconds) - dummy
211
+
212
+ :raises DestinationNotAccessible, ServiceUnavailable, SourceNotFound
213
+ """
214
+ self.logger(logging.DEBUG, 'xrootd.get: pfn: {}'.format(pfn))
215
+ try:
216
+ cmd = f'{self._auth_env} xrdcp -f {pfn} {dest}'
217
+ self.logger(logging.DEBUG, 'xrootd.get: cmd: {}'.format(cmd))
218
+ status, out, err = execute(cmd)
219
+ if status == 54:
220
+ raise exception.SourceNotFound()
221
+ elif status != 0:
222
+ raise exception.RucioException(err)
223
+ except Exception as e:
224
+ raise exception.ServiceUnavailable(e)
225
+
226
+ def put(self, filename, target, source_dir, transfer_timeout=None):
227
+ """
228
+ Allows to store files inside the referred RSE.
229
+
230
+ :param source: path to the source file on the client file system
231
+ :param target: path to the destination file on the storage
232
+ :param source_dir: Path where the to be transferred files are stored in the local file system
233
+ :param transfer_timeout: Transfer timeout (in seconds) - dummy
234
+
235
+ :raises DestinationNotAccessible: if the destination storage was not accessible.
236
+ :raises ServiceUnavailable: if some generic error occurred in the library.
237
+ :raises SourceNotFound: if the source file was not found on the referred storage.
238
+ """
239
+ self.logger(logging.DEBUG, 'xrootd.put: filename: {} target: {}'.format(filename, target))
240
+ source_dir = source_dir or '.'
241
+ source_url = '%s/%s' % (source_dir, filename)
242
+ self.logger(logging.DEBUG, 'xrootd put: source url: {}'.format(source_url))
243
+ path = self.path2pfn(target)
244
+ if not os.path.exists(source_url):
245
+ raise exception.SourceNotFound()
246
+ try:
247
+ cmd = f'{self._auth_env} xrdcp -f {source_url} {path}'
248
+ self.logger(logging.DEBUG, 'xrootd.put: cmd: {}'.format(cmd))
249
+ status, out, err = execute(cmd)
250
+ if status != 0:
251
+ raise exception.RucioException(err)
252
+ except Exception as e:
253
+ raise exception.ServiceUnavailable(e)
254
+
255
+ def delete(self, pfn):
256
+ """
257
+ Deletes a file from the connected RSE.
258
+
259
+ :param pfn: Physical file name
260
+
261
+ :raises ServiceUnavailable: if some generic error occurred in the library.
262
+ :raises SourceNotFound: if the source file was not found on the referred storage.
263
+ """
264
+ self.logger(logging.DEBUG, 'xrootd.delete: pfn: {}'.format(pfn))
265
+ if not self.exists(pfn):
266
+ raise exception.SourceNotFound()
267
+ try:
268
+ path = self.pfn2path(pfn)
269
+ cmd = f'{self._auth_env} xrdfs {self.hostname}:{self.port} rm {path}'
270
+ self.logger(logging.DEBUG, 'xrootd.delete: cmd: {}'.format(cmd))
271
+ status, out, err = execute(cmd)
272
+ if status != 0:
273
+ raise exception.RucioException(err)
274
+ except Exception as e:
275
+ raise exception.ServiceUnavailable(e)
276
+
277
+ def rename(self, pfn, new_pfn):
278
+ """ Allows to rename a file stored inside the connected RSE.
279
+
280
+ :param pfn: Current physical file name
281
+ :param new_pfn New physical file name
282
+ :raises DestinationNotAccessible: if the destination storage was not accessible.
283
+ :raises ServiceUnavailable: if some generic error occurred in the library.
284
+ :raises SourceNotFound: if the source file was not found on the referred storage.
285
+ """
286
+ self.logger(logging.DEBUG, 'xrootd.rename: pfn: {}'.format(pfn))
287
+ if not self.exists(pfn):
288
+ raise exception.SourceNotFound()
289
+ try:
290
+ path = self.pfn2path(pfn)
291
+ new_path = self.pfn2path(new_pfn)
292
+ new_dir = new_path[:new_path.rindex('/') + 1]
293
+ cmd = f'{self._auth_env} xrdfs {self.hostname}:{self.port} mkdir -p {new_dir}'
294
+ self.logger(logging.DEBUG, 'xrootd.stat: mkdir cmd: {}'.format(cmd))
295
+ status, out, err = execute(cmd)
296
+ cmd = f'{self._auth_env} xrdfs {self.hostname}:{self.port} mv {path} {new_path}'
297
+ self.logger(logging.DEBUG, 'xrootd.stat: rename cmd: {}'.format(cmd))
298
+ status, out, err = execute(cmd)
299
+ if status != 0:
300
+ raise exception.RucioException(err)
301
+ except Exception as e:
302
+ raise exception.ServiceUnavailable(e)