rucio-clients 35.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.

Files changed (88) hide show
  1. rucio/__init__.py +17 -0
  2. rucio/alembicrevision.py +15 -0
  3. rucio/client/__init__.py +15 -0
  4. rucio/client/accountclient.py +433 -0
  5. rucio/client/accountlimitclient.py +183 -0
  6. rucio/client/baseclient.py +974 -0
  7. rucio/client/client.py +76 -0
  8. rucio/client/configclient.py +126 -0
  9. rucio/client/credentialclient.py +59 -0
  10. rucio/client/didclient.py +866 -0
  11. rucio/client/diracclient.py +56 -0
  12. rucio/client/downloadclient.py +1785 -0
  13. rucio/client/exportclient.py +44 -0
  14. rucio/client/fileclient.py +50 -0
  15. rucio/client/importclient.py +42 -0
  16. rucio/client/lifetimeclient.py +90 -0
  17. rucio/client/lockclient.py +109 -0
  18. rucio/client/metaconventionsclient.py +140 -0
  19. rucio/client/pingclient.py +44 -0
  20. rucio/client/replicaclient.py +454 -0
  21. rucio/client/requestclient.py +125 -0
  22. rucio/client/rseclient.py +746 -0
  23. rucio/client/ruleclient.py +294 -0
  24. rucio/client/scopeclient.py +90 -0
  25. rucio/client/subscriptionclient.py +173 -0
  26. rucio/client/touchclient.py +82 -0
  27. rucio/client/uploadclient.py +955 -0
  28. rucio/common/__init__.py +13 -0
  29. rucio/common/cache.py +74 -0
  30. rucio/common/config.py +801 -0
  31. rucio/common/constants.py +159 -0
  32. rucio/common/constraints.py +17 -0
  33. rucio/common/didtype.py +189 -0
  34. rucio/common/exception.py +1151 -0
  35. rucio/common/extra.py +36 -0
  36. rucio/common/logging.py +420 -0
  37. rucio/common/pcache.py +1408 -0
  38. rucio/common/plugins.py +153 -0
  39. rucio/common/policy.py +84 -0
  40. rucio/common/schema/__init__.py +150 -0
  41. rucio/common/schema/atlas.py +413 -0
  42. rucio/common/schema/belleii.py +408 -0
  43. rucio/common/schema/domatpc.py +401 -0
  44. rucio/common/schema/escape.py +426 -0
  45. rucio/common/schema/generic.py +433 -0
  46. rucio/common/schema/generic_multi_vo.py +412 -0
  47. rucio/common/schema/icecube.py +406 -0
  48. rucio/common/stomp_utils.py +159 -0
  49. rucio/common/stopwatch.py +55 -0
  50. rucio/common/test_rucio_server.py +148 -0
  51. rucio/common/types.py +403 -0
  52. rucio/common/utils.py +2238 -0
  53. rucio/rse/__init__.py +96 -0
  54. rucio/rse/protocols/__init__.py +13 -0
  55. rucio/rse/protocols/bittorrent.py +184 -0
  56. rucio/rse/protocols/cache.py +122 -0
  57. rucio/rse/protocols/dummy.py +111 -0
  58. rucio/rse/protocols/gfal.py +703 -0
  59. rucio/rse/protocols/globus.py +243 -0
  60. rucio/rse/protocols/gsiftp.py +92 -0
  61. rucio/rse/protocols/http_cache.py +82 -0
  62. rucio/rse/protocols/mock.py +123 -0
  63. rucio/rse/protocols/ngarc.py +209 -0
  64. rucio/rse/protocols/posix.py +250 -0
  65. rucio/rse/protocols/protocol.py +594 -0
  66. rucio/rse/protocols/rclone.py +364 -0
  67. rucio/rse/protocols/rfio.py +136 -0
  68. rucio/rse/protocols/srm.py +338 -0
  69. rucio/rse/protocols/ssh.py +413 -0
  70. rucio/rse/protocols/storm.py +206 -0
  71. rucio/rse/protocols/webdav.py +550 -0
  72. rucio/rse/protocols/xrootd.py +301 -0
  73. rucio/rse/rsemanager.py +764 -0
  74. rucio/vcsversion.py +11 -0
  75. rucio/version.py +38 -0
  76. rucio_clients-35.7.0.data/data/etc/rse-accounts.cfg.template +25 -0
  77. rucio_clients-35.7.0.data/data/etc/rucio.cfg.atlas.client.template +42 -0
  78. rucio_clients-35.7.0.data/data/etc/rucio.cfg.template +257 -0
  79. rucio_clients-35.7.0.data/data/requirements.client.txt +15 -0
  80. rucio_clients-35.7.0.data/data/rucio_client/merge_rucio_configs.py +144 -0
  81. rucio_clients-35.7.0.data/scripts/rucio +2542 -0
  82. rucio_clients-35.7.0.data/scripts/rucio-admin +2447 -0
  83. rucio_clients-35.7.0.dist-info/METADATA +50 -0
  84. rucio_clients-35.7.0.dist-info/RECORD +88 -0
  85. rucio_clients-35.7.0.dist-info/WHEEL +5 -0
  86. rucio_clients-35.7.0.dist-info/licenses/AUTHORS.rst +97 -0
  87. rucio_clients-35.7.0.dist-info/licenses/LICENSE +201 -0
  88. rucio_clients-35.7.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,243 @@
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
+ from urllib.parse import urlparse
17
+
18
+ from rucio.common import exception
19
+ from rucio.common.constants import RseAttr
20
+ from rucio.common.extra import import_extras
21
+ from rucio.core.rse import get_rse_attribute
22
+ from rucio.rse.protocols.protocol import RSEProtocol
23
+ from rucio.transfertool.globus_library import get_transfer_client, send_bulk_delete_task, send_delete_task
24
+
25
+ EXTRA_MODULES = import_extras(['globus_sdk'])
26
+
27
+ if EXTRA_MODULES['globus_sdk']:
28
+ from globus_sdk import TransferAPIError # pylint: disable=import-error
29
+
30
+
31
+ class GlobusRSEProtocol(RSEProtocol):
32
+ """ Implementing access to RSEs using the Globus service as a Rucio RSE protocol. """
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 of the requested protocol
38
+ """
39
+ super(GlobusRSEProtocol, self).__init__(protocol_attr, rse_settings, logger=logger)
40
+ self.globus_endpoint_id = get_rse_attribute(self.rse.get('id'), RseAttr.GLOBUS_ENDPOINT_ID)
41
+ self.logger = logger
42
+
43
+ def lfns2pfns(self, lfns):
44
+ """
45
+ Returns a fully qualified PFN for the file referred by path.
46
+
47
+ :param path: The path to the file.
48
+
49
+ :returns: Fully qualified PFN.
50
+ """
51
+ pfns = {}
52
+ prefix = self.attributes['prefix']
53
+
54
+ if not prefix.startswith('/'):
55
+ prefix = ''.join(['/', prefix])
56
+ if not prefix.endswith('/'):
57
+ prefix = ''.join([prefix, '/'])
58
+
59
+ lfns = [lfns] if isinstance(lfns, dict) else lfns
60
+ for lfn in lfns:
61
+ scope, name = lfn['scope'], lfn['name']
62
+
63
+ if 'path' in lfn and lfn['path'] is not None:
64
+ pfns['%s:%s' % (scope, name)] = ''.join([prefix, lfn['path'] if not lfn['path'].startswith('/') else lfn['path'][1:]])
65
+ else:
66
+ pfns['%s:%s' % (scope, name)] = ''.join([prefix, self._get_path(scope=scope, name=name)])
67
+ return pfns
68
+
69
+ def _get_path(self, scope, name):
70
+ """ Transforms the logical file name into a PFN.
71
+ Suitable for sites implementing the RUCIO naming convention.
72
+ This implementation is only invoked if the RSE is deterministic.
73
+
74
+ :param scope: scope
75
+ :param name: filename
76
+
77
+ :returns: RSE specific URI of the physical file
78
+ """
79
+ return self.translator.path(scope, name)
80
+
81
+ def parse_pfns(self, pfns):
82
+ """
83
+ Splits the given PFN into the parts known by the protocol. It is also checked if the provided protocol supports the given PFNs.
84
+
85
+ :param pfns: a list of a fully qualified PFNs
86
+
87
+ :returns: dic with PFN as key and a dict with path and name as value
88
+
89
+ :raises RSEFileNameNotSupported: if the provided PFN doesn't match with the protocol settings
90
+ """
91
+ ret = dict()
92
+ pfns = [pfns] if isinstance(pfns, str) else pfns
93
+
94
+ for pfn in pfns:
95
+ parsed = urlparse(pfn)
96
+ scheme = parsed.scheme
97
+ hostname = parsed.netloc.partition(':')[0]
98
+ port = int(parsed.netloc.partition(':')[2]) if parsed.netloc.partition(':')[2] != '' else 0
99
+ while '//' in parsed.path:
100
+ parsed = parsed._replace(path=parsed.path.replace('//', '/'))
101
+ path = parsed.path
102
+
103
+ # Protect against 'lazy' defined prefixes for RSEs in the repository
104
+ if not self.attributes['prefix'].startswith('/'):
105
+ self.attributes['prefix'] = '/' + self.attributes['prefix']
106
+ if not self.attributes['prefix'].endswith('/'):
107
+ self.attributes['prefix'] += '/'
108
+
109
+ if self.attributes['hostname'] != hostname:
110
+ if self.attributes['hostname'] != 'localhost': # In the database empty hostnames are replaced with localhost but for some URIs (e.g. file) a hostname is not included
111
+ raise exception.RSEFileNameNotSupported('Invalid hostname: provided \'%s\', expected \'%s\'' % (hostname, self.attributes['hostname']))
112
+
113
+ if self.attributes['port'] != port:
114
+ raise exception.RSEFileNameNotSupported('Invalid port: provided \'%s\', expected \'%s\'' % (port, self.attributes['port']))
115
+
116
+ if not path.startswith(self.attributes['prefix']):
117
+ raise exception.RSEFileNameNotSupported('Invalid prefix: provided \'%s\', expected \'%s\'' % ('/'.join(path.split('/')[0:len(self.attributes['prefix'].split('/')) - 1]),
118
+ self.attributes['prefix'])) # len(...)-1 due to the leading '/
119
+
120
+ # Splitting parsed.path into prefix, path, filename
121
+ prefix = self.attributes['prefix']
122
+ path = path.partition(self.attributes['prefix'])[2]
123
+ name = path.split('/')[-1]
124
+ path = '/'.join(path.split('/')[:-1])
125
+ if not path.startswith('/'):
126
+ path = '/' + path
127
+ if path != '/' and not path.endswith('/'):
128
+ path = path + '/'
129
+ ret[pfn] = {'path': path, 'name': name, 'scheme': scheme, 'prefix': prefix, 'port': port, 'hostname': hostname, }
130
+
131
+ return ret
132
+
133
+ def exists(self, path):
134
+ """
135
+ Checks if the requested file is known by the referred RSE.
136
+
137
+ :param path: Physical file name
138
+
139
+ :returns: True if the file exists, False if it doesn't
140
+
141
+ :raises SourceNotFound: if the source file was not found on the referred storage.
142
+
143
+ """
144
+
145
+ filepath = '/'.join(path.split('/')[0:-1]) + '/'
146
+ filename = path.split('/')[-1]
147
+
148
+ transfer_client = get_transfer_client()
149
+ exists = False
150
+
151
+ if self.globus_endpoint_id:
152
+ try:
153
+ resp = transfer_client.operation_ls(endpoint_id=self.globus_endpoint_id, path=filepath)
154
+ exists = len([r for r in resp if r['name'] == filename]) > 0
155
+ except TransferAPIError as err:
156
+ print(err)
157
+ else:
158
+ print('No rse attribute found for globus endpoint id.')
159
+
160
+ return exists
161
+
162
+ def list(self, path):
163
+ """
164
+
165
+ Checks if the requested path is known by the referred RSE and returns a list of items
166
+
167
+ :param path: Physical file name
168
+
169
+ :returns: List of items
170
+
171
+ """
172
+
173
+ transfer_client = get_transfer_client()
174
+ items = []
175
+
176
+ if self.globus_endpoint_id:
177
+ try:
178
+ resp = transfer_client.operation_ls(endpoint_id=self.globus_endpoint_id, path=path)
179
+ items = resp['DATA']
180
+ except TransferAPIError as err:
181
+ print(err)
182
+ else:
183
+ print('No rse attribute found for globus endpoint id.')
184
+
185
+ return items
186
+
187
+ def delete(self, path):
188
+ """
189
+ Deletes a file from the connected RSE.
190
+
191
+ :param path: path to the to be deleted file
192
+
193
+ :raises ServiceUnavailable: if some generic error occurred in the library.
194
+ :raises SourceNotFound: if the source file was not found on the referred storage.
195
+ """
196
+ if self.globus_endpoint_id:
197
+ try:
198
+ delete_response = send_delete_task(endpoint_id=self.globus_endpoint_id, path=path, logger=self.logger)
199
+ except TransferAPIError as err:
200
+ self.logger(logging.WARNING, str(err))
201
+ raise exception.RucioException(err)
202
+ else:
203
+ raise exception.RucioException('No rse attribute found for globus endpoint id.')
204
+
205
+ if delete_response['code'] != 'Accepted':
206
+ self.logger(logging.DEBUG, 'delete_response: %s' % delete_response)
207
+ raise exception.RucioException('delete_task not accepted by Globus')
208
+
209
+ def bulk_delete(self, pfns):
210
+ """
211
+ Submits an async task to bulk delete files on globus endpoint.
212
+
213
+ :param pfns: list of pfns to delete
214
+
215
+ :raises TransferAPIError: if unexpected response from the service.
216
+ """
217
+ if self.globus_endpoint_id:
218
+ try:
219
+ bulk_delete_response = send_bulk_delete_task(endpoint_id=self.globus_endpoint_id, pfns=pfns, logger=self.logger)
220
+ except TransferAPIError as err:
221
+ raise exception.RucioException(err)
222
+ else:
223
+ raise exception.RucioException('No rse attribute found for globus endpoint id.')
224
+
225
+ if bulk_delete_response['code'] != 'Accepted':
226
+ self.logger(logging.DEBUG, 'delete_response: %s' % bulk_delete_response)
227
+ raise exception.RucioException('delete_task not accepted by Globus')
228
+
229
+ def connect(self):
230
+ """
231
+ Establishes the actual connection to the referred RSE.
232
+
233
+ reaper2 daemon requires implementation of protocol.connect
234
+ """
235
+ pass
236
+
237
+ def close(self):
238
+ """
239
+ Closes the connection to RSE.
240
+
241
+ reaper2 daemon requires implementation of protocol.close
242
+ """
243
+ pass
@@ -0,0 +1,92 @@
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 json
16
+ import os
17
+
18
+ import requests
19
+
20
+ from rucio.common import exception
21
+ from rucio.rse.protocols import protocol
22
+
23
+
24
+ class Default(protocol.RSEProtocol):
25
+ """ Implementing access to RSEs using gsiftp."""
26
+
27
+ def __init__(self, protocol_attr, rse_settings, logger=None):
28
+ """ Initializes the object with information about the referred RSE.
29
+
30
+ :param props: Properties derived from the RSE Repository
31
+ """
32
+ super(Default, self).__init__(protocol_attr, rse_settings, logger=logger)
33
+
34
+ def connect(self):
35
+ """
36
+ Establishes the actual connection to the referred RSE.
37
+ If we decide to use gfal, init should be done here.
38
+
39
+ :raises RSEAccessDenied
40
+ """
41
+ pass
42
+
43
+ def close(self):
44
+ """
45
+ Closes the connection to RSE.
46
+ """
47
+ pass
48
+
49
+ def get_space_usage(self):
50
+ """
51
+ Get RSE space usage information.
52
+
53
+ :returns: a list with dict containing 'totalsize' and 'unusedsize'
54
+
55
+ :raises ServiceUnavailable: if some generic error occurred in the library.
56
+ """
57
+ rse_name = self.rse['rse']
58
+ dest = '/tmp/rucio-gsiftp-site-size_' + rse_name
59
+ space_usage_url = ''
60
+ # url of space usage json, would be nicer to have it in rse_settings
61
+ agis = requests.get('http://atlas-agis-api.cern.ch/request/ddmendpoint/query/list/?json').json()
62
+ agis_token = ''
63
+ for res in agis:
64
+ if rse_name == res['name']:
65
+ agis_token = res['token']
66
+ space_usage_url = res['space_usage_url']
67
+
68
+ import gfal2 # pylint: disable=import-error
69
+ gfal2.set_verbose(gfal2.verbose_level.normal) # pylint: disable=no-member
70
+ try:
71
+ if os.path.exists(dest):
72
+ os.remove(dest)
73
+ ctx = gfal2.creat_context() # pylint: disable=no-member
74
+ ctx.set_opt_string_list("SRM PLUGIN", "TURL_PROTOCOLS", ["gsiftp", "rfio", "gsidcap", "dcap", "kdcap"])
75
+ params = ctx.transfer_parameters()
76
+ params.timeout = 3600
77
+ ret = ctx.filecopy(params, str(space_usage_url), str('file://' + dest))
78
+
79
+ if ret == 0:
80
+ data_file = open(dest)
81
+ data = json.load(data_file)
82
+ data_file.close()
83
+ if agis_token not in list(data.keys()):
84
+ print('ERROR: space usage json has different token as key')
85
+ else:
86
+ totalsize = int(data[agis_token]['total_space'])
87
+ used = int(data[agis_token]['used_space'])
88
+ unusedsize = totalsize - used
89
+ return totalsize, unusedsize
90
+ except Exception as error:
91
+ print(error)
92
+ raise exception.ServiceUnavailable(error)
@@ -0,0 +1,82 @@
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
+ from rucio.rse.protocols import ngarc
16
+
17
+
18
+ class Default(ngarc.Default):
19
+
20
+ """ Implementing access to RSEs using the ngarc protocol."""
21
+
22
+ def __init__(self, protocol_attr, rse_settings, logger=None):
23
+ """ Initializes the object with information about the referred RSE.
24
+
25
+ :param props: Properties derived from the RSE Repository
26
+ """
27
+ super(Default, self).__init__(protocol_attr, rse_settings, logger=logger)
28
+ self.attributes.pop('determinism_type', None)
29
+ self.files = []
30
+
31
+ def _get_path(self, scope, name):
32
+ """ Transforms the physical file name into the local URI in the referred RSE.
33
+ Suitable for sites implementoing the RUCIO naming convention.
34
+
35
+ :param name: filename
36
+ :param scope: scope
37
+
38
+ :returns: RSE specific URI of the physical file
39
+ """
40
+ return '%s/%s' % (scope, name)
41
+
42
+ def path2pfn(self, path):
43
+ """
44
+ Returns a fully qualified PFN for the file referred by path.
45
+
46
+ :param path: The path to the file.
47
+
48
+ :returns: Fully qualified PFN.
49
+
50
+ """
51
+ return ''.join([self.attributes['scheme'], '://%s' % self.attributes['hostname'], path])
52
+
53
+ def put(self, source, target, source_dir=None, transfer_timeout=None):
54
+ """ Allows to store files inside the referred RSE.
55
+
56
+ :param source: Physical file name
57
+ :param target: Name of the file on the storage system e.g. with prefixed scope
58
+ :param source_dir Path where the to be transferred files are stored in the local file system
59
+ :param transfer_timeout Transfer timeout (in seconds)
60
+
61
+ :raises DestinationNotAccessible, ServiceUnavailable, SourceNotFound
62
+ """
63
+ raise NotImplementedError
64
+
65
+ def delete(self, pfn):
66
+ """ Deletes a file from the connected RSE.
67
+
68
+ :param pfn: Physical file name
69
+
70
+ :raises ServiceUnavailable, SourceNotFound
71
+ """
72
+ raise NotImplementedError
73
+
74
+ def rename(self, pfn, new_pfn):
75
+ """ Allows to rename a file stored inside the connected RSE.
76
+
77
+ :param pfn: Current physical file name
78
+ :param new_pfn New physical file name
79
+
80
+ :raises DestinationNotAccessible, ServiceUnavailable, SourceNotFound
81
+ """
82
+ raise NotImplementedError
@@ -0,0 +1,123 @@
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
+ from rucio.common import exception
16
+ from rucio.rse.protocols import protocol
17
+
18
+
19
+ class Default(protocol.RSEProtocol):
20
+ """ Implementing access to RSEs using the local filesystem."""
21
+
22
+ def __init__(self, protocol_attr, rse_settings, logger=None):
23
+ """ Initializes the object with information about the referred RSE.
24
+
25
+ :param props: Properties derived from the RSE Repository
26
+ """
27
+ super(Default, self).__init__(protocol_attr, rse_settings, logger=logger)
28
+ self.attributes.pop('determinism_type', None)
29
+ self.files = []
30
+
31
+ def path2pfn(self, path):
32
+ """
33
+ Returns a fully qualified PFN for the file referred by path.
34
+
35
+ :param path: The path to the file.
36
+
37
+ :returns: Fully qualified PFN.
38
+
39
+ """
40
+ return ''.join([self.rse['scheme'], '://%s' % self.rse['hostname'], path])
41
+
42
+ def exists(self, pfn):
43
+ """ Checks if the requested file is known by the referred RSE.
44
+
45
+ :param pfn: Physical file name
46
+
47
+ :returns: True if the file exists, False if it doesn't
48
+
49
+ :raise ServiceUnavailable
50
+ """
51
+ return pfn in self.files
52
+
53
+ def connect(self):
54
+ """ Establishes the actual connection to the referred RSE.
55
+
56
+ :param credentials: Provide all necessary information to establish a connection
57
+ to the referred storage system. Some is loaded from the repository inside the
58
+ RSE class and some must be provided specific for the SFTP protocol like
59
+ username, password, private_key, private_key_pass, port.
60
+ For details about possible additional parameters and details about their usage
61
+ see the pysftp.Connection() documentation.
62
+ NOTE: the host parametrer is overwritten with the value provided by the repository
63
+
64
+ :raise RSEAccessDenied
65
+ """
66
+ pass
67
+
68
+ def close(self):
69
+ """ Closes the connection to RSE."""
70
+ pass
71
+
72
+ def get(self, pfn, dest, transfer_timeout=None):
73
+ """ Provides access to files stored inside connected the RSE.
74
+
75
+ :param pfn: Physical file name of requested file
76
+ :param dest: Name and path of the files when stored at the client
77
+ :param transfer_timeout Transfer timeout (in seconds) - dummy
78
+
79
+ :raises DestinationNotAccessible, ServiceUnavailable, SourceNotFound
80
+ """
81
+ if pfn not in self.files:
82
+ raise exception.SourceNotFound(pfn)
83
+
84
+ def put(self, source, target, source_dir=None, transfer_timeout=None):
85
+ """ Allows to store files inside the referred RSE.
86
+
87
+ :param source: Physical file name
88
+ :param target: Name of the file on the storage system e.g. with prefixed scope
89
+ :param source_dir Path where the to be transferred files are stored in the local file system
90
+ :param transfer_timeout Transfer timeout (in seconds) - dummy
91
+
92
+ :raises DestinationNotAccessible, ServiceUnavailable, SourceNotFound
93
+ """
94
+ self.files.append(target)
95
+
96
+ def delete(self, pfn):
97
+ """ Deletes a file from the connected RSE.
98
+
99
+ :param pfn: Physical file name
100
+
101
+ :raises ServiceUnavailable, SourceNotFound
102
+ """
103
+ pass
104
+
105
+ def bulk_delete(self, pfns):
106
+ """
107
+ Submits an async task to bulk delete files.
108
+
109
+ :param pfns: list of pfns to delete
110
+
111
+ :raises TransferAPIError: if unexpected response from the service.
112
+ """
113
+ pass
114
+
115
+ def rename(self, pfn, new_pfn):
116
+ """ Allows to rename a file stored inside the connected RSE.
117
+
118
+ :param pfn: Current physical file name
119
+ :param new_pfn New physical file name
120
+
121
+ :raises DestinationNotAccessible, ServiceUnavailable, SourceNotFound
122
+ """
123
+ pass