Revision 29148653 snf-pithos-backend/pithos/backends/base.py
b/snf-pithos-backend/pithos/backends/base.py | ||
---|---|---|
37 | 37 |
DEFAULT_CONTAINER_VERSIONING = 'auto' |
38 | 38 |
|
39 | 39 |
|
40 |
|
|
41 | 40 |
class NotAllowedError(Exception): |
42 | 41 |
pass |
43 | 42 |
|
... | ... | |
71 | 70 |
|
72 | 71 |
|
73 | 72 |
class BaseBackend(object): |
74 |
"""Abstract backend class that serves as a reference for actual implementations. |
|
73 |
"""Abstract backend class. |
|
74 |
|
|
75 |
This class serves as a reference for actual implementations. |
|
75 | 76 |
|
76 |
The purpose of the backend is to provide the necessary functions for handling data
|
|
77 |
and metadata. It is responsible for the actual storage and retrieval of information.
|
|
77 |
The purpose of the backend is to provide the necessary functions |
|
78 |
for handling data and metadata.
|
|
78 | 79 |
|
79 |
Note that the account level is always valid as it is checked from another subsystem.
|
|
80 |
It is responsible for the actual storage and retrieval of information.
|
|
80 | 81 |
|
81 |
When not replacing metadata/groups/policy, keys with empty values should be deleted. |
|
82 |
Note that the account level is always valid as it is checked |
|
83 |
from another subsystem. |
|
84 |
|
|
85 |
When not replacing metadata/groups/policy, keys with empty values |
|
86 |
should be deleted. |
|
82 | 87 |
|
83 | 88 |
The following variables should be available: |
84 | 89 |
'hash_algorithm': Suggested is 'sha256' |
85 | 90 |
|
86 | 91 |
'block_size': Suggested is 4MB |
87 | 92 |
|
88 |
'default_account_policy': A dictionary with default account policy settings |
|
89 |
'default_container_policy': A dictionary with default container policy settings |
|
93 |
'default_account_policy': A dictionary with default account policy |
|
94 |
settings |
|
95 |
'default_container_policy': A dictionary with default container policy |
|
96 |
settings |
|
90 | 97 |
""" |
91 | 98 |
|
92 | 99 |
def close(self): |
... | ... | |
96 | 103 |
def list_accounts(self, user, marker=None, limit=10000): |
97 | 104 |
"""Return a list of accounts the user can access. |
98 | 105 |
|
99 |
Parameters:
|
|
106 |
Keyword arguments:
|
|
100 | 107 |
'marker': Start list from the next item after 'marker' |
101 | 108 |
|
102 | 109 |
'limit': Number of containers to return |
103 | 110 |
""" |
104 | 111 |
return [] |
105 | 112 |
|
106 |
def get_account_meta(self, user, account, domain, until=None, include_user_defined=True): |
|
113 |
def get_account_meta(self, user, account, domain, until=None, |
|
114 |
include_user_defined=True, external_quota=None): |
|
107 | 115 |
"""Return a dictionary with the account metadata for the domain. |
108 | 116 |
|
109 | 117 |
The keys returned are all user-defined, except: |
... | ... | |
117 | 125 |
|
118 | 126 |
'until_timestamp': Last modification until the timestamp provided |
119 | 127 |
|
128 |
'external_quota': The quota computed from external quota holder |
|
129 |
mechanism |
|
130 |
|
|
120 | 131 |
Raises: |
121 | 132 |
NotAllowedError: Operation not permitted |
122 | 133 |
""" |
... | ... | |
128 | 139 |
Parameters: |
129 | 140 |
'domain': Metadata domain |
130 | 141 |
|
142 |
Keyword arguments: |
|
131 | 143 |
'meta': Dictionary with metadata to update |
132 | 144 |
|
133 | 145 |
'replace': Replace instead of update |
... | ... | |
138 | 150 |
return |
139 | 151 |
|
140 | 152 |
def get_account_groups(self, user, account): |
141 |
"""Return a dictionary with the user groups defined for this account.
|
|
153 |
"""Return a dictionary with the user groups defined for the account.
|
|
142 | 154 |
|
143 | 155 |
Raises: |
144 | 156 |
NotAllowedError: Operation not permitted |
... | ... | |
161 | 173 |
The keys returned are: |
162 | 174 |
'quota': The maximum bytes allowed (default is 0 - unlimited) |
163 | 175 |
|
164 |
'versioning': Can be 'auto', 'manual' or 'none' (default is 'manual')
|
|
176 |
'versioning': Can be 'auto', 'manual' or 'none' (default: 'manual')
|
|
165 | 177 |
|
166 | 178 |
Raises: |
167 | 179 |
NotAllowedError: Operation not permitted |
... | ... | |
198 | 210 |
""" |
199 | 211 |
return |
200 | 212 |
|
201 |
def list_containers(self, user, account, marker=None, limit=10000, shared=False, until=None, public=False): |
|
213 |
def list_containers(self, user, account, marker=None, limit=10000, |
|
214 |
shared=False, until=None, public=False): |
|
202 | 215 |
"""Return a list of container names existing under an account. |
203 | 216 |
|
204 |
Parameters:
|
|
217 |
Keyword arguments:
|
|
205 | 218 |
'marker': Start list from the next item after 'marker' |
206 | 219 |
|
207 | 220 |
'limit': Number of containers to return |
... | ... | |
216 | 229 |
""" |
217 | 230 |
return [] |
218 | 231 |
|
219 |
def list_container_meta(self, user, account, container, domain, until=None): |
|
220 |
"""Return a list with all the container's object meta keys for the domain. |
|
232 |
def list_container_meta(self, user, account, container, domain, |
|
233 |
until=None): |
|
234 |
"""Return a list of the container's object meta keys for a domain. |
|
221 | 235 |
|
222 | 236 |
Raises: |
223 | 237 |
NotAllowedError: Operation not permitted |
... | ... | |
226 | 240 |
""" |
227 | 241 |
return [] |
228 | 242 |
|
229 |
def get_container_meta(self, user, account, container, domain, until=None, include_user_defined=True): |
|
243 |
def get_container_meta(self, user, account, container, domain, until=None, |
|
244 |
include_user_defined=True): |
|
230 | 245 |
"""Return a dictionary with the container metadata for the domain. |
231 | 246 |
|
232 | 247 |
The keys returned are all user-defined, except: |
... | ... | |
247 | 262 |
""" |
248 | 263 |
return {} |
249 | 264 |
|
250 |
def update_container_meta(self, user, account, container, domain, meta, replace=False): |
|
265 |
def update_container_meta(self, user, account, container, domain, meta, |
|
266 |
replace=False): |
|
251 | 267 |
"""Update the metadata associated with the container for the domain. |
252 | 268 |
|
253 | 269 |
Parameters: |
254 | 270 |
'domain': Metadata domain |
255 | 271 |
|
272 |
Keyword arguments: |
|
256 | 273 |
'meta': Dictionary with metadata to update |
257 | 274 |
|
258 | 275 |
'replace': Replace instead of update |
... | ... | |
270 | 287 |
The keys returned are: |
271 | 288 |
'quota': The maximum bytes allowed (default is 0 - unlimited) |
272 | 289 |
|
273 |
'versioning': Can be 'auto', 'manual' or 'none' (default is 'manual')
|
|
290 |
'versioning': Can be 'auto', 'manual' or 'none' (default: 'manual')
|
|
274 | 291 |
|
275 | 292 |
Raises: |
276 | 293 |
NotAllowedError: Operation not permitted |
... | ... | |
279 | 296 |
""" |
280 | 297 |
return {} |
281 | 298 |
|
282 |
def update_container_policy(self, user, account, container, policy, replace=False): |
|
299 |
def update_container_policy(self, user, account, container, policy, |
|
300 |
replace=False): |
|
283 | 301 |
"""Update the policy associated with the container. |
284 | 302 |
|
285 | 303 |
Raises: |
... | ... | |
291 | 309 |
""" |
292 | 310 |
return |
293 | 311 |
|
294 |
def put_container(self, user, account, container, policy=None, delimiter=None):
|
|
312 |
def put_container(self, user, account, container, policy=None): |
|
295 | 313 |
"""Create a new container with the given name. |
296 | 314 |
|
297 |
Parameters: |
|
298 |
'delimiter': If present deletes container contents instead of the container |
|
299 |
|
|
300 | 315 |
Raises: |
301 | 316 |
NotAllowedError: Operation not permitted |
302 | 317 |
|
... | ... | |
306 | 321 |
""" |
307 | 322 |
return |
308 | 323 |
|
309 |
def delete_container(self, user, account, container, until=None): |
|
324 |
def delete_container(self, user, account, container, until=None, |
|
325 |
delimiter=None): |
|
310 | 326 |
"""Delete/purge the container with the given name. |
311 | 327 |
|
328 |
Keyword arguments: |
|
329 |
'delimiter': If not None, deletes the container contents starting |
|
330 |
with the delimiter |
|
331 |
|
|
312 | 332 |
Raises: |
313 | 333 |
NotAllowedError: Operation not permitted |
314 | 334 |
|
... | ... | |
318 | 338 |
""" |
319 | 339 |
return |
320 | 340 |
|
321 |
def list_objects(self, user, account, container, prefix='', delimiter=None, marker=None, limit=10000, virtual=True, domain=None, keys=None, shared=False, until=None, size_range=None, public=False): |
|
322 |
"""Return a list of object (name, version_id) tuples existing under a container. |
|
341 |
def list_objects(self, user, account, container, prefix='', delimiter=None, |
|
342 |
marker=None, limit=10000, virtual=True, domain=None, |
|
343 |
keys=None, shared=False, until=None, size_range=None, |
|
344 |
public=False): |
|
345 |
"""List (object name, object version_id) under a container. |
|
323 | 346 |
|
324 |
Parameters:
|
|
347 |
Keyword arguments:
|
|
325 | 348 |
'prefix': List objects starting with 'prefix' |
326 | 349 |
|
327 |
'delimiter': Return unique names before 'delimiter' and after 'prefix' |
|
350 |
'delimiter': Return unique names before 'delimiter' and |
|
351 |
after 'prefix' |
|
328 | 352 |
|
329 | 353 |
'marker': Start list from the next item after 'marker' |
330 | 354 |
|
... | ... | |
333 | 357 |
'virtual': If not set, the result will only include names starting |
334 | 358 |
with 'prefix' and ending without a 'delimiter' or with |
335 | 359 |
the first occurance of the 'delimiter' after 'prefix'. |
336 |
If set, the result will include all names after 'prefix',
|
|
360 |
If set, the result will include all names after 'prefix' |
|
337 | 361 |
up to and including the 'delimiter' if it is found |
338 | 362 |
|
339 | 363 |
'domain': Metadata domain for keys |
... | ... | |
357 | 381 |
""" |
358 | 382 |
return [] |
359 | 383 |
|
360 |
def list_object_meta(self, user, account, container, prefix='', delimiter=None, marker=None, limit=10000, virtual=True, domain=None, keys=None, shared=False, until=None, size_range=None): |
|
361 |
"""Return a list of object metadata dicts existing under a container. |
|
384 |
def list_object_meta(self, user, account, container, prefix='', |
|
385 |
delimiter=None, marker=None, limit=10000, |
|
386 |
virtual=True, domain=None, keys=None, shared=False, |
|
387 |
until=None, size_range=None, public=False): |
|
388 |
"""Return a list of metadata dicts of objects under a container. |
|
362 | 389 |
|
363 | 390 |
Same parameters with list_objects. Returned dicts have no user-defined |
364 | 391 |
metadata and, if until is not None, a None 'modified' timestamp. |
... | ... | |
371 | 398 |
return [] |
372 | 399 |
|
373 | 400 |
def list_object_permissions(self, user, account, container, prefix=''): |
374 |
"""Return a list of paths that enforce permissions under a container.
|
|
401 |
"""Return a list of paths enforce permissions under a container. |
|
375 | 402 |
|
376 | 403 |
Raises: |
377 | 404 |
NotAllowedError: Operation not permitted |
... | ... | |
379 | 406 |
return [] |
380 | 407 |
|
381 | 408 |
def list_object_public(self, user, account, container, prefix=''): |
382 |
"""Return a dict mapping paths to public ids for objects that are public under a container."""
|
|
409 |
"""Return a mapping of object paths to public ids under a container."""
|
|
383 | 410 |
return {} |
384 | 411 |
|
385 |
def get_object_meta(self, user, account, container, name, domain, version=None, include_user_defined=True): |
|
412 |
def get_object_meta(self, user, account, container, name, domain, |
|
413 |
version=None, include_user_defined=True): |
|
386 | 414 |
"""Return a dictionary with the object metadata for the domain. |
387 | 415 |
|
388 | 416 |
The keys returned are all user-defined, except: |
... | ... | |
396 | 424 |
|
397 | 425 |
'modified': Last modification timestamp (overall) |
398 | 426 |
|
399 |
'modified_by': The user that committed the object (version requested) |
|
427 |
'modified_by': The user that committed the object |
|
428 |
(version requested) |
|
400 | 429 |
|
401 | 430 |
'version': The version identifier |
402 | 431 |
|
403 | 432 |
'version_timestamp': The version's modification timestamp |
404 | 433 |
|
405 |
'uuid': A unique identifier that persists data or metadata updates and renames |
|
434 |
'uuid': A unique identifier that persists data or metadata updates |
|
435 |
and renames |
|
406 | 436 |
|
407 | 437 |
'checksum': The MD5 sum of the object (may be empty) |
408 | 438 |
|
... | ... | |
415 | 445 |
""" |
416 | 446 |
return {} |
417 | 447 |
|
418 |
def update_object_meta(self, user, account, container, name, domain, meta, replace=False): |
|
419 |
"""Update the metadata associated with the object for the domain and return the new version. |
|
448 |
def update_object_meta(self, user, account, container, name, domain, meta, |
|
449 |
replace=False): |
|
450 |
"""Update object metadata for a domain and return the new version. |
|
420 | 451 |
|
421 | 452 |
Parameters: |
422 | 453 |
'domain': Metadata domain |
... | ... | |
449 | 480 |
""" |
450 | 481 |
return {} |
451 | 482 |
|
452 |
def update_object_permissions(self, user, account, container, name, permissions): |
|
483 |
def update_object_permissions(self, user, account, container, name, |
|
484 |
permissions): |
|
453 | 485 |
"""Update (set) the permissions associated with the object. |
454 | 486 |
|
455 | 487 |
Parameters: |
... | ... | |
499 | 531 |
""" |
500 | 532 |
return 0, [] |
501 | 533 |
|
502 |
def update_object_hashmap(self, user, account, container, name, size, type, hashmap, checksum, domain, meta=None, replace_meta=False, permissions=None): |
|
503 |
"""Create/update an object with the specified size and partial hashes and return the new version. |
|
534 |
def update_object_hashmap(self, user, account, container, name, size, type, |
|
535 |
hashmap, checksum, domain, meta=None, |
|
536 |
replace_meta=False, permissions=None): |
|
537 |
"""Create/update an object's hashmap and return the new version. |
|
504 | 538 |
|
505 | 539 |
Parameters: |
506 | 540 |
'domain': Metadata domain |
... | ... | |
522 | 556 |
""" |
523 | 557 |
return '' |
524 | 558 |
|
525 |
def update_object_checksum(self, user, account, container, name, version, checksum): |
|
559 |
def update_object_checksum(self, user, account, container, name, version, |
|
560 |
checksum): |
|
526 | 561 |
"""Update an object's checksum.""" |
527 | 562 |
return |
528 | 563 |
|
529 |
def copy_object(self, user, src_account, src_container, src_name, dest_account, dest_container, dest_name, type, domain, meta=None, replace_meta=False, permissions=None, src_version=None, delimiter=None): |
|
564 |
def copy_object(self, user, src_account, src_container, src_name, |
|
565 |
dest_account, dest_container, dest_name, type, domain, |
|
566 |
meta=None, replace_meta=False, permissions=None, |
|
567 |
src_version=None, delimiter=None): |
|
530 | 568 |
"""Copy an object's data and metadata and return the new version. |
531 | 569 |
|
532 | 570 |
Parameters: |
533 | 571 |
'domain': Metadata domain |
534 | 572 |
|
535 |
'meta': Dictionary with metadata to change from source to destination |
|
573 |
'meta': Dictionary with metadata to change from source |
|
574 |
to destination |
|
536 | 575 |
|
537 | 576 |
'replace_meta': Replace metadata instead of update |
538 | 577 |
|
... | ... | |
540 | 579 |
|
541 | 580 |
'src_version': Copy from the version provided |
542 | 581 |
|
543 |
'delimiter': Copy objects whose path starts with src_name + delimiter |
|
582 |
'delimiter': Copy objects whose path starts with |
|
583 |
src_name + delimiter |
|
544 | 584 |
|
545 | 585 |
Raises: |
546 | 586 |
NotAllowedError: Operation not permitted |
... | ... | |
555 | 595 |
""" |
556 | 596 |
return '' |
557 | 597 |
|
558 |
def move_object(self, user, src_account, src_container, src_name, dest_account, dest_container, dest_name, type, domain, meta=None, replace_meta=False, permissions=None, delimiter=None): |
|
598 |
def move_object(self, user, src_account, src_container, src_name, |
|
599 |
dest_account, dest_container, dest_name, type, domain, |
|
600 |
meta=None, replace_meta=False, permissions=None, |
|
601 |
delimiter=None): |
|
559 | 602 |
"""Move an object's data and metadata and return the new version. |
560 | 603 |
|
561 | 604 |
Parameters: |
562 | 605 |
'domain': Metadata domain |
563 | 606 |
|
564 |
'meta': Dictionary with metadata to change from source to destination |
|
607 |
'meta': Dictionary with metadata to change from source |
|
608 |
to destination |
|
565 | 609 |
|
566 | 610 |
'replace_meta': Replace metadata instead of update |
567 | 611 |
|
568 | 612 |
'permissions': New object permissions |
569 | 613 |
|
570 |
'delimiter': Move objects whose path starts with src_name + delimiter |
|
614 |
'delimiter': Move objects whose path starts with |
|
615 |
src_name + delimiter |
|
571 | 616 |
|
572 | 617 |
Raises: |
573 | 618 |
NotAllowedError: Operation not permitted |
... | ... | |
580 | 625 |
""" |
581 | 626 |
return '' |
582 | 627 |
|
583 |
def delete_object(self, user, account, container, name, until=None, delimiter=None): |
|
628 |
def delete_object(self, user, account, container, name, until=None, |
|
629 |
delimiter=None): |
|
584 | 630 |
"""Delete/purge an object. |
585 | 631 |
|
586 | 632 |
Parameters: |
587 |
'delimiter': Delete objects whose path starting with name + delimiter |
|
633 |
'delimiter': Delete objects whose path starting with |
|
634 |
name + delimiter |
|
588 | 635 |
|
589 | 636 |
Raises: |
590 | 637 |
NotAllowedError: Operation not permitted |
... | ... | |
594 | 641 |
return |
595 | 642 |
|
596 | 643 |
def list_versions(self, user, account, container, name): |
597 |
"""Return a list of all (version, version_timestamp) tuples for an object.
|
|
644 |
"""Return a list of all object (version, version_timestamp) tuples.
|
|
598 | 645 |
|
599 | 646 |
Raises: |
600 | 647 |
NotAllowedError: Operation not permitted |
... | ... | |
640 | 687 |
IndexError: Offset or data outside block limits |
641 | 688 |
""" |
642 | 689 |
return 0 |
690 |
|
|
691 |
def get_domain_objects(self, domain, user=None): |
|
692 |
"""Return a list of tuples for objects under the domain. |
|
693 |
|
|
694 |
Parameters: |
|
695 |
'user': return only objects accessible to the user. |
|
696 |
""" |
Also available in: Unified diff