Revision 2db7d9df snf-cyclades-app/synnefo/plankton/backend.py
b/snf-cyclades-app/synnefo/plankton/backend.py | ||
---|---|---|
54 | 54 |
import warnings |
55 | 55 |
|
56 | 56 |
from operator import itemgetter |
57 |
from time import gmtime, strftime, time |
|
57 |
from time import gmtime, strftime |
|
58 |
from functools import wraps |
|
58 | 59 |
|
59 | 60 |
from django.conf import settings |
60 | 61 |
|
61 |
from pithos.backends.base import NotAllowedError |
|
62 |
from pithos.backends.base import NotAllowedError as PithosNotAllowedError
|
|
62 | 63 |
|
63 | 64 |
|
64 | 65 |
PLANKTON_DOMAIN = 'plankton' |
... | ... | |
86 | 87 |
pass |
87 | 88 |
|
88 | 89 |
|
90 |
class NotAllowedError(BackendException): |
|
91 |
pass |
|
92 |
|
|
93 |
|
|
89 | 94 |
from pithos.backends.util import PithosBackendPool |
90 | 95 |
POOL_SIZE = 8 |
91 | 96 |
_pithos_backend_pool = \ |
... | ... | |
98 | 103 |
return _pithos_backend_pool.pool_get() |
99 | 104 |
|
100 | 105 |
|
106 |
def handle_backend_exceptions(func): |
|
107 |
@wraps(func) |
|
108 |
def wrapper(*args, **kwargs): |
|
109 |
try: |
|
110 |
return func(*args, **kwargs) |
|
111 |
except PithosNotAllowedError: |
|
112 |
raise NotAllowedError() |
|
113 |
return wrapper |
|
114 |
|
|
115 |
|
|
101 | 116 |
class ImageBackend(object): |
102 | 117 |
"""A wrapper arround the pithos backend to simplify image handling.""" |
103 | 118 |
|
... | ... | |
109 | 124 |
self.backend = get_pithos_backend() |
110 | 125 |
warnings.filters = original_filters # Restore warnings |
111 | 126 |
|
127 |
@handle_backend_exceptions |
|
112 | 128 |
def _get_image(self, location): |
113 | 129 |
def format_timestamp(t): |
114 | 130 |
return strftime('%Y-%m-%d %H:%M:%S', gmtime(t)) |
... | ... | |
159 | 175 |
|
160 | 176 |
return image |
161 | 177 |
|
178 |
@handle_backend_exceptions |
|
162 | 179 |
def _get_meta(self, location, version=None): |
163 | 180 |
account, container, object = split_location(location) |
164 | 181 |
try: |
... | ... | |
167 | 184 |
except NameError: |
168 | 185 |
return None |
169 | 186 |
|
187 |
@handle_backend_exceptions |
|
170 | 188 |
def _get_permissions(self, location): |
171 | 189 |
account, container, object = split_location(location) |
172 | 190 |
action, path, permissions = self.backend.get_object_permissions( |
173 | 191 |
self.user, account, container, object) |
174 | 192 |
return permissions |
175 | 193 |
|
194 |
@handle_backend_exceptions |
|
176 | 195 |
def _store(self, f, size=None): |
177 | 196 |
"""Breaks data into blocks and stores them in the backend""" |
178 | 197 |
|
... | ... | |
193 | 212 |
|
194 | 213 |
return hashmap, bytes |
195 | 214 |
|
215 |
@handle_backend_exceptions |
|
196 | 216 |
def _update(self, location, size, hashmap, meta, permissions): |
197 | 217 |
account, container, object = split_location(location) |
198 | 218 |
self.backend.update_object_hashmap(self.user, account, container, |
... | ... | |
200 | 220 |
permissions=permissions) |
201 | 221 |
self._update_meta(location, meta, replace=True) |
202 | 222 |
|
223 |
@handle_backend_exceptions |
|
203 | 224 |
def _update_meta(self, location, meta, replace=False): |
204 | 225 |
account, container, object = split_location(location) |
205 | 226 |
|
... | ... | |
213 | 234 |
self.backend.update_object_meta(self.user, account, container, object, |
214 | 235 |
PLANKTON_DOMAIN, prefixed, replace) |
215 | 236 |
|
237 |
@handle_backend_exceptions |
|
216 | 238 |
def _update_permissions(self, location, permissions): |
217 | 239 |
account, container, object = split_location(location) |
218 | 240 |
self.backend.update_object_permissions(self.user, account, container, |
219 | 241 |
object, permissions) |
220 | 242 |
|
243 |
@handle_backend_exceptions |
|
221 | 244 |
def add_user(self, image_id, user): |
222 | 245 |
image = self.get_image(image_id) |
223 | 246 |
assert image, "Image not found" |
... | ... | |
232 | 255 |
def close(self): |
233 | 256 |
self.backend.close() |
234 | 257 |
|
258 |
@handle_backend_exceptions |
|
235 | 259 |
def delete(self, image_id): |
236 | 260 |
image = self.get_image(image_id) |
237 | 261 |
account, container, object = split_location(image['location']) |
238 | 262 |
self.backend.delete_object(self.user, account, container, object) |
239 | 263 |
|
264 |
@handle_backend_exceptions |
|
240 | 265 |
def get_data(self, location): |
241 | 266 |
account, container, object = split_location(location) |
242 | 267 |
size, hashmap = self.backend.get_object_hashmap(self.user, account, |
... | ... | |
245 | 270 |
assert len(data) == size |
246 | 271 |
return data |
247 | 272 |
|
273 |
@handle_backend_exceptions |
|
248 | 274 |
def get_image(self, image_id): |
249 | 275 |
try: |
250 | 276 |
account, container, object = self.backend.get_uuid(self.user, |
... | ... | |
255 | 281 |
location = get_location(account, container, object) |
256 | 282 |
return self._get_image(location) |
257 | 283 |
|
284 |
@handle_backend_exceptions |
|
258 | 285 |
def iter(self): |
259 | 286 |
"""Iter over all images available to the user""" |
260 | 287 |
|
... | ... | |
269 | 296 |
if image: |
270 | 297 |
yield image |
271 | 298 |
|
299 |
@handle_backend_exceptions |
|
272 | 300 |
def iter_public(self, filters=None): |
273 | 301 |
filters = filters or {} |
274 | 302 |
backend = self.backend |
... | ... | |
295 | 323 |
if image: |
296 | 324 |
yield image |
297 | 325 |
|
326 |
@handle_backend_exceptions |
|
298 | 327 |
def iter_shared(self, member): |
299 | 328 |
"""Iterate over image ids shared to this member""" |
300 | 329 |
|
... | ... | |
313 | 342 |
except (NameError, NotAllowedError): |
314 | 343 |
continue |
315 | 344 |
|
345 |
@handle_backend_exceptions |
|
316 | 346 |
def list(self): |
317 | 347 |
"""Iter over all images available to the user""" |
318 | 348 |
|
319 | 349 |
return list(self.iter()) |
320 | 350 |
|
351 |
@handle_backend_exceptions |
|
321 | 352 |
def list_public(self, filters, params): |
322 | 353 |
images = list(self.iter_public(filters)) |
323 | 354 |
key = itemgetter(params.get('sort_key', 'created_at')) |
... | ... | |
325 | 356 |
images.sort(key=key, reverse=reverse) |
326 | 357 |
return images |
327 | 358 |
|
359 |
@handle_backend_exceptions |
|
328 | 360 |
def list_users(self, image_id): |
329 | 361 |
image = self.get_image(image_id) |
330 | 362 |
assert image, "Image not found" |
... | ... | |
332 | 364 |
permissions = self._get_permissions(image['location']) |
333 | 365 |
return [user for user in permissions.get('read', []) if user != '*'] |
334 | 366 |
|
367 |
@handle_backend_exceptions |
|
335 | 368 |
def put(self, name, f, params): |
336 | 369 |
assert 'checksum' not in params, "Passing a checksum is not supported" |
337 | 370 |
assert 'id' not in params, "Passing an ID is not supported" |
... | ... | |
359 | 392 |
self._update(location, size, hashmap, meta, permissions) |
360 | 393 |
return self._get_image(location) |
361 | 394 |
|
395 |
@handle_backend_exceptions |
|
362 | 396 |
def register(self, name, location, params): |
363 | 397 |
assert 'id' not in params, "Passing an ID is not supported" |
364 | 398 |
assert location.startswith('pithos://'), "Invalid location" |
... | ... | |
395 | 429 |
self._update_permissions(location, permissions) |
396 | 430 |
return self._get_image(location) |
397 | 431 |
|
432 |
@handle_backend_exceptions |
|
398 | 433 |
def remove_user(self, image_id, user): |
399 | 434 |
image = self.get_image(image_id) |
400 | 435 |
assert image, "Image not found" |
... | ... | |
407 | 442 |
return # User did not have access anyway |
408 | 443 |
self._update_permissions(location, permissions) |
409 | 444 |
|
445 |
@handle_backend_exceptions |
|
410 | 446 |
def replace_users(self, image_id, users): |
411 | 447 |
image = self.get_image(image_id) |
412 | 448 |
assert image, "Image not found" |
... | ... | |
418 | 454 |
permissions['read'].append('*') |
419 | 455 |
self._update_permissions(location, permissions) |
420 | 456 |
|
457 |
@handle_backend_exceptions |
|
421 | 458 |
def update(self, image_id, params): |
422 | 459 |
image = self.get_image(image_id) |
423 | 460 |
assert image, "Image not found" |
... | ... | |
440 | 477 |
|
441 | 478 |
self._update_meta(location, meta) |
442 | 479 |
return self.get_image(image_id) |
443 |
|
Also available in: Unified diff