Skip to content

Commit

Permalink
Use project/user from instance for quotas
Browse files Browse the repository at this point in the history
If an admin confirms a resize, a periodic task auto-confirms a resize,
or if an admin reverts a resize, these should all use the instance
project/user for quota updates.

Closes-bug: 1271429
Closes-bug: 1278686
Closes-bug: 1278695

Change-Id: I1e128cd4035d0140e35582de795eb4d6fb8603f2
  • Loading branch information
comstud committed Mar 24, 2014
1 parent 2a67b98 commit bf936b4
Showing 2 changed files with 19 additions and 20 deletions.
23 changes: 11 additions & 12 deletions nova/compute/api.py
Original file line number Diff line number Diff line change
@@ -1541,7 +1541,7 @@ def _confirm_resize_on_deleting(self, context, instance):
LOG.info(_('Migration %s may have been confirmed during delete') %
migration.id, context=context, instance=instance)
return
quotas = self._reserve_quota_delta(context, deltas)
quotas = self._reserve_quota_delta(context, deltas, instance)

self._record_action_start(context, instance,
instance_actions.CONFIRM_RESIZE)
@@ -2173,7 +2173,7 @@ def revert_resize(self, context, instance):

# reverse quota reservation for increased resource usage
deltas = self._reverse_upsize_quota_delta(context, migration)
quotas = self._reserve_quota_delta(context, deltas)
quotas = self._reserve_quota_delta(context, deltas, instance)

instance.task_state = task_states.RESIZE_REVERTING
try:
@@ -2210,7 +2210,7 @@ def confirm_resize(self, context, instance, migration=None):

# reserve quota only for any decrease in resource usage
deltas = self._downsize_quota_delta(context, instance)
quotas = self._reserve_quota_delta(context, deltas)
quotas = self._reserve_quota_delta(context, deltas, instance)

migration.status = 'confirming'
migration.save()
@@ -2282,20 +2282,22 @@ def _downsize_quota_delta(context, instance):
return API._resize_quota_delta(context, new_flavor, old_flavor, 1, -1)

@staticmethod
def _reserve_quota_delta(context, deltas, project_id=None):
def _reserve_quota_delta(context, deltas, instance):
"""If there are deltas to reserve, construct a Quotas object and
reserve the deltas for the given project.
@param context: The nova request context.
@param deltas: A dictionary of the proposed delta changes.
@param project_id: Specify the project_id if current context
is admin and admin wants to impact on
common user's tenant.
@param instance: The instance we're operating on, so that
quotas can use the correct project_id/user_id.
@return: nova.objects.quotas.Quotas
"""
quotas = quotas_obj.Quotas()
if deltas:
quotas.reserve(context, project_id=project_id, **deltas)
project_id, user_id = quotas_obj.ids_from_instance(context,
instance)
quotas.reserve(context, project_id=project_id, user_id=user_id,
**deltas)
return quotas

@staticmethod
@@ -2370,10 +2372,7 @@ def resize(self, context, instance, flavor_id=None,
deltas = self._upsize_quota_delta(context, new_instance_type,
current_instance_type)
try:
project_id, user_id = quotas_obj.ids_from_instance(context,
instance)
quotas = self._reserve_quota_delta(context, deltas,
project_id=project_id)
quotas = self._reserve_quota_delta(context, deltas, instance)
except exception.OverQuota as exc:
quotas = exc.kwargs['quotas']
overs = exc.kwargs['overs']
16 changes: 8 additions & 8 deletions nova/tests/compute/test_compute_api.py
Original file line number Diff line number Diff line change
@@ -426,7 +426,7 @@ def _test_delete_resized_part(self, inst):
).AndReturn('deltas')
fake_quotas = quotas_obj.Quotas.from_reservations(self.context,
['rsvs'])
self.compute_api._reserve_quota_delta(self.context, 'deltas'
self.compute_api._reserve_quota_delta(self.context, 'deltas', inst,
).AndReturn(fake_quotas)
self.compute_api._record_action_start(
self.context, inst, instance_actions.CONFIRM_RESIZE)
@@ -809,8 +809,8 @@ def _test_confirm_resize(self, mig_ref_passed=False):
resvs = ['resvs']
fake_quotas = quotas_obj.Quotas.from_reservations(self.context, resvs)

self.compute_api._reserve_quota_delta(self.context,
'deltas').AndReturn(fake_quotas)
self.compute_api._reserve_quota_delta(self.context, 'deltas',
fake_inst).AndReturn(fake_quotas)

def _check_mig(expected_task_state=None):
self.assertEqual('confirming', fake_mig.status)
@@ -870,8 +870,8 @@ def _test_revert_resize(self):
resvs = ['resvs']
fake_quotas = quotas_obj.Quotas.from_reservations(self.context, resvs)

self.compute_api._reserve_quota_delta(self.context,
'deltas').AndReturn(fake_quotas)
self.compute_api._reserve_quota_delta(self.context, 'deltas',
fake_inst).AndReturn(fake_quotas)

def _check_state(expected_task_state=None):
self.assertEqual(task_states.RESIZE_REVERTING,
@@ -927,7 +927,7 @@ def test_revert_resize_concurent_fail(self):
resvs = ['resvs']
fake_quotas = quotas_obj.Quotas.from_reservations(self.context, resvs)
self.compute_api._reserve_quota_delta(
self.context, delta).AndReturn(fake_quotas)
self.context, delta, fake_inst).AndReturn(fake_quotas)

exc = exception.UnexpectedTaskStateError(
actual=task_states.RESIZE_REVERTING, expected=None)
@@ -992,7 +992,7 @@ def _test_resize(self, flavor_id_passed=True,
self.context, new_flavor,
current_flavor).AndReturn('deltas')
self.compute_api._reserve_quota_delta(self.context, 'deltas',
project_id=project_id).AndReturn(fake_quotas)
fake_inst).AndReturn(fake_quotas)

def _check_state(expected_task_state=None):
self.assertEqual(task_states.RESIZE_PREP,
@@ -1166,7 +1166,7 @@ def test_resize_quota_exceeds_fails(self):
headroom=headroom)

self.compute_api._reserve_quota_delta(self.context, deltas,
project_id=fake_inst['project_id']).AndRaise(
fake_inst).AndRaise(
exception.OverQuota(**over_quota_args))

self.mox.ReplayAll()

0 comments on commit bf936b4

Please sign in to comment.