1 # Copyright 2011 GRNET S.A. All rights reserved.
3 # Redistribution and use in source and binary forms, with or
4 # without modification, are permitted provided that the following
7 # 1. Redistributions of source code must retain the above
8 # copyright notice, this list of conditions and the following
11 # 2. Redistributions in binary form must reproduce the above
12 # copyright notice, this list of conditions and the following
13 # disclaimer in the documentation and/or other materials
14 # provided with the distribution.
16 # THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 # POSSIBILITY OF SUCH DAMAGE.
29 # The views and conclusions contained in the software and
30 # documentation are those of the authors and should not be
31 # interpreted as representing official policies, either expressed
32 # or implied, of GRNET S.A.
34 class NotAllowedError(Exception):
37 class BaseBackend(object):
38 """Abstract backend class that serves as a reference for actual implementations.
40 The purpose of the backend is to provide the necessary functions for handling data
41 and metadata. It is responsible for the actual storage and retrieval of information.
43 Note that the account level is always valid as it is checked from another subsystem.
45 When not replacing metadata, keys with empty values should be deleted.
47 The following variables should be available:
48 'hash_algorithm': Suggested is 'sha256'
49 'block_size': Suggested is 4MB
52 def delete_account(self, user, account):
53 """Delete the account with the given name.
56 NotAllowedError: Operation not permitted
57 IndexError: Account is not empty
61 def get_account_meta(self, user, account, until=None):
62 """Return a dictionary with the account metadata.
64 The keys returned are all user-defined, except:
65 'name': The account name
66 'count': The number of containers (or 0)
67 'bytes': The total data size (or 0)
68 'modified': Last modification timestamp (overall)
69 'until_timestamp': Last modification until the timestamp provided
72 NotAllowedError: Operation not permitted
76 def update_account_meta(self, user, account, meta, replace=False):
77 """Update the metadata associated with the account.
80 'meta': Dictionary with metadata to update
81 'replace': Replace instead of update
84 NotAllowedError: Operation not permitted
88 def list_containers(self, user, account, marker=None, limit=10000, until=None):
89 """Return a list of container (name, version_id) tuples existing under an account.
92 'marker': Start list from the next item after 'marker'
93 'limit': Number of containers to return
96 NotAllowedError: Operation not permitted
100 def put_container(self, user, account, container):
101 """Create a new container with the given name.
104 NotAllowedError: Operation not permitted
105 NameError: Container already exists
109 def delete_container(self, user, account, container):
110 """Delete the container with the given name.
113 NotAllowedError: Operation not permitted
114 NameError: Container does not exist
115 IndexError: Container is not empty
119 def get_container_meta(self, user, account, container, until=None):
120 """Return a dictionary with the container metadata.
122 The keys returned are all user-defined, except:
123 'name': The container name
124 'count': The number of objects
125 'bytes': The total data size
126 'modified': Last modification timestamp (overall)
127 'until_timestamp': Last modification until the timestamp provided
130 NotAllowedError: Operation not permitted
131 NameError: Container does not exist
135 def update_container_meta(self, user, account, container, meta, replace=False):
136 """Update the metadata associated with the container.
139 'meta': Dictionary with metadata to update
140 'replace': Replace instead of update
143 NotAllowedError: Operation not permitted
144 NameError: Container does not exist
148 def list_objects(self, user, account, container, prefix='', delimiter=None, marker=None, limit=10000, virtual=True, keys=[], until=None):
149 """Return a list of object (name, version_id) tuples existing under a container.
152 'prefix': List objects starting with 'prefix'
153 'delimiter': Return unique names before 'delimiter' and after 'prefix'
154 'marker': Start list from the next item after 'marker'
155 'limit': Number of objects to return
156 'virtual': If not set, the result will only include names starting\
157 with 'prefix' and ending without a 'delimiter' or with\
158 the first occurance of the 'delimiter' after 'prefix'.\
159 If set, the result will include all names after 'prefix',\
160 up to and including the 'delimiter' if it is found
161 'keys': Include objects that have meta with the keys in the list
164 NotAllowedError: Operation not permitted
165 NameError: Container does not exist
169 def list_object_meta(self, user, account, container, until=None):
170 """Return a list with all the container's object meta keys.
173 NotAllowedError: Operation not permitted
174 NameError: Container does not exist
178 def get_object_meta(self, user, account, container, name, version=None):
179 """Return a dictionary with the object metadata.
181 The keys returned are all user-defined, except:
182 'name': The object name
183 'bytes': The total data size
184 'modified': Last modification timestamp (overall)
185 'version': The version identifier
186 'version_timestamp': The version's modification timestamp
189 NotAllowedError: Operation not permitted
190 NameError: Container/object does not exist
191 IndexError: Version does not exist
195 def update_object_meta(self, user, account, container, name, meta, replace=False):
196 """Update the metadata associated with the object.
199 'meta': Dictionary with metadata to update
200 'replace': Replace instead of update
203 NotAllowedError: Operation not permitted
204 NameError: Container/object does not exist
208 def get_object_permissions(self, user, account, container, name):
209 """Return the path from which this object gets its permissions from,\
210 along with a dictionary containing the permissions.
213 'read': The object is readable by the users/groups in the list
214 'write': The object is writable by the users/groups in the list
217 NotAllowedError: Operation not permitted
218 NameError: Container/object does not exist
222 def update_object_permissions(self, user, account, container, name, permissions):
223 """Update the permissions associated with the object.
226 'permissions': Dictionary with permissions to update
229 NotAllowedError: Operation not permitted
230 NameError: Container/object does not exist
231 ValueError: Invalid users/groups in permissions
232 AttributeError: Can not set permissions, as this object\
233 is already shared/private by another object higher\
234 in the hierarchy, or setting permissions here will\
235 invalidate other permissions deeper in the hierarchy
239 def get_object_hashmap(self, user, account, container, name, version=None):
240 """Return the object's size and a list with partial hashes.
243 NotAllowedError: Operation not permitted
244 NameError: Container/object does not exist
245 IndexError: Version does not exist
249 def update_object_hashmap(self, user, account, container, name, size, hashmap, meta={}, replace_meta=False, permissions=None):
250 """Create/update an object with the specified size and partial hashes.
253 'dest_meta': Dictionary with metadata to change
254 'replace_meta': Replace metadata instead of update
255 'permissions': Updated object permissions
258 NotAllowedError: Operation not permitted
259 NameError: Container does not exist
260 ValueError: Invalid users/groups in permissions
261 AttributeError: Can not set permissions
265 def copy_object(self, user, account, src_container, src_name, dest_container, dest_name, dest_meta={}, replace_meta=False, permissions=None, src_version=None):
266 """Copy an object's data and metadata.
269 'dest_meta': Dictionary with metadata to change from source to destination
270 'replace_meta': Replace metadata instead of update
271 'permissions': New object permissions
272 'src_version': Copy from the version provided
275 NotAllowedError: Operation not permitted
276 NameError: Container/object does not exist
277 IndexError: Version does not exist
278 ValueError: Invalid users/groups in permissions
279 AttributeError: Can not set permissions
283 def move_object(self, user, account, src_container, src_name, dest_container, dest_name, dest_meta={}, replace_meta=False, permissions=None):
284 """Move an object's data and metadata.
287 'dest_meta': Dictionary with metadata to change from source to destination
288 'replace_meta': Replace metadata instead of update
289 'permissions': New object permissions
292 NotAllowedError: Operation not permitted
293 NameError: Container/object does not exist
294 ValueError: Invalid users/groups in permissions
295 AttributeError: Can not set permissions
299 def delete_object(self, user, account, container, name):
303 NotAllowedError: Operation not permitted
304 NameError: Container/object does not exist
308 def list_versions(self, user, account, container, name):
309 """Return a list of all (version, version_timestamp) tuples for an object.
312 NotAllowedError: Operation not permitted
316 def get_block(self, hash):
317 """Return a block's data.
320 NameError: Block does not exist
324 def put_block(self, data):
325 """Store a block and return the hash."""
328 def update_block(self, hash, data, offset=0):
329 """Update a known block and return the hash.
332 IndexError: Offset or data outside block limits