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:
		@@ -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)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user