Revision 19ddd41b snf-pithos-backend/pithos/backends/modular.py
b/snf-pithos-backend/pithos/backends/modular.py | ||
---|---|---|
32 | 32 |
# or implied, of GRNET S.A. |
33 | 33 |
|
34 | 34 |
import sys |
35 |
import os |
|
36 |
import time |
|
37 | 35 |
import uuid as uuidlib |
38 | 36 |
import logging |
39 | 37 |
import hashlib |
... | ... | |
41 | 39 |
|
42 | 40 |
from synnefo.lib.quotaholder import QuotaholderClient |
43 | 41 |
|
44 |
from base import DEFAULT_QUOTA, DEFAULT_VERSIONING, NotAllowedError, QuotaError, BaseBackend, \ |
|
45 |
AccountExists, ContainerExists, AccountNotEmpty, ContainerNotEmpty, ItemNotExists, VersionNotExists |
|
42 |
from base import (DEFAULT_ACCOUNT_QUOTA, DEFAULT_CONTAINER_QUOTA, |
|
43 |
DEFAULT_CONTAINER_VERSIONING, NotAllowedError, QuotaError, |
|
44 |
BaseBackend, AccountExists, ContainerExists, AccountNotEmpty, |
|
45 |
ContainerNotEmpty, ItemNotExists, VersionNotExists) |
|
46 | 46 |
|
47 | 47 |
# Stripped-down version of the HashMap class found in tools. |
48 | 48 |
|
... | ... | |
155 | 155 |
quotaholder_client_poolsize=None, |
156 | 156 |
free_versioning=True, block_params=None, |
157 | 157 |
public_url_security=None, |
158 |
public_url_alphabet=None): |
|
158 |
public_url_alphabet=None, |
|
159 |
account_quota_policy=None, |
|
160 |
container_quota_policy=None, |
|
161 |
container_versioning_policy=None): |
|
159 | 162 |
db_module = db_module or DEFAULT_DB_MODULE |
160 | 163 |
db_connection = db_connection or DEFAULT_DB_CONNECTION |
161 | 164 |
block_module = block_module or DEFAULT_BLOCK_MODULE |
... | ... | |
163 | 166 |
block_umask = block_umask or DEFAULT_BLOCK_UMASK |
164 | 167 |
block_params = block_params or DEFAULT_BLOCK_PARAMS |
165 | 168 |
#queue_module = queue_module or DEFAULT_QUEUE_MODULE |
166 |
|
|
167 |
self.default_policy = {'quota': DEFAULT_QUOTA, 'versioning': DEFAULT_VERSIONING} |
|
169 |
account_quota_policy = account_quota_policy or DEFAULT_ACCOUNT_QUOTA |
|
170 |
container_quota_policy = container_quota_policy \ |
|
171 |
or DEFAULT_CONTAINER_QUOTA |
|
172 |
container_versioning_policy = container_versioning_policy \ |
|
173 |
or DEFAULT_CONTAINER_VERSIONING |
|
174 |
|
|
175 |
self.default_account_policy = {'quota': account_quota_policy} |
|
176 |
self.default_container_policy = { |
|
177 |
'quota': container_quota_policy, |
|
178 |
'versioning': container_versioning_policy |
|
179 |
} |
|
168 | 180 |
#queue_hosts = queue_hosts or DEFAULT_QUEUE_HOSTS |
169 | 181 |
#queue_exchange = queue_exchange or DEFAULT_QUEUE_EXCHANGE |
170 | 182 |
|
... | ... | |
175 | 187 |
self.block_size = 4 * 1024 * 1024 # 4MB |
176 | 188 |
self.free_versioning = free_versioning |
177 | 189 |
|
178 |
self.default_policy = {'quota': DEFAULT_QUOTA, |
|
179 |
'versioning': DEFAULT_VERSIONING} |
|
180 |
|
|
181 | 190 |
def load_module(m): |
182 | 191 |
__import__(m) |
183 | 192 |
return sys.modules[m] |
... | ... | |
342 | 351 |
raise NotAllowedError |
343 | 352 |
return {} |
344 | 353 |
path, node = self._lookup_account(account, True) |
345 |
policy = self._get_policy(node) |
|
354 |
policy = self._get_policy(node, is_account_policy=True)
|
|
346 | 355 |
if self.using_external_quotaholder: |
347 | 356 |
external_quota = external_quota or {} |
348 | 357 |
policy['quota'] = external_quota.get('maxValue', 0) |
... | ... | |
357 | 366 |
if user != account: |
358 | 367 |
raise NotAllowedError |
359 | 368 |
path, node = self._lookup_account(account, True) |
360 |
self._check_policy(policy) |
|
361 |
self._put_policy(node, policy, replace) |
|
369 |
self._check_policy(policy, is_account_policy=True)
|
|
370 |
self._put_policy(node, policy, replace, is_account_policy=True)
|
|
362 | 371 |
|
363 | 372 |
@backend_method |
364 | 373 |
def put_account(self, user, account, policy=None): |
... | ... | |
372 | 381 |
if node is not None: |
373 | 382 |
raise AccountExists('Account already exists') |
374 | 383 |
if policy: |
375 |
self._check_policy(policy) |
|
384 |
self._check_policy(policy, is_account_policy=True)
|
|
376 | 385 |
node = self._put_path(user, self.ROOTNODE, account) |
377 |
self._put_policy(node, policy, True) |
|
386 |
self._put_policy(node, policy, True, is_account_policy=True)
|
|
378 | 387 |
|
379 | 388 |
@backend_method |
380 | 389 |
def delete_account(self, user, account): |
... | ... | |
483 | 492 |
src_version_id, dest_version_id = self._put_metadata( |
484 | 493 |
user, node, domain, meta, replace) |
485 | 494 |
if src_version_id is not None: |
486 |
versioning = self._get_policy(node)['versioning'] |
|
495 |
versioning = self._get_policy( |
|
496 |
node, is_account_policy=False)['versioning'] |
|
487 | 497 |
if versioning != 'auto': |
488 | 498 |
self.node.version_remove(src_version_id) |
489 | 499 |
|
... | ... | |
498 | 508 |
raise NotAllowedError |
499 | 509 |
return {} |
500 | 510 |
path, node = self._lookup_container(account, container) |
501 |
return self._get_policy(node) |
|
511 |
return self._get_policy(node, is_account_policy=False)
|
|
502 | 512 |
|
503 | 513 |
@backend_method |
504 | 514 |
def update_container_policy(self, user, account, container, policy, replace=False): |
... | ... | |
509 | 519 |
if user != account: |
510 | 520 |
raise NotAllowedError |
511 | 521 |
path, node = self._lookup_container(account, container) |
512 |
self._check_policy(policy) |
|
513 |
self._put_policy(node, policy, replace) |
|
522 |
self._check_policy(policy, is_account_policy=False)
|
|
523 |
self._put_policy(node, policy, replace, is_account_policy=False)
|
|
514 | 524 |
|
515 | 525 |
@backend_method |
516 | 526 |
def put_container(self, user, account, container, policy=None): |
... | ... | |
528 | 538 |
else: |
529 | 539 |
raise ContainerExists('Container already exists') |
530 | 540 |
if policy: |
531 |
self._check_policy(policy) |
|
541 |
self._check_policy(policy, is_account_policy=False)
|
|
532 | 542 |
path = '/'.join((account, container)) |
533 | 543 |
node = self._put_path( |
534 | 544 |
user, self._lookup_account(account, True)[1], path) |
535 |
self._put_policy(node, policy, True) |
|
545 |
self._put_policy(node, policy, True, is_account_policy=False)
|
|
536 | 546 |
|
537 | 547 |
@backend_method |
538 | 548 |
def delete_container(self, user, account, container, until=None, prefix='', delimiter=None): |
... | ... | |
879 | 889 |
size_delta = size - del_size |
880 | 890 |
if not self.using_external_quotaholder: # Check account quota. |
881 | 891 |
if size_delta > 0: |
882 |
account_quota = long(self._get_policy(account_node)['quota']) |
|
892 |
account_quota = long( |
|
893 |
self._get_policy(account_node, is_account_policy=True |
|
894 |
)['quota'] |
|
895 |
) |
|
883 | 896 |
account_usage = self._get_statistics(account_node)[1] + size_delta |
884 | 897 |
if (account_quota > 0 and account_usage > account_quota): |
885 | 898 |
raise QuotaError('account quota exceeded: limit: %s, usage: %s' % ( |
... | ... | |
887 | 900 |
)) |
888 | 901 |
|
889 | 902 |
# Check container quota. |
890 |
container_quota = long(self._get_policy(container_node)['quota']) |
|
903 |
container_quota = long( |
|
904 |
self._get_policy(container_node, is_account_policy=False |
|
905 |
)['quota'] |
|
906 |
) |
|
891 | 907 |
container_usage = self._get_statistics(container_node)[1] + size_delta |
892 | 908 |
if (container_quota > 0 and container_usage > container_quota): |
893 | 909 |
# This must be executed in a transaction, so the version is |
... | ... | |
1366 | 1382 |
|
1367 | 1383 |
# Policy functions. |
1368 | 1384 |
|
1369 |
def _check_policy(self, policy): |
|
1385 |
def _check_policy(self, policy, is_account_policy=True): |
|
1386 |
default_policy = self.default_account_policy \ |
|
1387 |
if is_account_policy else self.default_container_policy |
|
1370 | 1388 |
for k in policy.keys(): |
1371 | 1389 |
if policy[k] == '': |
1372 |
policy[k] = self.default_policy.get(k)
|
|
1390 |
policy[k] = default_policy.get(k) |
|
1373 | 1391 |
for k, v in policy.iteritems(): |
1374 | 1392 |
if k == 'quota': |
1375 | 1393 |
q = int(v) # May raise ValueError. |
... | ... | |
1381 | 1399 |
else: |
1382 | 1400 |
raise ValueError |
1383 | 1401 |
|
1384 |
def _put_policy(self, node, policy, replace): |
|
1402 |
def _put_policy(self, node, policy, replace, is_account_policy=True): |
|
1403 |
default_policy = self.default_account_policy \ |
|
1404 |
if is_account_policy else self.default_container_policy |
|
1385 | 1405 |
if replace: |
1386 |
for k, v in self.default_policy.iteritems():
|
|
1406 |
for k, v in default_policy.iteritems(): |
|
1387 | 1407 |
if k not in policy: |
1388 | 1408 |
policy[k] = v |
1389 | 1409 |
self.node.policy_set(node, policy) |
1390 | 1410 |
|
1391 |
def _get_policy(self, node): |
|
1392 |
policy = self.default_policy.copy() |
|
1411 |
def _get_policy(self, node, is_account_policy=True): |
|
1412 |
default_policy = self.default_account_policy \ |
|
1413 |
if is_account_policy else self.default_container_policy |
|
1414 |
policy = default_policy.copy() |
|
1393 | 1415 |
policy.update(self.node.policy_get(node)) |
1394 | 1416 |
return policy |
1395 | 1417 |
|
... | ... | |
1401 | 1423 |
if version_id is None: |
1402 | 1424 |
return 0 |
1403 | 1425 |
path, node = self._lookup_container(account, container) |
1404 |
versioning = self._get_policy(node)['versioning'] |
|
1426 |
versioning = self._get_policy( |
|
1427 |
node, is_account_policy=False)['versioning'] |
|
1405 | 1428 |
if versioning != 'auto': |
1406 | 1429 |
hash, size = self.node.version_remove(version_id) |
1407 | 1430 |
self.store.map_delete(hash) |
Also available in: Unified diff