Revision d50ed8d4 snf-pithos-backend/pithos/backends/base.py
b/snf-pithos-backend/pithos/backends/base.py | ||
---|---|---|
1 | 1 |
# Copyright 2011-2012 GRNET S.A. All rights reserved. |
2 |
#
|
|
2 |
# |
|
3 | 3 |
# Redistribution and use in source and binary forms, with or |
4 | 4 |
# without modification, are permitted provided that the following |
5 | 5 |
# conditions are met: |
6 |
#
|
|
6 |
# |
|
7 | 7 |
# 1. Redistributions of source code must retain the above |
8 | 8 |
# copyright notice, this list of conditions and the following |
9 | 9 |
# disclaimer. |
10 |
#
|
|
10 |
# |
|
11 | 11 |
# 2. Redistributions in binary form must reproduce the above |
12 | 12 |
# copyright notice, this list of conditions and the following |
13 | 13 |
# disclaimer in the documentation and/or other materials |
14 | 14 |
# provided with the distribution. |
15 |
#
|
|
15 |
# |
|
16 | 16 |
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS |
17 | 17 |
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | 18 |
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
... | ... | |
25 | 25 |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
26 | 26 |
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
27 | 27 |
# POSSIBILITY OF SUCH DAMAGE. |
28 |
#
|
|
28 |
# |
|
29 | 29 |
# The views and conclusions contained in the software and |
30 | 30 |
# documentation are those of the authors and should not be |
31 | 31 |
# interpreted as representing official policies, either expressed |
32 | 32 |
# or implied, of GRNET S.A. |
33 | 33 |
|
34 | 34 |
# Default setting for new accounts. |
35 |
DEFAULT_QUOTA = 0 # No quota. |
|
35 |
DEFAULT_QUOTA = 0 # No quota.
|
|
36 | 36 |
DEFAULT_VERSIONING = 'auto' |
37 | 37 |
|
38 | 38 |
|
39 |
|
|
39 | 40 |
class NotAllowedError(Exception): |
40 | 41 |
pass |
41 | 42 |
|
43 |
|
|
42 | 44 |
class QuotaError(Exception): |
43 | 45 |
pass |
44 | 46 |
|
47 |
|
|
45 | 48 |
class AccountExists(NameError): |
46 | 49 |
pass |
47 |
|
|
50 |
|
|
51 |
|
|
48 | 52 |
class ContainerExists(NameError): |
49 | 53 |
pass |
50 | 54 |
|
55 |
|
|
51 | 56 |
class AccountNotEmpty(IndexError): |
52 | 57 |
pass |
53 | 58 |
|
59 |
|
|
54 | 60 |
class ContainerNotEmpty(IndexError): |
55 | 61 |
pass |
56 | 62 |
|
63 |
|
|
57 | 64 |
class ItemNotExists(NameError): |
58 | 65 |
pass |
59 | 66 |
|
67 |
|
|
60 | 68 |
class VersionNotExists(IndexError): |
61 | 69 |
pass |
62 | 70 |
|
71 |
|
|
63 | 72 |
class BaseBackend(object): |
64 | 73 |
"""Abstract backend class that serves as a reference for actual implementations. |
65 |
|
|
74 |
|
|
66 | 75 |
The purpose of the backend is to provide the necessary functions for handling data |
67 | 76 |
and metadata. It is responsible for the actual storage and retrieval of information. |
68 |
|
|
77 |
|
|
69 | 78 |
Note that the account level is always valid as it is checked from another subsystem. |
70 |
|
|
79 |
|
|
71 | 80 |
When not replacing metadata/groups/policy, keys with empty values should be deleted. |
72 |
|
|
81 |
|
|
73 | 82 |
The following variables should be available: |
74 | 83 |
'hash_algorithm': Suggested is 'sha256' |
75 |
|
|
84 |
|
|
76 | 85 |
'block_size': Suggested is 4MB |
77 |
|
|
86 |
|
|
78 | 87 |
'default_policy': A dictionary with default policy settings |
79 | 88 |
""" |
80 |
|
|
89 |
|
|
81 | 90 |
def close(self): |
82 | 91 |
"""Close the backend connection.""" |
83 | 92 |
pass |
84 |
|
|
93 |
|
|
85 | 94 |
def list_accounts(self, user, marker=None, limit=10000): |
86 | 95 |
"""Return a list of accounts the user can access. |
87 |
|
|
96 |
|
|
88 | 97 |
Parameters: |
89 | 98 |
'marker': Start list from the next item after 'marker' |
90 |
|
|
99 |
|
|
91 | 100 |
'limit': Number of containers to return |
92 | 101 |
""" |
93 | 102 |
return [] |
94 |
|
|
103 |
|
|
95 | 104 |
def get_account_meta(self, user, account, domain, until=None, include_user_defined=True): |
96 | 105 |
"""Return a dictionary with the account metadata for the domain. |
97 |
|
|
106 |
|
|
98 | 107 |
The keys returned are all user-defined, except: |
99 | 108 |
'name': The account name |
100 |
|
|
109 |
|
|
101 | 110 |
'count': The number of containers (or 0) |
102 |
|
|
111 |
|
|
103 | 112 |
'bytes': The total data size (or 0) |
104 |
|
|
113 |
|
|
105 | 114 |
'modified': Last modification timestamp (overall) |
106 |
|
|
115 |
|
|
107 | 116 |
'until_timestamp': Last modification until the timestamp provided |
108 |
|
|
117 |
|
|
109 | 118 |
Raises: |
110 | 119 |
NotAllowedError: Operation not permitted |
111 | 120 |
""" |
112 | 121 |
return {} |
113 |
|
|
122 |
|
|
114 | 123 |
def update_account_meta(self, user, account, domain, meta, replace=False): |
115 | 124 |
"""Update the metadata associated with the account for the domain. |
116 |
|
|
125 |
|
|
117 | 126 |
Parameters: |
118 | 127 |
'domain': Metadata domain |
119 |
|
|
128 |
|
|
120 | 129 |
'meta': Dictionary with metadata to update |
121 |
|
|
130 |
|
|
122 | 131 |
'replace': Replace instead of update |
123 |
|
|
132 |
|
|
124 | 133 |
Raises: |
125 | 134 |
NotAllowedError: Operation not permitted |
126 | 135 |
""" |
127 | 136 |
return |
128 |
|
|
137 |
|
|
129 | 138 |
def get_account_groups(self, user, account): |
130 | 139 |
"""Return a dictionary with the user groups defined for this account. |
131 |
|
|
140 |
|
|
132 | 141 |
Raises: |
133 | 142 |
NotAllowedError: Operation not permitted |
134 | 143 |
""" |
135 | 144 |
return {} |
136 |
|
|
145 |
|
|
137 | 146 |
def update_account_groups(self, user, account, groups, replace=False): |
138 | 147 |
"""Update the groups associated with the account. |
139 |
|
|
148 |
|
|
140 | 149 |
Raises: |
141 | 150 |
NotAllowedError: Operation not permitted |
142 |
|
|
151 |
|
|
143 | 152 |
ValueError: Invalid data in groups |
144 | 153 |
""" |
145 | 154 |
return |
146 |
|
|
155 |
|
|
147 | 156 |
def get_account_policy(self, user, account): |
148 | 157 |
"""Return a dictionary with the account policy. |
149 |
|
|
158 |
|
|
150 | 159 |
The keys returned are: |
151 | 160 |
'quota': The maximum bytes allowed (default is 0 - unlimited) |
152 |
|
|
161 |
|
|
153 | 162 |
'versioning': Can be 'auto', 'manual' or 'none' (default is 'manual') |
154 |
|
|
163 |
|
|
155 | 164 |
Raises: |
156 | 165 |
NotAllowedError: Operation not permitted |
157 | 166 |
""" |
158 | 167 |
return {} |
159 |
|
|
168 |
|
|
160 | 169 |
def update_account_policy(self, user, account, policy, replace=False): |
161 | 170 |
"""Update the policy associated with the account. |
162 |
|
|
171 |
|
|
163 | 172 |
Raises: |
164 | 173 |
NotAllowedError: Operation not permitted |
165 |
|
|
174 |
|
|
166 | 175 |
ValueError: Invalid policy defined |
167 | 176 |
""" |
168 | 177 |
return |
169 |
|
|
178 |
|
|
170 | 179 |
def put_account(self, user, account, policy={}): |
171 | 180 |
"""Create a new account with the given name. |
172 |
|
|
181 |
|
|
173 | 182 |
Raises: |
174 | 183 |
NotAllowedError: Operation not permitted |
175 |
|
|
184 |
|
|
176 | 185 |
ValueError: Invalid policy defined |
177 | 186 |
""" |
178 | 187 |
return |
179 |
|
|
188 |
|
|
180 | 189 |
def delete_account(self, user, account): |
181 | 190 |
"""Delete the account with the given name. |
182 |
|
|
191 |
|
|
183 | 192 |
Raises: |
184 | 193 |
NotAllowedError: Operation not permitted |
185 |
|
|
194 |
|
|
186 | 195 |
AccountNotEmpty: Account is not empty |
187 | 196 |
""" |
188 | 197 |
return |
189 |
|
|
198 |
|
|
190 | 199 |
def list_containers(self, user, account, marker=None, limit=10000, shared=False, until=None, public=False): |
191 | 200 |
"""Return a list of container names existing under an account. |
192 |
|
|
201 |
|
|
193 | 202 |
Parameters: |
194 | 203 |
'marker': Start list from the next item after 'marker' |
195 |
|
|
204 |
|
|
196 | 205 |
'limit': Number of containers to return |
197 |
|
|
206 |
|
|
198 | 207 |
'shared': Only list containers with permissions set |
199 |
|
|
208 |
|
|
200 | 209 |
'public': Only list containers containing public objects |
201 |
|
|
202 |
|
|
210 |
|
|
211 |
|
|
203 | 212 |
Raises: |
204 | 213 |
NotAllowedError: Operation not permitted |
205 | 214 |
""" |
206 | 215 |
return [] |
207 |
|
|
216 |
|
|
208 | 217 |
def list_container_meta(self, user, account, container, domain, until=None): |
209 | 218 |
"""Return a list with all the container's object meta keys for the domain. |
210 |
|
|
219 |
|
|
211 | 220 |
Raises: |
212 | 221 |
NotAllowedError: Operation not permitted |
213 |
|
|
222 |
|
|
214 | 223 |
ItemNotExists: Container does not exist |
215 | 224 |
""" |
216 | 225 |
return [] |
217 |
|
|
226 |
|
|
218 | 227 |
def get_container_meta(self, user, account, container, domain, until=None, include_user_defined=True): |
219 | 228 |
"""Return a dictionary with the container metadata for the domain. |
220 |
|
|
229 |
|
|
221 | 230 |
The keys returned are all user-defined, except: |
222 | 231 |
'name': The container name |
223 |
|
|
232 |
|
|
224 | 233 |
'count': The number of objects |
225 |
|
|
234 |
|
|
226 | 235 |
'bytes': The total data size |
227 |
|
|
236 |
|
|
228 | 237 |
'modified': Last modification timestamp (overall) |
229 |
|
|
238 |
|
|
230 | 239 |
'until_timestamp': Last modification until the timestamp provided |
231 |
|
|
240 |
|
|
232 | 241 |
Raises: |
233 | 242 |
NotAllowedError: Operation not permitted |
234 |
|
|
243 |
|
|
235 | 244 |
ItemNotExists: Container does not exist |
236 | 245 |
""" |
237 | 246 |
return {} |
238 |
|
|
247 |
|
|
239 | 248 |
def update_container_meta(self, user, account, container, domain, meta, replace=False): |
240 | 249 |
"""Update the metadata associated with the container for the domain. |
241 |
|
|
250 |
|
|
242 | 251 |
Parameters: |
243 | 252 |
'domain': Metadata domain |
244 |
|
|
253 |
|
|
245 | 254 |
'meta': Dictionary with metadata to update |
246 |
|
|
255 |
|
|
247 | 256 |
'replace': Replace instead of update |
248 |
|
|
257 |
|
|
249 | 258 |
Raises: |
250 | 259 |
NotAllowedError: Operation not permitted |
251 |
|
|
260 |
|
|
252 | 261 |
ItemNotExists: Container does not exist |
253 | 262 |
""" |
254 | 263 |
return |
255 |
|
|
264 |
|
|
256 | 265 |
def get_container_policy(self, user, account, container): |
257 | 266 |
"""Return a dictionary with the container policy. |
258 |
|
|
267 |
|
|
259 | 268 |
The keys returned are: |
260 | 269 |
'quota': The maximum bytes allowed (default is 0 - unlimited) |
261 |
|
|
270 |
|
|
262 | 271 |
'versioning': Can be 'auto', 'manual' or 'none' (default is 'manual') |
263 |
|
|
272 |
|
|
264 | 273 |
Raises: |
265 | 274 |
NotAllowedError: Operation not permitted |
266 |
|
|
275 |
|
|
267 | 276 |
ItemNotExists: Container does not exist |
268 | 277 |
""" |
269 | 278 |
return {} |
270 |
|
|
279 |
|
|
271 | 280 |
def update_container_policy(self, user, account, container, policy, replace=False): |
272 | 281 |
"""Update the policy associated with the container. |
273 |
|
|
282 |
|
|
274 | 283 |
Raises: |
275 | 284 |
NotAllowedError: Operation not permitted |
276 |
|
|
285 |
|
|
277 | 286 |
ItemNotExists: Container does not exist |
278 |
|
|
287 |
|
|
279 | 288 |
ValueError: Invalid policy defined |
280 | 289 |
""" |
281 | 290 |
return |
282 |
|
|
291 |
|
|
283 | 292 |
def put_container(self, user, account, container, policy={}, delimiter=None): |
284 | 293 |
"""Create a new container with the given name. |
285 |
|
|
294 |
|
|
286 | 295 |
Parameters: |
287 | 296 |
'delimiter': If present deletes container contents instead of the container |
288 |
|
|
297 |
|
|
289 | 298 |
Raises: |
290 | 299 |
NotAllowedError: Operation not permitted |
291 |
|
|
300 |
|
|
292 | 301 |
ContainerExists: Container already exists |
293 |
|
|
302 |
|
|
294 | 303 |
ValueError: Invalid policy defined |
295 | 304 |
""" |
296 | 305 |
return |
297 |
|
|
306 |
|
|
298 | 307 |
def delete_container(self, user, account, container, until=None): |
299 | 308 |
"""Delete/purge the container with the given name. |
300 |
|
|
309 |
|
|
301 | 310 |
Raises: |
302 | 311 |
NotAllowedError: Operation not permitted |
303 |
|
|
312 |
|
|
304 | 313 |
ItemNotExists: Container does not exist |
305 |
|
|
314 |
|
|
306 | 315 |
ContainerNotEmpty: Container is not empty |
307 | 316 |
""" |
308 | 317 |
return |
309 |
|
|
318 |
|
|
310 | 319 |
def list_objects(self, user, account, container, prefix='', delimiter=None, marker=None, limit=10000, virtual=True, domain=None, keys=[], shared=False, until=None, size_range=None, public=False): |
311 | 320 |
"""Return a list of object (name, version_id) tuples existing under a container. |
312 |
|
|
321 |
|
|
313 | 322 |
Parameters: |
314 | 323 |
'prefix': List objects starting with 'prefix' |
315 |
|
|
324 |
|
|
316 | 325 |
'delimiter': Return unique names before 'delimiter' and after 'prefix' |
317 |
|
|
326 |
|
|
318 | 327 |
'marker': Start list from the next item after 'marker' |
319 |
|
|
328 |
|
|
320 | 329 |
'limit': Number of objects to return |
321 |
|
|
330 |
|
|
322 | 331 |
'virtual': If not set, the result will only include names starting |
323 | 332 |
with 'prefix' and ending without a 'delimiter' or with |
324 | 333 |
the first occurance of the 'delimiter' after 'prefix'. |
325 | 334 |
If set, the result will include all names after 'prefix', |
326 | 335 |
up to and including the 'delimiter' if it is found |
327 |
|
|
336 |
|
|
328 | 337 |
'domain': Metadata domain for keys |
329 |
|
|
338 |
|
|
330 | 339 |
'keys': Include objects that satisfy the key queries in the list. |
331 | 340 |
Use 'key', '!key' for existence queries, 'key op value' for |
332 | 341 |
value queries, where 'op' can be one of =, !=, <=, >=, <, > |
333 |
|
|
342 |
|
|
334 | 343 |
'shared': Only list objects with permissions set |
335 |
|
|
344 |
|
|
336 | 345 |
'size_range': Include objects with byte size in (from, to). |
337 | 346 |
Use None to specify unlimited |
338 |
|
|
347 |
|
|
339 | 348 |
'public': Only list public objects |
340 |
|
|
341 |
|
|
349 |
|
|
350 |
|
|
342 | 351 |
Raises: |
343 | 352 |
NotAllowedError: Operation not permitted |
344 |
|
|
353 |
|
|
345 | 354 |
ItemNotExists: Container does not exist |
346 | 355 |
""" |
347 | 356 |
return [] |
348 |
|
|
357 |
|
|
349 | 358 |
def list_object_meta(self, user, account, container, prefix='', delimiter=None, marker=None, limit=10000, virtual=True, domain=None, keys=[], shared=False, until=None, size_range=None): |
350 | 359 |
"""Return a list of object metadata dicts existing under a container. |
351 |
|
|
360 |
|
|
352 | 361 |
Same parameters with list_objects. Returned dicts have no user-defined |
353 | 362 |
metadata and, if until is not None, a None 'modified' timestamp. |
354 |
|
|
363 |
|
|
355 | 364 |
Raises: |
356 | 365 |
NotAllowedError: Operation not permitted |
357 |
|
|
366 |
|
|
358 | 367 |
ItemNotExists: Container does not exist |
359 | 368 |
""" |
360 | 369 |
return [] |
361 |
|
|
370 |
|
|
362 | 371 |
def list_object_permissions(self, user, account, container, prefix=''): |
363 | 372 |
"""Return a list of paths that enforce permissions under a container. |
364 |
|
|
373 |
|
|
365 | 374 |
Raises: |
366 | 375 |
NotAllowedError: Operation not permitted |
367 | 376 |
""" |
368 | 377 |
return [] |
369 |
|
|
378 |
|
|
370 | 379 |
def list_object_public(self, user, account, container, prefix=''): |
371 | 380 |
"""Return a dict mapping paths to public ids for objects that are public under a container.""" |
372 | 381 |
return {} |
373 |
|
|
382 |
|
|
374 | 383 |
def get_object_meta(self, user, account, container, name, domain, version=None, include_user_defined=True): |
375 | 384 |
"""Return a dictionary with the object metadata for the domain. |
376 |
|
|
385 |
|
|
377 | 386 |
The keys returned are all user-defined, except: |
378 | 387 |
'name': The object name |
379 |
|
|
388 |
|
|
380 | 389 |
'bytes': The total data size |
381 |
|
|
390 |
|
|
382 | 391 |
'type': The content type |
383 |
|
|
392 |
|
|
384 | 393 |
'hash': The hashmap hash |
385 |
|
|
394 |
|
|
386 | 395 |
'modified': Last modification timestamp (overall) |
387 |
|
|
396 |
|
|
388 | 397 |
'modified_by': The user that committed the object (version requested) |
389 |
|
|
398 |
|
|
390 | 399 |
'version': The version identifier |
391 |
|
|
400 |
|
|
392 | 401 |
'version_timestamp': The version's modification timestamp |
393 |
|
|
402 |
|
|
394 | 403 |
'uuid': A unique identifier that persists data or metadata updates and renames |
395 |
|
|
404 |
|
|
396 | 405 |
'checksum': The MD5 sum of the object (may be empty) |
397 |
|
|
406 |
|
|
398 | 407 |
Raises: |
399 | 408 |
NotAllowedError: Operation not permitted |
400 |
|
|
409 |
|
|
401 | 410 |
ItemNotExists: Container/object does not exist |
402 |
|
|
411 |
|
|
403 | 412 |
VersionNotExists: Version does not exist |
404 | 413 |
""" |
405 | 414 |
return {} |
406 |
|
|
415 |
|
|
407 | 416 |
def update_object_meta(self, user, account, container, name, domain, meta, replace=False): |
408 | 417 |
"""Update the metadata associated with the object for the domain and return the new version. |
409 |
|
|
418 |
|
|
410 | 419 |
Parameters: |
411 | 420 |
'domain': Metadata domain |
412 |
|
|
421 |
|
|
413 | 422 |
'meta': Dictionary with metadata to update |
414 |
|
|
423 |
|
|
415 | 424 |
'replace': Replace instead of update |
416 |
|
|
425 |
|
|
417 | 426 |
Raises: |
418 | 427 |
NotAllowedError: Operation not permitted |
419 |
|
|
428 |
|
|
420 | 429 |
ItemNotExists: Container/object does not exist |
421 | 430 |
""" |
422 | 431 |
return '' |
423 |
|
|
432 |
|
|
424 | 433 |
def get_object_permissions(self, user, account, container, name): |
425 | 434 |
"""Return the action allowed on the object, the path |
426 | 435 |
from which the object gets its permissions from, |
427 | 436 |
along with a dictionary containing the permissions. |
428 |
|
|
437 |
|
|
429 | 438 |
The dictionary keys are (also used for defining the action): |
430 | 439 |
'read': The object is readable by the users/groups in the list |
431 |
|
|
440 |
|
|
432 | 441 |
'write': The object is writable by the users/groups in the list |
433 |
|
|
442 |
|
|
434 | 443 |
Raises: |
435 | 444 |
NotAllowedError: Operation not permitted |
436 |
|
|
445 |
|
|
437 | 446 |
ItemNotExists: Container/object does not exist |
438 | 447 |
""" |
439 | 448 |
return {} |
440 |
|
|
449 |
|
|
441 | 450 |
def update_object_permissions(self, user, account, container, name, permissions): |
442 | 451 |
"""Update (set) the permissions associated with the object. |
443 |
|
|
452 |
|
|
444 | 453 |
Parameters: |
445 | 454 |
'permissions': Dictionary with permissions to set |
446 |
|
|
455 |
|
|
447 | 456 |
Raises: |
448 | 457 |
NotAllowedError: Operation not permitted |
449 |
|
|
458 |
|
|
450 | 459 |
ItemNotExists: Container/object does not exist |
451 |
|
|
460 |
|
|
452 | 461 |
ValueError: Invalid users/groups in permissions |
453 | 462 |
""" |
454 | 463 |
return |
455 |
|
|
464 |
|
|
456 | 465 |
def get_object_public(self, user, account, container, name): |
457 | 466 |
"""Return the public id of the object if applicable. |
458 |
|
|
467 |
|
|
459 | 468 |
Raises: |
460 | 469 |
NotAllowedError: Operation not permitted |
461 |
|
|
470 |
|
|
462 | 471 |
ItemNotExists: Container/object does not exist |
463 | 472 |
""" |
464 | 473 |
return None |
465 |
|
|
474 |
|
|
466 | 475 |
def update_object_public(self, user, account, container, name, public): |
467 | 476 |
"""Update the public status of the object. |
468 |
|
|
477 |
|
|
469 | 478 |
Parameters: |
470 | 479 |
'public': Boolean value |
471 |
|
|
480 |
|
|
472 | 481 |
Raises: |
473 | 482 |
NotAllowedError: Operation not permitted |
474 |
|
|
483 |
|
|
475 | 484 |
ItemNotExists: Container/object does not exist |
476 | 485 |
""" |
477 | 486 |
return |
478 |
|
|
487 |
|
|
479 | 488 |
def get_object_hashmap(self, user, account, container, name, version=None): |
480 | 489 |
"""Return the object's size and a list with partial hashes. |
481 |
|
|
490 |
|
|
482 | 491 |
Raises: |
483 | 492 |
NotAllowedError: Operation not permitted |
484 |
|
|
493 |
|
|
485 | 494 |
ItemNotExists: Container/object does not exist |
486 |
|
|
495 |
|
|
487 | 496 |
VersionNotExists: Version does not exist |
488 | 497 |
""" |
489 | 498 |
return 0, [] |
490 |
|
|
499 |
|
|
491 | 500 |
def update_object_hashmap(self, user, account, container, name, size, type, hashmap, checksum, domain, meta={}, replace_meta=False, permissions=None): |
492 | 501 |
"""Create/update an object with the specified size and partial hashes and return the new version. |
493 |
|
|
502 |
|
|
494 | 503 |
Parameters: |
495 | 504 |
'domain': Metadata domain |
496 |
|
|
505 |
|
|
497 | 506 |
'meta': Dictionary with metadata to change |
498 |
|
|
507 |
|
|
499 | 508 |
'replace_meta': Replace metadata instead of update |
500 |
|
|
509 |
|
|
501 | 510 |
'permissions': Updated object permissions |
502 |
|
|
511 |
|
|
503 | 512 |
Raises: |
504 | 513 |
NotAllowedError: Operation not permitted |
505 |
|
|
514 |
|
|
506 | 515 |
ItemNotExists: Container does not exist |
507 |
|
|
516 |
|
|
508 | 517 |
ValueError: Invalid users/groups in permissions |
509 |
|
|
518 |
|
|
510 | 519 |
QuotaError: Account or container quota exceeded |
511 | 520 |
""" |
512 | 521 |
return '' |
513 |
|
|
522 |
|
|
514 | 523 |
def update_object_checksum(self, user, account, container, name, version, checksum): |
515 | 524 |
"""Update an object's checksum.""" |
516 | 525 |
return |
517 |
|
|
526 |
|
|
518 | 527 |
def copy_object(self, user, src_account, src_container, src_name, dest_account, dest_container, dest_name, type, domain, meta={}, replace_meta=False, permissions=None, src_version=None, delimiter=None): |
519 | 528 |
"""Copy an object's data and metadata and return the new version. |
520 |
|
|
529 |
|
|
521 | 530 |
Parameters: |
522 | 531 |
'domain': Metadata domain |
523 |
|
|
532 |
|
|
524 | 533 |
'meta': Dictionary with metadata to change from source to destination |
525 |
|
|
534 |
|
|
526 | 535 |
'replace_meta': Replace metadata instead of update |
527 |
|
|
536 |
|
|
528 | 537 |
'permissions': New object permissions |
529 |
|
|
538 |
|
|
530 | 539 |
'src_version': Copy from the version provided |
531 |
|
|
540 |
|
|
532 | 541 |
'delimiter': Copy objects whose path starts with src_name + delimiter |
533 |
|
|
542 |
|
|
534 | 543 |
Raises: |
535 | 544 |
NotAllowedError: Operation not permitted |
536 |
|
|
545 |
|
|
537 | 546 |
ItemNotExists: Container/object does not exist |
538 |
|
|
547 |
|
|
539 | 548 |
VersionNotExists: Version does not exist |
540 |
|
|
549 |
|
|
541 | 550 |
ValueError: Invalid users/groups in permissions |
542 |
|
|
551 |
|
|
543 | 552 |
QuotaError: Account or container quota exceeded |
544 | 553 |
""" |
545 | 554 |
return '' |
546 |
|
|
555 |
|
|
547 | 556 |
def move_object(self, user, src_account, src_container, src_name, dest_account, dest_container, dest_name, type, domain, meta={}, replace_meta=False, permissions=None, delimiter=None): |
548 | 557 |
"""Move an object's data and metadata and return the new version. |
549 |
|
|
558 |
|
|
550 | 559 |
Parameters: |
551 | 560 |
'domain': Metadata domain |
552 |
|
|
561 |
|
|
553 | 562 |
'meta': Dictionary with metadata to change from source to destination |
554 |
|
|
563 |
|
|
555 | 564 |
'replace_meta': Replace metadata instead of update |
556 |
|
|
565 |
|
|
557 | 566 |
'permissions': New object permissions |
558 |
|
|
567 |
|
|
559 | 568 |
'delimiter': Move objects whose path starts with src_name + delimiter |
560 |
|
|
569 |
|
|
561 | 570 |
Raises: |
562 | 571 |
NotAllowedError: Operation not permitted |
563 |
|
|
572 |
|
|
564 | 573 |
ItemNotExists: Container/object does not exist |
565 |
|
|
574 |
|
|
566 | 575 |
ValueError: Invalid users/groups in permissions |
567 |
|
|
576 |
|
|
568 | 577 |
QuotaError: Account or container quota exceeded |
569 | 578 |
""" |
570 | 579 |
return '' |
571 |
|
|
580 |
|
|
572 | 581 |
def delete_object(self, user, account, container, name, until=None, delimiter=None): |
573 | 582 |
"""Delete/purge an object. |
574 |
|
|
583 |
|
|
575 | 584 |
Parameters: |
576 | 585 |
'delimiter': Delete objects whose path starting with name + delimiter |
577 |
|
|
586 |
|
|
578 | 587 |
Raises: |
579 | 588 |
NotAllowedError: Operation not permitted |
580 |
|
|
589 |
|
|
581 | 590 |
ItemNotExists: Container/object does not exist |
582 | 591 |
""" |
583 | 592 |
return |
584 |
|
|
593 |
|
|
585 | 594 |
def list_versions(self, user, account, container, name): |
586 | 595 |
"""Return a list of all (version, version_timestamp) tuples for an object. |
587 |
|
|
596 |
|
|
588 | 597 |
Raises: |
589 | 598 |
NotAllowedError: Operation not permitted |
590 | 599 |
""" |
591 | 600 |
return [] |
592 |
|
|
601 |
|
|
593 | 602 |
def get_uuid(self, user, uuid): |
594 | 603 |
"""Return the (account, container, name) for the UUID given. |
595 |
|
|
604 |
|
|
596 | 605 |
Raises: |
597 | 606 |
NotAllowedError: Operation not permitted |
598 |
|
|
607 |
|
|
599 | 608 |
NameError: UUID does not exist |
600 | 609 |
""" |
601 | 610 |
return None |
602 |
|
|
611 |
|
|
603 | 612 |
def get_public(self, user, public): |
604 | 613 |
"""Return the (account, container, name) for the public id given. |
605 |
|
|
614 |
|
|
606 | 615 |
Raises: |
607 | 616 |
NotAllowedError: Operation not permitted |
608 |
|
|
617 |
|
|
609 | 618 |
NameError: Public id does not exist |
610 | 619 |
""" |
611 | 620 |
return None |
612 |
|
|
621 |
|
|
613 | 622 |
def get_block(self, hash): |
614 | 623 |
"""Return a block's data. |
615 |
|
|
624 |
|
|
616 | 625 |
Raises: |
617 | 626 |
ItemNotExists: Block does not exist |
618 | 627 |
""" |
619 | 628 |
return '' |
620 |
|
|
629 |
|
|
621 | 630 |
def put_block(self, data): |
622 | 631 |
"""Store a block and return the hash.""" |
623 | 632 |
return 0 |
624 |
|
|
633 |
|
|
625 | 634 |
def update_block(self, hash, data, offset=0): |
626 | 635 |
"""Update a known block and return the hash. |
627 |
|
|
636 |
|
|
628 | 637 |
Raises: |
629 | 638 |
IndexError: Offset or data outside block limits |
630 | 639 |
""" |
Also available in: Unified diff