Compute: Catch binding failed exception while init host
While compute starts it will init all instances,
if an exception is raised from one instance
(e.g NovaException during plug_vifs), then the
compute process exits unexpectedly because of
this unhandled exception.
This commit changes the NovaException to more
appropriate VirtualInterfacePlugException and
catches it during init host, as well as the
instance is set to error state, with this change
the compute process can be started normally even
if this VirtualInterfacePlugException is raised.
Closes-bug: #1324041
Conflicts:
nova/tests/unit/compute/test_compute_mgr.py
nova/virt/ironic/driver.py
nova/virt/libvirt/vif.py
Change-Id: Ia584dba66affb86787e3069df19bd17b89cb5c49
(cherry picked from commit 16ac50b1e7
)
This commit is contained in:
parent
bbf65ab569
commit
e9cf07b96f
|
@ -915,6 +915,12 @@ class ComputeManager(manager.Manager):
|
|||
self.driver.plug_vifs(instance, net_info)
|
||||
except NotImplementedError as e:
|
||||
LOG.debug(e, instance=instance)
|
||||
except exception.VirtualInterfacePlugException:
|
||||
# we don't want an exception to block the init_host
|
||||
LOG.exception(_("Vifs plug failed"), instance=instance)
|
||||
self._set_instance_error_state(context, instance)
|
||||
return
|
||||
|
||||
if instance.task_state == task_states.RESIZE_MIGRATING:
|
||||
# We crashed during resize/migration, so roll back for safety
|
||||
try:
|
||||
|
|
|
@ -156,6 +156,10 @@ class VirtualInterfaceMacAddressException(NovaException):
|
|||
"unique mac address failed")
|
||||
|
||||
|
||||
class VirtualInterfacePlugException(NovaException):
|
||||
msg_fmt = _("Virtual interface plugin failed")
|
||||
|
||||
|
||||
class GlanceConnectionFailed(NovaException):
|
||||
msg_fmt = _("Connection to glance host %(host)s:%(port)s failed: "
|
||||
"%(reason)s")
|
||||
|
|
|
@ -272,6 +272,30 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase):
|
|||
self.mox.VerifyAll()
|
||||
self.mox.UnsetStubs()
|
||||
|
||||
def test_init_instance_with_binding_failed_vif_type(self):
|
||||
# this instance will plug a 'binding_failed' vif
|
||||
instance = fake_instance.fake_instance_obj(
|
||||
self.context,
|
||||
uuid='fake-uuid',
|
||||
info_cache=None,
|
||||
power_state=power_state.RUNNING,
|
||||
vm_state=vm_states.ACTIVE,
|
||||
task_state=None,
|
||||
expected_attrs=['info_cache'])
|
||||
|
||||
with contextlib.nested(
|
||||
mock.patch.object(context, 'get_admin_context',
|
||||
return_value=self.context),
|
||||
mock.patch.object(compute_utils, 'get_nw_info_for_instance',
|
||||
return_value=network_model.NetworkInfo()),
|
||||
mock.patch.object(self.compute.driver, 'plug_vifs',
|
||||
side_effect=exception.VirtualInterfacePlugException(
|
||||
"Unexpected vif_type=binding_failed")),
|
||||
mock.patch.object(self.compute, '_set_instance_error_state')
|
||||
) as (get_admin_context, get_nw_info, plug_vifs, set_error_state):
|
||||
self.compute._init_instance(self.context, instance)
|
||||
set_error_state.assert_called_once_with(self.context, instance)
|
||||
|
||||
def test_init_instance_failed_resume_sets_error(self):
|
||||
instance = fake_instance.fake_instance_obj(
|
||||
self.context,
|
||||
|
|
|
@ -592,7 +592,7 @@ class LibvirtGenericVIFDriver(LibvirtBaseVIFDriver):
|
|||
'vif': vif})
|
||||
|
||||
if vif_type is None:
|
||||
raise exception.NovaException(
|
||||
raise exception.VirtualInterfacePlugException(
|
||||
_("vif_type parameter must be present "
|
||||
"for this vif_driver implementation"))
|
||||
elif vif_type == network_model.VIF_TYPE_BRIDGE:
|
||||
|
@ -612,7 +612,7 @@ class LibvirtGenericVIFDriver(LibvirtBaseVIFDriver):
|
|||
elif vif_type == network_model.VIF_TYPE_MIDONET:
|
||||
self.plug_midonet(instance, vif)
|
||||
else:
|
||||
raise exception.NovaException(
|
||||
raise exception.VirtualInterfacePlugException(
|
||||
_("Unexpected vif_type=%s") % vif_type)
|
||||
|
||||
def unplug_bridge(self, instance, vif):
|
||||
|
|
Loading…
Reference in New Issue