diff options
| author | Ken'ichi Ohmichi <oomichi@mxs.nes.nec.co.jp> | 2013-01-08 05:08:17 +0900 |
|---|---|---|
| committer | Ken'ichi Ohmichi <oomichi@mxs.nes.nec.co.jp> | 2013-01-08 06:37:16 +0900 |
| commit | 4e02fa1964f5de3a6ba345d858623f35b24beafd (patch) | |
| tree | 20a42a345e671bcbd8719658687ff74ce75578a8 | |
| parent | e1c7b18c7f3c8d97ba7b2cccf27b968ad4710735 (diff) | |
| download | nova-4e02fa1964f5de3a6ba345d858623f35b24beafd.tar.gz nova-4e02fa1964f5de3a6ba345d858623f35b24beafd.tar.xz nova-4e02fa1964f5de3a6ba345d858623f35b24beafd.zip | |
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
| -rw-r--r-- | nova/api/openstack/compute/servers.py | 3 | ||||
| -rw-r--r-- | nova/compute/resource_tracker.py | 7 | ||||
| -rw-r--r-- | nova/tests/compute/test_compute.py | 34 |
3 files changed, 43 insertions, 1 deletions
diff --git a/nova/api/openstack/compute/servers.py b/nova/api/openstack/compute/servers.py index 7a8d7d5a8..d2fad58e8 100644 --- a/nova/api/openstack/compute/servers.py +++ b/nova/api/openstack/compute/servers.py @@ -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') diff --git a/nova/compute/resource_tracker.py b/nova/compute/resource_tracker.py index c784fd83d..ba1915f42 100644 --- a/nova/compute/resource_tracker.py +++ b/nova/compute/resource_tracker.py @@ -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.""" diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py index 4099a2a15..112552200 100644 --- a/nova/tests/compute/test_compute.py +++ b/nova/tests/compute/test_compute.py @@ -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']) |
