Do not perform port update in case of baremetal instance.
In case of a baremetal instance, the instance's port binding:host_id gets updated during instance reboot to the nova compute host id by the periodic task: _heal_instance_info_cache. This regression was introduced in commit: I75fd15ac2a29e420c09499f2c41d11259ca811ae This is an un-desirable change as ironic virt driver did the original port binding, nova should not update the value. In case of a baremetal port, the binding:host_id represents the ironic node_uuid. In case of a SmartNIC(baremetal) port[1] the binding:host_id represent the SmartNIC hostname and it MUST not change since ironic relies on that information as well as the Neutron agent that runs on the SmartNIC. A new API method was added, "manages_port_bindings()", to ComputeDriver that defaults to False, and overriden in IronicDriver to True. A call to this API method is now made in _heal_instance_info_cache() to prevent port update for instance ports in case the underlying ComputeDriver manages the port binding. [1] I658754f7f8c74087b0aabfdef222a2c0b5698541 Change-Id: I47d1aba17cd2e9fff67846cc243c8fbd9ac21659 Closes-Bug: #1822801
This commit is contained in:
parent
fc3890667e
commit
091aa32896
|
@ -7204,8 +7204,14 @@ class ComputeManager(manager.Manager):
|
||||||
binding_failed or unbound binding:vif_type for any of the instances
|
binding_failed or unbound binding:vif_type for any of the instances
|
||||||
ports.
|
ports.
|
||||||
"""
|
"""
|
||||||
if not utils.is_neutron():
|
# Only update port bindings if compute manager does manage port
|
||||||
|
# bindings instead of the compute driver. For example IronicDriver
|
||||||
|
# manages the port binding for baremetal instance ports, hence,
|
||||||
|
# external intervention with the binding is not desired.
|
||||||
|
if (not utils.is_neutron() or
|
||||||
|
self.driver.manages_network_binding_host_id()):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
search_opts = {'device_id': instance.uuid,
|
search_opts = {'device_id': instance.uuid,
|
||||||
'fields': ['binding:host_id', 'binding:vif_type']}
|
'fields': ['binding:host_id', 'binding:vif_type']}
|
||||||
ports = self.network_api.list_ports(context, **search_opts)
|
ports = self.network_api.list_ports(context, **search_opts)
|
||||||
|
|
|
@ -7250,6 +7250,19 @@ class ComputeTestCase(BaseTestCase,
|
||||||
self.assertTrue(val)
|
self.assertTrue(val)
|
||||||
mock_list_ports.assert_called_once_with(ctxt, **search_opts)
|
mock_list_ports.assert_called_once_with(ctxt, **search_opts)
|
||||||
|
|
||||||
|
def test_require_nw_info_update_for_baremetal(self):
|
||||||
|
"""Tests _require_nw_info_update for baremetal instance,
|
||||||
|
expected behavior is to return False.
|
||||||
|
"""
|
||||||
|
compute_mgr = compute_manager.ComputeManager('ironic.IronicDriver')
|
||||||
|
with mock.patch.object(compute_mgr, 'network_api') as \
|
||||||
|
network_api_mock:
|
||||||
|
ctxt = context.get_admin_context()
|
||||||
|
instance = self._create_fake_instance_obj()
|
||||||
|
val = compute_mgr._require_nw_info_update(ctxt, instance)
|
||||||
|
self.assertFalse(val)
|
||||||
|
network_api_mock.assert_not_called()
|
||||||
|
|
||||||
def _heal_instance_info_cache(self,
|
def _heal_instance_info_cache(self,
|
||||||
_get_instance_nw_info_raise=False,
|
_get_instance_nw_info_raise=False,
|
||||||
_get_instance_nw_info_raise_cache=False,
|
_get_instance_nw_info_raise_cache=False,
|
||||||
|
|
|
@ -1843,6 +1843,19 @@ class ComputeDriver(object):
|
||||||
"""
|
"""
|
||||||
return instance.get('host')
|
return instance.get('host')
|
||||||
|
|
||||||
|
def manages_network_binding_host_id(self):
|
||||||
|
"""Compute driver manages port bindings.
|
||||||
|
|
||||||
|
Used to indicate whether or not the compute driver is responsible
|
||||||
|
for managing port binding details, such as the host_id.
|
||||||
|
By default the ComputeManager will manage port bindings and the
|
||||||
|
host_id associated with a binding using the network API.
|
||||||
|
However, some backends, like Ironic, will manage the port binding
|
||||||
|
host_id out-of-band and the compute service should not override what
|
||||||
|
is set by the backing hypervisor.
|
||||||
|
"""
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def load_compute_driver(virtapi, compute_driver=None):
|
def load_compute_driver(virtapi, compute_driver=None):
|
||||||
"""Load a compute driver module.
|
"""Load a compute driver module.
|
||||||
|
|
|
@ -2176,3 +2176,8 @@ class IronicDriver(virt_driver.ComputeDriver):
|
||||||
timer.start(interval=CONF.ironic.api_retry_interval).wait()
|
timer.start(interval=CONF.ironic.api_retry_interval).wait()
|
||||||
LOG.info('Successfully unrescued Ironic node %(node)s',
|
LOG.info('Successfully unrescued Ironic node %(node)s',
|
||||||
{'node': node_uuid}, instance=instance)
|
{'node': node_uuid}, instance=instance)
|
||||||
|
|
||||||
|
def manages_network_binding_host_id(self):
|
||||||
|
"""IronicDriver manages port bindings for baremetal instances.
|
||||||
|
"""
|
||||||
|
return True
|
||||||
|
|
Loading…
Reference in New Issue