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