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
rucio/rse/__init__.py ADDED
@@ -0,0 +1,96 @@
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 dogpile.cache import make_region
16
+
17
+ from rucio.common.utils import is_client
18
+ from rucio.rse import rsemanager
19
+
20
+ if is_client():
21
+ setattr(rsemanager, 'CLIENT_MODE', True)
22
+ setattr(rsemanager, 'SERVER_MODE', False)
23
+ else:
24
+ setattr(rsemanager, 'CLIENT_MODE', False)
25
+ setattr(rsemanager, 'SERVER_MODE', True)
26
+
27
+
28
+ def get_rse_client(rse, vo='def', **kwarg):
29
+ '''
30
+ get_rse_client
31
+ '''
32
+ from rucio.client.rseclient import RSEClient
33
+ client = RSEClient(vo=vo)
34
+ return client.get_rse(rse)
35
+
36
+
37
+ def get_signed_url_client(rse, service, op, url, vo='def'):
38
+ '''
39
+ get_signed_url_client
40
+ '''
41
+ from rucio.client.credentialclient import CredentialClient
42
+ return CredentialClient(vo=vo).get_signed_url(rse, service, op, url)
43
+
44
+
45
+ def get_signed_url_server(rse, service, op, url, vo='def'):
46
+ '''
47
+ get_signed_url_server
48
+ '''
49
+ from rucio.core.credential import get_signed_url
50
+ from rucio.core.rse import get_rse_id
51
+
52
+ rse_id = get_rse_id(rse=rse, vo=vo)
53
+ return get_signed_url(rse_id, service, op, url)
54
+
55
+
56
+ def rse_key_generator(namespace, fn, **kwargs):
57
+ '''
58
+ Key generator for RSE
59
+ '''
60
+ def generate_key(rse, vo='def', session=None):
61
+ '''
62
+ generate_key
63
+ '''
64
+ return '{}:{}'.format(rse, vo)
65
+ return generate_key
66
+
67
+
68
+ if rsemanager.CLIENT_MODE: # pylint:disable=no-member
69
+ setattr(rsemanager, '__request_rse_info', get_rse_client)
70
+ setattr(rsemanager, '__get_signed_url', get_signed_url_client)
71
+
72
+ # Preparing region for dogpile.cache
73
+ RSE_REGION = make_region(function_key_generator=rse_key_generator).configure(
74
+ 'dogpile.cache.memory',
75
+ expiration_time=900)
76
+ setattr(rsemanager, 'RSE_REGION', RSE_REGION)
77
+
78
+
79
+ if rsemanager.SERVER_MODE: # pylint:disable=no-member
80
+ from rucio.common.cache import make_region_memcached
81
+ from rucio.core.rse import get_rse_id, get_rse_protocols
82
+ from rucio.core.vo import map_vo
83
+
84
+ def tmp_rse_info(rse=None, vo='def', rse_id=None, session=None):
85
+ if rse_id is None:
86
+ # This can be called directly by client tools if they're co-located on a server
87
+ # i.e. running rucio cli on a server and during the test suite.
88
+ # We have to map to VO name here for this situations, despite this nominally
89
+ # not being a client interface.
90
+ rse_id = get_rse_id(rse=rse, vo=map_vo(vo))
91
+ return get_rse_protocols(rse_id=rse_id, session=session)
92
+
93
+ setattr(rsemanager, '__request_rse_info', tmp_rse_info)
94
+ setattr(rsemanager, '__get_signed_url', get_signed_url_server)
95
+ RSE_REGION = make_region_memcached(expiration_time=900)
96
+ setattr(rsemanager, 'RSE_REGION', RSE_REGION)
@@ -0,0 +1,13 @@
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.
@@ -0,0 +1,184 @@
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 base64
16
+ import logging
17
+ import os.path
18
+ import time
19
+ from urllib.parse import parse_qs, urlencode, urlparse
20
+
21
+ from rucio.common import exception
22
+ from rucio.common.extra import import_extras
23
+ from rucio.common.utils import construct_torrent, resolve_ip
24
+ from rucio.rse import rsemanager
25
+ from rucio.rse.protocols.protocol import RSEProtocol
26
+
27
+ EXTRA_MODULES = import_extras(['libtorrent'])
28
+
29
+ lt = None
30
+ if EXTRA_MODULES['libtorrent']:
31
+ import libtorrent as lt # pylint: disable=E0401
32
+
33
+ if getattr(rsemanager, 'CLIENT_MODE', None):
34
+ from rucio.client.didclient import DIDClient
35
+
36
+ def _fetch_meta_client(rse_id: str, scope: str, name: str):
37
+ return DIDClient().get_metadata(scope=scope, name=name, plugin='all')
38
+
39
+ _fetch_meta = _fetch_meta_client
40
+ else:
41
+ from rucio.common.types import InternalScope
42
+ from rucio.core.did import get_metadata
43
+ from rucio.core.rse import get_rse_vo
44
+
45
+ def _fetch_meta_server(rse_id: str, scope: str, name: str):
46
+ vo = get_rse_vo(rse_id)
47
+ return get_metadata(scope=InternalScope(scope, vo=vo), name=name, plugin='all')
48
+
49
+ _fetch_meta = _fetch_meta_server
50
+
51
+
52
+ class Default(RSEProtocol):
53
+
54
+ def __init__(self, protocol_attr, rse_settings, logger=logging.log):
55
+ super(Default, self).__init__(protocol_attr, rse_settings, logger=logger)
56
+ self.logger = logger
57
+
58
+ def lfns2pfns(self, lfns):
59
+ pfns = {}
60
+ prefix = self.attributes['prefix']
61
+
62
+ if not prefix.startswith('/'):
63
+ prefix = ''.join(['/', prefix])
64
+ if not prefix.endswith('/'):
65
+ prefix = ''.join([prefix, '/'])
66
+
67
+ host_port = '%s:%s' % (self.attributes['hostname'], str(self.attributes['port']))
68
+
69
+ lfns = [lfns] if isinstance(lfns, dict) else lfns
70
+ for lfn in lfns:
71
+ scope, name = lfn['scope'], lfn['name']
72
+
73
+ if 'path' in lfn and lfn['path'] is not None:
74
+ path = lfn['path'] if not lfn['path'].startswith('/') else lfn['path'][1:]
75
+ else:
76
+ path = self._get_path(scope=scope, name=name)
77
+
78
+ scope_name = '%s:%s' % (scope, name)
79
+
80
+ query = {
81
+ 'x.pe': host_port,
82
+ 'x.rucio_scope': scope,
83
+ 'x.rucio_name': name,
84
+ 'x.rucio_path': ''.join((prefix, path))
85
+ }
86
+ pfns[scope_name] = 'magnet:?' + urlencode(query)
87
+
88
+ return pfns
89
+
90
+ def parse_pfns(self, pfns):
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
+
98
+ query = parse_qs(parsed.query)
99
+ host_port = next(iter(query.get('x.pe', [])), ':')
100
+ hostname, port = host_port.split(':')
101
+ port = int(port)
102
+ path = next(iter(query.get('x.rucio_path', [])), '')
103
+ scope = next(iter(query.get('x.rucio_scope', [])), '')
104
+ name = next(iter(query.get('x.rucio_name', [])), '')
105
+
106
+ # Protect against 'lazy' defined prefixes for RSEs in the repository
107
+ if not self.attributes['prefix'].startswith('/'):
108
+ self.attributes['prefix'] = '/' + self.attributes['prefix']
109
+ if not self.attributes['prefix'].endswith('/'):
110
+ self.attributes['prefix'] += '/'
111
+
112
+ if self.attributes['hostname'] != hostname:
113
+ 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
114
+ raise exception.RSEFileNameNotSupported('Invalid hostname: provided \'%s\', expected \'%s\'' % (hostname, self.attributes['hostname']))
115
+
116
+ if self.attributes['port'] != port:
117
+ raise exception.RSEFileNameNotSupported('Invalid port: provided \'%s\', expected \'%s\'' % (port, self.attributes['port']))
118
+
119
+ if not path.startswith(self.attributes['prefix']):
120
+ raise exception.RSEFileNameNotSupported('Invalid prefix: provided \'%s\', expected \'%s\'' % ('/'.join(path.split('/')[0:len(self.attributes['prefix'].split('/')) - 1]),
121
+ self.attributes['prefix'])) # len(...)-1 due to the leading '/
122
+
123
+ # Splitting parsed.path into prefix, path, filename
124
+ prefix = self.attributes['prefix']
125
+ path = path.partition(self.attributes['prefix'])[2]
126
+ path = '/'.join(path.split('/')[:-1])
127
+ if not path.startswith('/'):
128
+ path = '/' + path
129
+ if path != '/' and not path.endswith('/'):
130
+ path = path + '/'
131
+ ret[pfn] = {'path': path, 'scope': scope, 'name': name, 'scheme': scheme, 'prefix': prefix, 'port': port, 'hostname': hostname, }
132
+
133
+ return ret
134
+
135
+ def connect(self):
136
+ pass
137
+
138
+ def close(self):
139
+ pass
140
+
141
+ def get(self, path, dest, transfer_timeout=None):
142
+ if not lt:
143
+ raise exception.RucioException('The libtorrent python package is required to perform this operation')
144
+
145
+ [lfn] = self.parse_pfns([path]).values()
146
+ scope = lfn['scope']
147
+ name = lfn['name']
148
+ hostname = lfn['hostname']
149
+ port = lfn['port']
150
+
151
+ meta = _fetch_meta(rse_id=self.rse['id'], scope=scope, name=name)
152
+ pieces_root = base64.b64decode(meta.get('bittorrent_pieces_root', ''))
153
+ if not pieces_root:
154
+ raise exception.RucioException('Torrent metadata missing. Cannot download file.')
155
+
156
+ length = meta.get('bytes')
157
+ piece_length = meta.get('bittorrent_piece_length', 0)
158
+ pieces_layers = base64.b64decode(meta.get('bittorrent_pieces_layers', ''))
159
+
160
+ _, torrent = construct_torrent(
161
+ scope=scope,
162
+ name=name,
163
+ length=length,
164
+ piece_length=piece_length,
165
+ pieces_root=pieces_root,
166
+ pieces_layers=pieces_layers,
167
+ )
168
+
169
+ ses = lt.session() # type: ignore # noqa
170
+ params = {
171
+ 'ti': lt.torrent_info(torrent), # type: ignore # noqa
172
+ 'save_path': os.path.dirname(dest),
173
+ 'name': os.path.basename(dest),
174
+ 'renamed_files': {0: os.path.basename(dest)},
175
+ }
176
+
177
+ handle = ses.add_torrent(params)
178
+ try:
179
+ handle.resume()
180
+ handle.connect_peer((resolve_ip(hostname), port))
181
+ while handle.status().progress != 1.0:
182
+ time.sleep(0.25)
183
+ finally:
184
+ ses.remove_torrent(handle)
@@ -0,0 +1,122 @@
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 protocol
16
+
17
+
18
+ class Default(protocol.RSEProtocol):
19
+ """ Implementing access to RSEs using the local filesystem."""
20
+
21
+ def __init__(self, protocol_attr, rse_settings, logger=None):
22
+ """ Initializes the object with information about the referred RSE.
23
+
24
+ :param props: Properties derived from the RSE Repository
25
+ """
26
+ super(Default, self).__init__(protocol_attr, rse_settings, logger=logger)
27
+ self.attributes.pop('determinism_type', None)
28
+ self.files = []
29
+
30
+ def _get_path(self, scope, name):
31
+ """ Transforms the physical file name into the local URI in the referred RSE.
32
+ Suitable for sites implementoing the RUCIO naming convention.
33
+
34
+ :param name: filename
35
+ :param scope: scope
36
+
37
+ :returns: RSE specific URI of the physical file
38
+ """
39
+ return '%s/%s' % (scope, name)
40
+
41
+ def path2pfn(self, path):
42
+ """
43
+ Returns a fully qualified PFN for the file referred by path.
44
+
45
+ :param path: The path to the file.
46
+
47
+ :returns: Fully qualified PFN.
48
+
49
+ """
50
+ return ''.join([self.rse['scheme'], '://%s' % self.rse['hostname'], path])
51
+
52
+ def exists(self, pfn):
53
+ """ Checks if the requested file is known by the referred RSE.
54
+
55
+ :param pfn: Physical file name
56
+
57
+ :returns: True if the file exists, False if it doesn't
58
+
59
+ :raise ServiceUnavailable
60
+ """
61
+ raise NotImplementedError
62
+
63
+ def connect(self):
64
+ """ Establishes the actual connection to the referred RSE.
65
+
66
+ :param credentials: Provide all necessary information to establish a connection
67
+ to the referred storage system. Some is loaded from the repository inside the
68
+ RSE class and some must be provided specific for the SFTP protocol like
69
+ username, password, private_key, private_key_pass, port.
70
+ For details about possible additional parameters and details about their usage
71
+ see the pysftp.Connection() documentation.
72
+ NOTE: the host parametrer is overwritten with the value provided by the repository
73
+
74
+ :raise RSEAccessDenied
75
+ """
76
+ raise NotImplementedError
77
+
78
+ def close(self):
79
+ """ Closes the connection to RSE."""
80
+ raise NotImplementedError
81
+
82
+ def get(self, pfn, dest, transfer_timeout=None):
83
+ """ Provides access to files stored inside connected the RSE.
84
+
85
+ :param pfn: Physical file name of requested file
86
+ :param dest: Name and path of the files when stored at the client
87
+ :param transfer_timeout Transfer timeout (in seconds)
88
+
89
+ :raises DestinationNotAccessible, ServiceUnavailable, SourceNotFound
90
+ """
91
+ raise NotImplementedError
92
+
93
+ def put(self, source, target, source_dir=None, transfer_timeout=None):
94
+ """ Allows to store files inside the referred RSE.
95
+
96
+ :param source: Physical file name
97
+ :param target: Name of the file on the storage system e.g. with prefixed scope
98
+ :param source_dir Path where the to be transferred files are stored in the local file system
99
+ :param transfer_timeout Transfer timeout (in seconds)
100
+
101
+ :raises DestinationNotAccessible, ServiceUnavailable, SourceNotFound
102
+ """
103
+ raise NotImplementedError
104
+
105
+ def delete(self, pfn):
106
+ """ Deletes a file from the connected RSE.
107
+
108
+ :param pfn: Physical file name
109
+
110
+ :raises ServiceUnavailable, SourceNotFound
111
+ """
112
+ raise NotImplementedError
113
+
114
+ def rename(self, pfn, new_pfn):
115
+ """ Allows to rename a file stored inside the connected RSE.
116
+
117
+ :param pfn: Current physical file name
118
+ :param new_pfn New physical file name
119
+
120
+ :raises DestinationNotAccessible, ServiceUnavailable, SourceNotFound
121
+ """
122
+ raise NotImplementedError
@@ -0,0 +1,111 @@
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 protocol
16
+
17
+
18
+ class Default(protocol.RSEProtocol):
19
+ """ Implementing access to RSEs using the local filesystem."""
20
+
21
+ def __init__(self, protocol_attr, rse_settings, logger=None):
22
+ """ Initializes the object with information about the referred RSE.
23
+
24
+ :param props: Properties derived from the RSE Repository
25
+ """
26
+ super(Default, self).__init__(protocol_attr, rse_settings, logger=logger)
27
+ self.attributes.pop('determinism_type', None)
28
+ self.files = []
29
+
30
+ def path2pfn(self, path):
31
+ """
32
+ Returns a fully qualified PFN for the file referred by path.
33
+
34
+ :param path: The path to the file.
35
+
36
+ :returns: Fully qualified PFN.
37
+
38
+ """
39
+ return ''.join([self.rse['scheme'], '://%s' % self.rse['hostname'], path])
40
+
41
+ def exists(self, pfn):
42
+ """ Checks if the requested file is known by the referred RSE.
43
+
44
+ :param pfn: Physical file name
45
+
46
+ :returns: True if the file exists, False if it doesn't
47
+
48
+ :raise ServiceUnavailable
49
+ """
50
+ raise NotImplementedError
51
+
52
+ def connect(self):
53
+ """ Establishes the actual connection to the referred RSE.
54
+
55
+ :param credentials: Provide all necessary information to establish a connection
56
+ to the referred storage system. Some is loaded from the repository inside the
57
+ RSE class and some must be provided specific for the SFTP protocol like
58
+ username, password, private_key, private_key_pass, port.
59
+ For details about possible additional parameters and details about their usage
60
+ see the pysftp.Connection() documentation.
61
+ NOTE: the host parametrer is overwritten with the value provided by the repository
62
+
63
+ :raise RSEAccessDenied
64
+ """
65
+ raise NotImplementedError
66
+
67
+ def close(self):
68
+ """ Closes the connection to RSE."""
69
+ raise NotImplementedError
70
+
71
+ def get(self, pfn, dest, transfer_timeout=None):
72
+ """ Provides access to files stored inside connected the RSE.
73
+
74
+ :param pfn: Physical file name of requested file
75
+ :param dest: Name and path of the files when stored at the client
76
+ :param transfer_timeout Transfer timeout (in seconds)
77
+
78
+ :raises DestinationNotAccessible, ServiceUnavailable, SourceNotFound
79
+ """
80
+ raise NotImplementedError
81
+
82
+ def put(self, source, target, source_dir=None, transfer_timeout=None):
83
+ """ Allows to store files inside the referred RSE.
84
+
85
+ :param source: Physical file name
86
+ :param target: Name of the file on the storage system e.g. with prefixed scope
87
+ :param source_dir Path where the to be transferred files are stored in the local file system
88
+ :param transfer_timeout Transfer timeout (in seconds)
89
+
90
+ :raises DestinationNotAccessible, ServiceUnavailable, SourceNotFound
91
+ """
92
+ raise NotImplementedError
93
+
94
+ def delete(self, pfn):
95
+ """ Deletes a file from the connected RSE.
96
+
97
+ :param pfn: Physical file name
98
+
99
+ :raises ServiceUnavailable, SourceNotFound
100
+ """
101
+ raise NotImplementedError
102
+
103
+ def rename(self, pfn, new_pfn):
104
+ """ Allows to rename a file stored inside the connected RSE.
105
+
106
+ :param pfn: Current physical file name
107
+ :param new_pfn New physical file name
108
+
109
+ :raises DestinationNotAccessible, ServiceUnavailable, SourceNotFound
110
+ """
111
+ raise NotImplementedError