hyper-v: Logs tips on PortBindingFailed
When spawning an Hyper-V instance with NICs having the vif_type "hyperv", neutron will fail to bind the port to the Hyper-V host if the neutron server doesn't have the "hyperv" mechanism driver installed and configured, resulting in a PortBindingFailed exception on the nova-compute side. When this exception is encountered, the logs will say to check the neutron-server logs, but the problem and its solution are not obvious or clear, resulting in plenty of questions / reports, all having the same solution: is there an L2 agent on the host alive and reporting to neutron, and if neutron Hyper-V agent is used, make sure to install networking-hyperv and configure neutron-server to use the "hyperv" mechanism_driver. Change-Id: I94ed8f15f3c6312a6f675b9255aff7e9d76f96fc Closes-Bug: #1744032
This commit is contained in:
parent
95116aae72
commit
d4fa1d7da1
|
@ -352,9 +352,11 @@ class VMOps(object):
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def wait_vif_plug_events(self, instance, network_info):
|
def wait_vif_plug_events(self, instance, network_info):
|
||||||
timeout = CONF.vif_plugging_timeout
|
timeout = CONF.vif_plugging_timeout
|
||||||
events = self._get_neutron_events(network_info)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
# NOTE(claudiub): async calls to bind the neutron ports will be
|
||||||
|
# done when network_info is being accessed.
|
||||||
|
events = self._get_neutron_events(network_info)
|
||||||
with self._virtapi.wait_for_instance_event(
|
with self._virtapi.wait_for_instance_event(
|
||||||
instance, events, deadline=timeout,
|
instance, events, deadline=timeout,
|
||||||
error_callback=self._neutron_failed_callback):
|
error_callback=self._neutron_failed_callback):
|
||||||
|
@ -365,6 +367,18 @@ class VMOps(object):
|
||||||
'instance.', instance=instance)
|
'instance.', instance=instance)
|
||||||
if CONF.vif_plugging_is_fatal:
|
if CONF.vif_plugging_is_fatal:
|
||||||
raise exception.VirtualInterfaceCreateException()
|
raise exception.VirtualInterfaceCreateException()
|
||||||
|
except exception.PortBindingFailed:
|
||||||
|
LOG.warning(
|
||||||
|
"Neutron failed to bind a port to this host. Make sure that "
|
||||||
|
"an L2 agent is registered on this node and alive (Neutron "
|
||||||
|
"Open vSwitch agent or Hyper-V agent), or that Neutron is "
|
||||||
|
"configured with a mechanism driver that is able to bind "
|
||||||
|
"ports without requiring an L2 agent on this host (e.g. OVN "
|
||||||
|
"mechanism driver). If you're using Neutron Hyper-V agent, "
|
||||||
|
"make sure that networking-hyperv is installed on the "
|
||||||
|
"Neutron controller and that the neutron-server service was "
|
||||||
|
"configured to use the 'hyperv' mechanism_driver.")
|
||||||
|
raise
|
||||||
|
|
||||||
def _neutron_failed_callback(self, event_name, instance):
|
def _neutron_failed_callback(self, event_name, instance):
|
||||||
LOG.error('Neutron Reported failure on event %s',
|
LOG.error('Neutron Reported failure on event %s',
|
||||||
|
|
|
@ -616,6 +616,18 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase):
|
||||||
deadline=CONF.vif_plugging_timeout,
|
deadline=CONF.vif_plugging_timeout,
|
||||||
error_callback=self._vmops._neutron_failed_callback)
|
error_callback=self._vmops._neutron_failed_callback)
|
||||||
|
|
||||||
|
@mock.patch.object(vmops.VMOps, '_get_neutron_events')
|
||||||
|
def test_wait_vif_plug_events_port_binding_failed(self, mock_get_events):
|
||||||
|
mock_get_events.side_effect = exception.PortBindingFailed(
|
||||||
|
port_id='fake_id')
|
||||||
|
|
||||||
|
def _context_user():
|
||||||
|
with self._vmops.wait_vif_plug_events(mock.sentinel.instance,
|
||||||
|
mock.sentinel.network_info):
|
||||||
|
pass
|
||||||
|
|
||||||
|
self.assertRaises(exception.PortBindingFailed, _context_user)
|
||||||
|
|
||||||
def test_neutron_failed_callback(self):
|
def test_neutron_failed_callback(self):
|
||||||
self.flags(vif_plugging_is_fatal=True)
|
self.flags(vif_plugging_is_fatal=True)
|
||||||
self.assertRaises(exception.VirtualInterfaceCreateException,
|
self.assertRaises(exception.VirtualInterfaceCreateException,
|
||||||
|
|
Loading…
Reference in New Issue