Snapshot reservation sync calls wrong resource.
The snapshot reservations code isn't calling the
correct resource on sync (it's calling volumes). There's
also some problems with the logic being used on the delete/clean up
that are fixed here as well.
Fixes bug: 1157506
Fixes bug: 1157982
Change-Id: I91327b8043ab63aa35ea8a91b6de544bf5bf6c61
(cherry picked from commit b450eef832
)
This commit is contained in:
parent
407d9e5e95
commit
5ffed5d2f7
|
@ -314,7 +314,7 @@ def snapshot_data_get_for_project(context, project_id, session=None):
|
||||||
"""Get count and gigabytes used for snapshots for specified project."""
|
"""Get count and gigabytes used for snapshots for specified project."""
|
||||||
return IMPL.snapshot_data_get_for_project(context,
|
return IMPL.snapshot_data_get_for_project(context,
|
||||||
project_id,
|
project_id,
|
||||||
session=None)
|
session)
|
||||||
|
|
||||||
|
|
||||||
####################
|
####################
|
||||||
|
|
|
@ -238,6 +238,9 @@ global_opts = [
|
||||||
default=None,
|
default=None,
|
||||||
help='A list of backend names to use. These backend names '
|
help='A list of backend names to use. These backend names '
|
||||||
'should be backed by a unique [CONFIG] group '
|
'should be backed by a unique [CONFIG] group '
|
||||||
'with its options'), ]
|
'with its options'),
|
||||||
|
cfg.BoolOpt('no_snapshot_gb_quota',
|
||||||
|
default=False,
|
||||||
|
help='Whether snapshots count against GigaByte quota'), ]
|
||||||
|
|
||||||
FLAGS.register_opts(global_opts)
|
FLAGS.register_opts(global_opts)
|
||||||
|
|
|
@ -738,9 +738,9 @@ def _sync_volumes(context, project_id, session):
|
||||||
|
|
||||||
def _sync_snapshots(context, project_id, session):
|
def _sync_snapshots(context, project_id, session):
|
||||||
return dict(zip(('snapshots', 'gigabytes'),
|
return dict(zip(('snapshots', 'gigabytes'),
|
||||||
db.volume_data_get_for_project(context,
|
db.snapshot_data_get_for_project(context,
|
||||||
project_id,
|
project_id,
|
||||||
session=session)))
|
session=session)))
|
||||||
|
|
||||||
|
|
||||||
QUOTAS = QuotaEngine()
|
QUOTAS = QuotaEngine()
|
||||||
|
|
|
@ -68,13 +68,14 @@ class QuotaIntegrationTestCase(test.TestCase):
|
||||||
vol['user_id'] = self.user_id
|
vol['user_id'] = self.user_id
|
||||||
vol['project_id'] = self.project_id
|
vol['project_id'] = self.project_id
|
||||||
vol['size'] = size
|
vol['size'] = size
|
||||||
return db.volume_create(self.context, vol)['id']
|
vol['status'] = 'available'
|
||||||
|
return db.volume_create(self.context, vol)
|
||||||
|
|
||||||
def test_too_many_volumes(self):
|
def test_too_many_volumes(self):
|
||||||
volume_ids = []
|
volume_ids = []
|
||||||
for i in range(FLAGS.quota_volumes):
|
for i in range(FLAGS.quota_volumes):
|
||||||
volume_id = self._create_volume()
|
vol_ref = self._create_volume()
|
||||||
volume_ids.append(volume_id)
|
volume_ids.append(vol_ref['id'])
|
||||||
self.assertRaises(exception.QuotaError,
|
self.assertRaises(exception.QuotaError,
|
||||||
volume.API().create,
|
volume.API().create,
|
||||||
self.context, 10, '', '', None)
|
self.context, 10, '', '', None)
|
||||||
|
@ -83,8 +84,8 @@ class QuotaIntegrationTestCase(test.TestCase):
|
||||||
|
|
||||||
def test_too_many_gigabytes(self):
|
def test_too_many_gigabytes(self):
|
||||||
volume_ids = []
|
volume_ids = []
|
||||||
volume_id = self._create_volume(size=20)
|
vol_ref = self._create_volume(size=20)
|
||||||
volume_ids.append(volume_id)
|
volume_ids.append(vol_ref['id'])
|
||||||
self.assertRaises(exception.QuotaError,
|
self.assertRaises(exception.QuotaError,
|
||||||
volume.API().create,
|
volume.API().create,
|
||||||
self.context, 10, '', '', None)
|
self.context, 10, '', '', None)
|
||||||
|
|
|
@ -491,8 +491,11 @@ class API(base.Base):
|
||||||
raise exception.InvalidVolume(reason=msg)
|
raise exception.InvalidVolume(reason=msg)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
reservations = QUOTAS.reserve(context, snapshots=1,
|
if FLAGS.no_snapshot_gb_quota:
|
||||||
gigabytes=volume['size'])
|
reservations = QUOTAS.reserve(context, snapshots=1)
|
||||||
|
else:
|
||||||
|
reservations = QUOTAS.reserve(context, snapshots=1,
|
||||||
|
gigabytes=volume['size'])
|
||||||
except exception.OverQuota as e:
|
except exception.OverQuota as e:
|
||||||
overs = e.kwargs['overs']
|
overs = e.kwargs['overs']
|
||||||
usages = e.kwargs['usages']
|
usages = e.kwargs['usages']
|
||||||
|
|
|
@ -489,9 +489,25 @@ class VolumeManager(manager.SchedulerDependentManager):
|
||||||
snapshot_ref['id'],
|
snapshot_ref['id'],
|
||||||
{'status': 'error_deleting'})
|
{'status': 'error_deleting'})
|
||||||
|
|
||||||
|
# Get reservations
|
||||||
|
try:
|
||||||
|
if CONF.no_snapshot_gb_quota:
|
||||||
|
reservations = QUOTAS.reserve(context, snapshots=-1)
|
||||||
|
else:
|
||||||
|
reservations = QUOTAS.reserve(
|
||||||
|
context,
|
||||||
|
snapshots=-1,
|
||||||
|
gigabytes=-snapshot_ref['volume_size'])
|
||||||
|
except Exception:
|
||||||
|
reservations = None
|
||||||
|
LOG.exception(_("Failed to update usages deleting snapshot"))
|
||||||
self.db.volume_glance_metadata_delete_by_snapshot(context, snapshot_id)
|
self.db.volume_glance_metadata_delete_by_snapshot(context, snapshot_id)
|
||||||
self.db.snapshot_destroy(context, snapshot_id)
|
self.db.snapshot_destroy(context, snapshot_id)
|
||||||
LOG.info(_("snapshot %s: deleted successfully"), snapshot_ref['name'])
|
LOG.info(_("snapshot %s: deleted successfully"), snapshot_ref['name'])
|
||||||
|
|
||||||
|
# Commit the reservations
|
||||||
|
if reservations:
|
||||||
|
QUOTAS.commit(context, reservations)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def attach_volume(self, context, volume_id, instance_uuid, mountpoint):
|
def attach_volume(self, context, volume_id, instance_uuid, mountpoint):
|
||||||
|
|
|
@ -44,6 +44,8 @@
|
||||||
# syslog facility to receive log lines (string value)
|
# syslog facility to receive log lines (string value)
|
||||||
#syslog_log_facility=LOG_USER
|
#syslog_log_facility=LOG_USER
|
||||||
|
|
||||||
|
# Do not count snapshots against gigabytes quota (bool value)
|
||||||
|
#no_snapshot_gb_quota=False
|
||||||
|
|
||||||
#
|
#
|
||||||
# Options defined in cinder.exception
|
# Options defined in cinder.exception
|
||||||
|
@ -1168,4 +1170,4 @@
|
||||||
#volume_driver=cinder.volume.driver.FakeISCSIDriver
|
#volume_driver=cinder.volume.driver.FakeISCSIDriver
|
||||||
|
|
||||||
|
|
||||||
# Total option count: 254
|
# Total option count: 255
|
||||||
|
|
Loading…
Reference in New Issue