Add exception handler for previous deleted flavor.
An exception happens if a previous flavor is deleted and 'nova resize-revert' run, because 'nova resize-revert' does not handle the deleted flavor. And also we have the same problem in _update_usage_from_migration(). This patch fixes the problems. How to reproduce the problem on DevStack: $ nova flavor-create sample 10 512 0 2 $ nova boot --image cirros-0.3.0-x86_64-uec --flavor sample test01 $ nova resize test01 m1.tiny $ nova flavor-delete 10 $ nova resize-revert test01 Before applying this patch: $ nova resize-revert test01 ERROR: The server could not comply with the request since it is either malformed or otherwise incorrect. (HTTP 400) (Request-ID: req-b0d3e016-9608-4a87-a0cc-44dfe00b25a1) $ After applying this patch: $ nova resize-revert test01 ERROR: Flavor used by the instance could not be found. (HTTP 400) (Request-ID: req-ed4ce174-33f2-4258-b522-674a1023ea74) $ Fixes bug 1091490 Change-Id: I39dd23a7565ae66544e8bc2aa7ad3299eb61bfcc
This commit is contained in:
parent
e1c7b18c7f
commit
4e02fa1964
|
@ -1024,6 +1024,9 @@ class Controller(wsgi.Controller):
|
|||
except exception.MigrationNotFound:
|
||||
msg = _("Instance has not been resized.")
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
except exception.InstanceTypeNotFound:
|
||||
msg = _("Flavor used by the instance could not be found.")
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
except exception.InstanceInvalidState as state_error:
|
||||
common.raise_http_conflict_for_instance_invalid_state(state_error,
|
||||
'revertResize')
|
||||
|
|
|
@ -453,7 +453,12 @@ class ResourceTracker(object):
|
|||
filtered[uuid] = migration
|
||||
|
||||
for migration in filtered.values():
|
||||
self._update_usage_from_migration(resources, migration)
|
||||
try:
|
||||
self._update_usage_from_migration(resources, migration)
|
||||
except exception.InstanceTypeNotFound:
|
||||
LOG.warn(_("InstanceType could not be found, skipping "
|
||||
"migration."), instance_uuid=uuid)
|
||||
continue
|
||||
|
||||
def _update_usage_from_instance(self, resources, instance):
|
||||
"""Update usage for a single instance."""
|
||||
|
|
|
@ -4239,6 +4239,40 @@ class ComputeAPITestCase(BaseTestCase):
|
|||
instance_types.destroy(name)
|
||||
self.compute.terminate_instance(self.context, instance=instance)
|
||||
|
||||
def test_resize_revert_deleted_flavor_fails(self):
|
||||
orig_name = 'test_resize_revert_orig_flavor'
|
||||
orig_flavorid = 11
|
||||
memory_mb = 128
|
||||
root_gb = 0
|
||||
vcpus = 1
|
||||
instance_types.create(orig_name, memory_mb, vcpus, root_gb, 0,
|
||||
orig_flavorid, 0, 1.0, True)
|
||||
|
||||
instance = self._create_fake_instance(type_name=orig_name)
|
||||
instance = db.instance_get_by_uuid(self.context, instance['uuid'])
|
||||
instance = jsonutils.to_primitive(instance)
|
||||
self.compute.run_instance(self.context, instance=instance)
|
||||
|
||||
old_instance_type_id = instance['instance_type_id']
|
||||
new_flavor = instance_types.get_instance_type_by_name('m1.tiny')
|
||||
new_flavorid = new_flavor['flavorid']
|
||||
new_instance_type_id = new_flavor['id']
|
||||
self.compute_api.resize(self.context, instance, new_flavorid)
|
||||
|
||||
db.migration_create(self.context.elevated(),
|
||||
{'instance_uuid': instance['uuid'],
|
||||
'old_instance_type_id': old_instance_type_id,
|
||||
'new_instance_type_id': new_instance_type_id,
|
||||
'status': 'finished'})
|
||||
instance = db.instance_update(self.context, instance['uuid'],
|
||||
{'task_state': None,
|
||||
'vm_state': vm_states.RESIZED})
|
||||
instance_types.destroy(orig_name)
|
||||
self.assertRaises(exception.InstanceTypeNotFound,
|
||||
self.compute_api.revert_resize,
|
||||
self.context, instance)
|
||||
self.compute.terminate_instance(self.context, instance=instance)
|
||||
|
||||
def test_migrate(self):
|
||||
instance = self._create_fake_instance()
|
||||
instance = db.instance_get_by_uuid(self.context, instance['uuid'])
|
||||
|
|
Loading…
Reference in New Issue