diff options
| author | Russell Bryant <rbryant@redhat.com> | 2013-03-13 14:45:49 -0400 |
|---|---|---|
| committer | Russell Bryant <rbryant@redhat.com> | 2013-03-13 17:53:17 -0400 |
| commit | dced117ea919b74d9521ff422b4eb8a880474a0d (patch) | |
| tree | 8f8a5dabb58ed85441876408a2feb790948480fc /nova/compute | |
| parent | 1df14918988ba45fc95b6925a617238af398cc50 (diff) | |
Generalize console error handling during build.
There is a race condition where you can create an instance and then
quickly request a VNC or Spice console before the instance is ready.
The way this went down was different depending on the virt driver in
use. The libvirt driver would raise InstanceNotFound. The xenapi
driver would raise InstanceNotReady.
This patch moves the handling of this race that was in the xenapi driver
up to the compute manager. Now, all of the virt drivers that support
this method (libvirt, xenapi, vmware) will all raise InstanceNotFound in
this case, and the compute manager will convert it into InstanceNotReady
IFF the vm_state is BUILDING.
Related to bug 1154327.
Change-Id: I68f4a6db8aac26c6f731c985d97299ee38c34448
Diffstat (limited to 'nova/compute')
| -rwxr-xr-x | nova/compute/manager.py | 38 |
1 files changed, 26 insertions, 12 deletions
diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 3d3a094a2..2ced60da3 100755 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -2580,7 +2580,8 @@ class ComputeManager(manager.SchedulerDependentManager): else: return '\n'.join(log.split('\n')[-int(length):]) - @rpc_common.client_exceptions(exception.ConsoleTypeInvalid) + @rpc_common.client_exceptions(exception.ConsoleTypeInvalid, + exception.InstanceNotReady, exception.InstanceNotFound) @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) @wrap_instance_fault def get_vnc_console(self, context, console_type, instance): @@ -2601,15 +2602,21 @@ class ComputeManager(manager.SchedulerDependentManager): else: raise exception.ConsoleTypeInvalid(console_type=console_type) - # Retrieve connect info from driver, and then decorate with our - # access info token - connect_info = self.driver.get_vnc_console(instance) - connect_info['token'] = token - connect_info['access_url'] = access_url + try: + # Retrieve connect info from driver, and then decorate with our + # access info token + connect_info = self.driver.get_vnc_console(instance) + connect_info['token'] = token + connect_info['access_url'] = access_url + except exception.InstanceNotFound: + if instance['vm_state'] != vm_states.BUILDING: + raise + raise exception.InstanceNotReady(instance_id=instance['uuid']) return connect_info - @rpc_common.client_exceptions(exception.ConsoleTypeInvalid) + @rpc_common.client_exceptions(exception.ConsoleTypeInvalid, + exception.InstanceNotReady, exception.InstanceNotFound) @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) @wrap_instance_fault def get_spice_console(self, context, console_type, instance): @@ -2629,14 +2636,21 @@ class ComputeManager(manager.SchedulerDependentManager): else: raise exception.ConsoleTypeInvalid(console_type=console_type) - # Retrieve connect info from driver, and then decorate with our - # access info token - connect_info = self.driver.get_spice_console(instance) - connect_info['token'] = token - connect_info['access_url'] = access_url + try: + # Retrieve connect info from driver, and then decorate with our + # access info token + connect_info = self.driver.get_spice_console(instance) + connect_info['token'] = token + connect_info['access_url'] = access_url + except exception.InstanceNotFound: + if instance['vm_state'] != vm_states.BUILDING: + raise + raise exception.InstanceNotReady(instance_id=instance['uuid']) return connect_info + @rpc_common.client_exceptions(exception.ConsoleTypeInvalid, + exception.InstanceNotReady, exception.InstanceNotFound) @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) @wrap_instance_fault def validate_console_port(self, ctxt, instance, port, console_type): |
