Use project id from volume when retyping volumes
Use the project_id from the volume being retyped to reserve quota in get_volume_type_reservation(). Previously the project_id from the context was used, which could cause reservations to be made and never cleared. Change-Id: I25f7c00961e259102cdaea6ea9394d04ded96b92 Closes-Bug: #1505307
This commit is contained in:
parent
71932e9c4f
commit
ceb65b6f86
|
@ -31,7 +31,14 @@ def get_volume_type_reservation(ctxt, volume, type_id):
|
|||
QUOTAS.add_volume_type_opts(ctxt,
|
||||
reserve_opts,
|
||||
type_id)
|
||||
reservations = QUOTAS.reserve(ctxt, **reserve_opts)
|
||||
# Note that usually the project_id on the volume will be the same as
|
||||
# the project_id in the context. But, if they are different then the
|
||||
# reservations must be recorded against the project_id that owns the
|
||||
# volume.
|
||||
project_id = volume['project_id']
|
||||
reservations = QUOTAS.reserve(ctxt,
|
||||
project_id=project_id,
|
||||
**reserve_opts)
|
||||
except exception.OverQuota as e:
|
||||
overs = e.kwargs['overs']
|
||||
usages = e.kwargs['usages']
|
||||
|
|
|
@ -53,7 +53,8 @@ class VolumeActionsTest(test.TestCase):
|
|||
self.api_patchers[_meth].return_value = True
|
||||
|
||||
vol = {'id': 'fake', 'host': 'fake', 'status': 'available', 'size': 1,
|
||||
'migration_status': None, 'volume_type_id': 'fake'}
|
||||
'migration_status': None, 'volume_type_id': 'fake',
|
||||
'project_id': 'project_id'}
|
||||
self.get_patcher = mock.patch('cinder.volume.API.get')
|
||||
self.mock_volume_get = self.get_patcher.start()
|
||||
self.addCleanup(self.get_patcher.stop)
|
||||
|
|
|
@ -31,6 +31,7 @@ from cinder.db.sqlalchemy import models as sqa_models
|
|||
from cinder import exception
|
||||
from cinder import objects
|
||||
from cinder import quota
|
||||
from cinder import quota_utils
|
||||
from cinder import test
|
||||
import cinder.tests.unit.image.fake
|
||||
from cinder import volume
|
||||
|
@ -1821,3 +1822,38 @@ class QuotaReserveSqlAlchemyTestCase(test.TestCase):
|
|||
usage_id=self.usages['gigabytes'],
|
||||
project_id='test_project',
|
||||
delta=-2 * 1024), ])
|
||||
|
||||
|
||||
class QuotaVolumeTypeReservationTestCase(test.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(QuotaVolumeTypeReservationTestCase, self).setUp()
|
||||
|
||||
self.volume_type_name = CONF.default_volume_type
|
||||
self.volume_type = db.volume_type_create(
|
||||
context.get_admin_context(),
|
||||
dict(name=self.volume_type_name))
|
||||
|
||||
@mock.patch.object(quota.QUOTAS, 'reserve')
|
||||
@mock.patch.object(quota.QUOTAS, 'add_volume_type_opts')
|
||||
def test_volume_type_reservation(self,
|
||||
mock_add_volume_type_opts,
|
||||
mock_reserve):
|
||||
my_context = FakeContext('MyProject', None)
|
||||
volume = {'name': 'my_vol_name',
|
||||
'id': 'my_vol_id',
|
||||
'size': '1',
|
||||
'project_id': 'vol_project_id',
|
||||
}
|
||||
reserve_opts = {'volumes': 1, 'gigabytes': volume['size']}
|
||||
quota_utils.get_volume_type_reservation(my_context,
|
||||
volume,
|
||||
self.volume_type['id'])
|
||||
mock_add_volume_type_opts.assert_called_once_with(
|
||||
my_context,
|
||||
reserve_opts,
|
||||
self.volume_type['id'])
|
||||
mock_reserve.assert_called_once_with(my_context,
|
||||
project_id='vol_project_id',
|
||||
gigabytes='1',
|
||||
volumes=1)
|
||||
|
|
Loading…
Reference in New Issue