diff --git a/cinder/tests/unit/test_quota.py b/cinder/tests/unit/test_quota.py index 0306f18dae5..87d5246e456 100644 --- a/cinder/tests/unit/test_quota.py +++ b/cinder/tests/unit/test_quota.py @@ -37,6 +37,7 @@ from cinder import quota_utils from cinder import test from cinder.tests.unit import fake_constants as fake import cinder.tests.unit.image.fake +from cinder.tests.unit import utils as tests_utils from cinder import volume @@ -158,6 +159,25 @@ class QuotaIntegrationTestCase(test.TestCase): self.assertEqual(msg, six.text_type(ex)) vol_ref.destroy() + def test__snapshots_quota_value(self): + test_volume1 = tests_utils.create_volume( + self.context, + status='available', + host=CONF.host) + test_volume2 = tests_utils.create_volume( + self.context, + status='available', + host=CONF.host) + volume_api = cinder.volume.api.API() + volume_api.create_snapshots_in_db(self.context, + [test_volume1, test_volume2], + 'fake_name', + 'fake_description', + fake.CONSISTENCY_GROUP_ID) + usages = db.quota_usage_get_all_by_project(self.context, + self.project_id) + self.assertEqual(1, usages['snapshots']['in_use']) + def test_too_many_snapshots_of_type(self): resource = 'snapshots_%s' % self.volume_type_name db.quota_class_create(self.context, 'default', resource, 1) diff --git a/cinder/tests/unit/utils.py b/cinder/tests/unit/utils.py index 4288f39e6ba..01c6832092d 100644 --- a/cinder/tests/unit/utils.py +++ b/cinder/tests/unit/utils.py @@ -89,6 +89,7 @@ def create_volume(ctxt, vol['consistencygroup_id'] = consistencygroup_id if group_id: vol['group_id'] = group_id + vol['group_snapshot'] = None if volume_type_id: vol['volume_type_id'] = volume_type_id if metadata: diff --git a/cinder/tests/unit/volume/flows/test_create_volume_flow.py b/cinder/tests/unit/volume/flows/test_create_volume_flow.py index b2a9a0b7630..59b26ed0016 100644 --- a/cinder/tests/unit/volume/flows/test_create_volume_flow.py +++ b/cinder/tests/unit/volume/flows/test_create_volume_flow.py @@ -191,7 +191,8 @@ class CreateVolumeFlowTestCase(test.TestCase): key_manager=fake_key_manager, consistencygroup=None, cgsnapshot=None, - group=None) + group=None, + group_snapshot=None) self.assertEqual(replication_status, result['replication_status'], extra_specs) @@ -236,7 +237,8 @@ class CreateVolumeFlowTestCase(test.TestCase): key_manager=fake_key_manager, consistencygroup=None, cgsnapshot=None, - group=None) + group=None, + group_snapshot=None) fake_get_encryption_key.assert_called_once_with( fake_key_manager, self.ctxt, fakes.VOLUME_TYPE_ID, None, None, image_meta) @@ -280,7 +282,8 @@ class CreateVolumeFlowTestCase(test.TestCase): key_manager=fake_key_manager, consistencygroup=None, cgsnapshot=None, - group=None) + group=None, + group_snapshot=None) expected_result = {'size': 1, 'snapshot_id': None, 'source_volid': None, @@ -336,7 +339,8 @@ class CreateVolumeFlowTestCase(test.TestCase): key_manager=fake_key_manager, consistencygroup=None, cgsnapshot=None, - group=None) + group=None, + group_snapshot=None) @mock.patch('cinder.volume.volume_types.is_encrypted') @mock.patch('cinder.volume.volume_types.get_volume_type_qos_specs') @@ -379,7 +383,8 @@ class CreateVolumeFlowTestCase(test.TestCase): key_manager=fake_key_manager, consistencygroup=None, cgsnapshot=None, - group=None) + group=None, + group_snapshot=None) expected_result = {'size': 1, 'snapshot_id': None, 'source_volid': None, @@ -442,7 +447,8 @@ class CreateVolumeFlowTestCase(test.TestCase): key_manager=fake_key_manager, consistencygroup=None, cgsnapshot=None, - group=None) + group=None, + group_snapshot=None) mock_is_encrypted.assert_called_once_with(self.ctxt, 1) mock_get_volume_type_encryption.assert_called_once_with(self.ctxt, 1) @@ -485,7 +491,8 @@ class CreateVolumeFlowTestCase(test.TestCase): key_manager=fake_key_manager, consistencygroup=None, cgsnapshot=None, - group=None) + group=None, + group_snapshot=None) expected_result = {'size': (sys.maxsize + 1), 'snapshot_id': None, 'source_volid': None, @@ -541,7 +548,8 @@ class CreateVolumeFlowTestCase(test.TestCase): key_manager=fake_key_manager, consistencygroup=None, cgsnapshot=None, - group=None) + group=None, + group_snapshot=None) expected_result = {'size': 1, 'snapshot_id': None, 'source_volid': None, @@ -604,7 +612,8 @@ class CreateVolumeFlowTestCase(test.TestCase): key_manager=fake_key_manager, consistencygroup=None, cgsnapshot=None, - group=None) + group=None, + group_snapshot=None) expected_result = {'size': 1, 'snapshot_id': None, 'source_volid': None, @@ -668,7 +677,8 @@ class CreateVolumeFlowTestCase(test.TestCase): key_manager=fake_key_manager, consistencygroup=None, cgsnapshot=None, - group=None) + group=None, + group_snapshot=None) expected_result = {'size': 1, 'snapshot_id': None, 'source_volid': None, @@ -731,7 +741,8 @@ class CreateVolumeFlowTestCase(test.TestCase): key_manager=fake_key_manager, consistencygroup=None, cgsnapshot=None, - group=None) + group=None, + group_snapshot=None) expected_result = {'size': 1, 'snapshot_id': None, 'source_volid': None, @@ -792,7 +803,8 @@ class CreateVolumeFlowTestCase(test.TestCase): key_manager=fake_key_manager, consistencygroup=None, cgsnapshot=None, - group=None) + group=None, + group_snapshot=None) @ddt.ddt diff --git a/cinder/tests/unit/volume/flows/test_manage_volume_flow.py b/cinder/tests/unit/volume/flows/test_manage_volume_flow.py index bf4f75d9b8a..ed5b6f6ab19 100644 --- a/cinder/tests/unit/volume/flows/test_manage_volume_flow.py +++ b/cinder/tests/unit/volume/flows/test_manage_volume_flow.py @@ -109,6 +109,7 @@ class ManageVolumeFlowTestCase(test.TestCase): 'context': mock.sentinel.context, 'volume': mock.sentinel.volume, 'manage_existing_ref': mock.sentinel.ref, + 'group_snapshot': None, 'optional_args': {'is_quota_committed': False}, } @@ -135,6 +136,7 @@ class ManageVolumeFlowTestCase(test.TestCase): 'context', 'volume', 'manage_existing_ref', + 'group_snapshot', 'optional_args', ] diff --git a/cinder/volume/api.py b/cinder/volume/api.py index 3e8a2c9270d..8282a013261 100644 --- a/cinder/volume/api.py +++ b/cinder/volume/api.py @@ -959,12 +959,10 @@ class API(base.Base): reserve_opts_list = [] total_reserve_opts = {} try: + reserve_opts_list.append({'snapshots': 1}) for volume in volume_list: - if CONF.no_snapshot_gb_quota: - reserve_opts = {'snapshots': 1} - else: - reserve_opts = {'snapshots': 1, - 'gigabytes': volume['size']} + if not CONF.no_snapshot_gb_quota: + reserve_opts = {'gigabytes': volume['size']} QUOTAS.add_volume_type_opts(context, reserve_opts, volume.get('volume_type_id')) diff --git a/cinder/volume/flows/api/create_volume.py b/cinder/volume/flows/api/create_volume.py index c5d1451c6de..0460a0a9e69 100644 --- a/cinder/volume/flows/api/create_volume.py +++ b/cinder/volume/flows/api/create_volume.py @@ -414,7 +414,7 @@ class ExtractVolumeRequestTask(flow_utils.CinderTask): def execute(self, context, size, snapshot, image_id, source_volume, availability_zone, volume_type, metadata, key_manager, - consistencygroup, cgsnapshot, group): + consistencygroup, cgsnapshot, group, group_snapshot): utils.check_exclusive_options(snapshot=snapshot, imageRef=image_id, @@ -615,7 +615,8 @@ class QuotaReserveTask(flow_utils.CinderTask): def __init__(self): super(QuotaReserveTask, self).__init__(addons=[ACTION]) - def execute(self, context, size, volume_type_id, optional_args): + def execute(self, context, size, volume_type_id, group_snapshot, + optional_args): try: values = {'per_volume_gigabytes': size} QUOTAS.limit_check(context, project_id=context.project_id, @@ -626,7 +627,10 @@ class QuotaReserveTask(flow_utils.CinderTask): size=size, limit=quotas['per_volume_gigabytes']) try: - reserve_opts = {'volumes': 1, 'gigabytes': size} + if group_snapshot: + reserve_opts = {'volumes': 1} + else: + reserve_opts = {'volumes': 1, 'gigabytes': size} QUOTAS.add_volume_type_opts(context, reserve_opts, volume_type_id) reservations = QUOTAS.reserve(context, **reserve_opts) return { diff --git a/cinder/volume/flows/manager/manage_existing.py b/cinder/volume/flows/manager/manage_existing.py index d55f9cec0e1..e6f33940fc2 100644 --- a/cinder/volume/flows/manager/manage_existing.py +++ b/cinder/volume/flows/manager/manage_existing.py @@ -117,6 +117,7 @@ def get_flow(context, db, driver, host, volume, ref): 'context': context, 'volume': volume, 'manage_existing_ref': ref, + 'group_snapshot': None, 'optional_args': {'is_quota_committed': False}, }