Handle binding_failed vif plug errors on compute restart
Like change Ia584dba66affb86787e3069df19bd17b89cb5c49 which came before, is port binding fails and we have a "binding_failed" vif type in the info cache, we'll fail to plug vifs for an instance on compute restart which will prevent the service from restarting. Before the os-vif conversion code, this was handled with VirtualInterfacePlugException but the os-vif conversion code fails in a different way by raising a generic NovaException because the os-vif conversion utility doesn't handle a vif_type of "binding_failed". To resolve this and make the os-vif flow for binding_failed behave the same as the legacy path, we implement a translation function in os_vif_util for binding_failed which will make the plug_vifs code raise VirtualInterfacePlugException which is what the _init_instance code in ComputeManager is already handling. Admittedly this isn't the smartest thing and doesn't attempt to recover / fix the instance networking info, but it at least gives a more clear indication of what's wrong and lets the nova-compute service start up. A note is left in the _init_instance error handling that we could potentially try to heal binding_failed vifs in _heal_instance_info_cache, but that would need to be done in a separate change since it's more invasive. Change-Id: Ia963a093a1b26d90b4de2e8fc623031cf175aece Closes-Bug: #1784579 (cherry picked from commitcdf8ba5acb
) (cherry picked from commita890e3d624
) (cherry picked from commit4827cedbc5
)
This commit is contained in:
parent
745bd464f0
commit
254a19f0d3
|
@ -970,8 +970,15 @@ class ComputeManager(manager.Manager):
|
|||
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)
|
||||
# NOTE(mriedem): If we get here, it could be because the vif_type
|
||||
# in the cache is "binding_failed". The only way to fix that is to
|
||||
# try and bind the ports again, which would be expensive here on
|
||||
# host startup. We could add a check to _heal_instance_info_cache
|
||||
# to handle this, but probably only if the instance task_state is
|
||||
# None.
|
||||
LOG.exception('Virtual interface plugging failed for instance. '
|
||||
'The port binding:host_id may need to be manually '
|
||||
'updated.', instance=instance)
|
||||
self._set_instance_obj_error_state(context, instance)
|
||||
return
|
||||
|
||||
|
|
|
@ -462,6 +462,20 @@ def _nova_to_osvif_vif_hostdev_physical(vif):
|
|||
raise NotImplementedError()
|
||||
|
||||
|
||||
# VIF_TYPE_BINDING_FAILED = 'binding_failed'
|
||||
def _nova_to_osvif_vif_binding_failed(vif):
|
||||
"""Special handler for the "binding_failed" vif type.
|
||||
|
||||
The "binding_failed" vif type indicates port binding to a host failed
|
||||
and we are trying to plug the vifs again, which will fail because we
|
||||
do not know the actual real vif type, like ovs, bridge, etc. We raise
|
||||
NotImplementedError to indicate to the caller that we cannot handle
|
||||
this type of vif rather than the generic "Unsupported VIF type" error
|
||||
in nova_to_osvif_vif.
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
def nova_to_osvif_vif(vif):
|
||||
"""Convert a Nova VIF model to an os-vif object
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
from os_vif import objects as osv_objects
|
||||
from os_vif.objects import fields as os_vif_fields
|
||||
import six
|
||||
|
||||
from nova import exception
|
||||
from nova.network import model
|
||||
|
@ -972,9 +973,20 @@ class OSVIFUtilTestCase(test.NoDBTestCase):
|
|||
subnets=[]),
|
||||
)
|
||||
|
||||
self.assertRaises(exception.NovaException,
|
||||
os_vif_util.nova_to_osvif_vif,
|
||||
vif)
|
||||
ex = self.assertRaises(exception.NovaException,
|
||||
os_vif_util.nova_to_osvif_vif, vif)
|
||||
self.assertIn('Unsupported VIF type wibble', six.text_type(ex))
|
||||
|
||||
def test_nova_to_osvif_vif_binding_failed(self):
|
||||
vif = model.VIF(
|
||||
id="dc065497-3c8d-4f44-8fb4-e1d33c16a536",
|
||||
type="binding_failed",
|
||||
address="22:52:25:62:e2:aa",
|
||||
network=model.Network(
|
||||
id="b82c1929-051e-481d-8110-4669916c7915",
|
||||
label="Demo Net",
|
||||
subnets=[]),)
|
||||
self.assertIsNone(os_vif_util.nova_to_osvif_vif(vif))
|
||||
|
||||
def test_nova_to_osvif_vhostuser_vrouter(self):
|
||||
vif = model.VIF(
|
||||
|
|
Loading…
Reference in New Issue