[OVN][Trunk] Set the subports correct host during live migration
During the trunk migration, the parent port multiple port binding will contain the destination host. Because this update is done before the migration is done (in other words, the parent port still has two port binding registers), the method setting the binding profile of the subport will use the destination host in advance. At the end of the live migration, the subports host will point to the correct hostname. Related-Bug: #2027605 Change-Id: I2370ea2f96e2e31dbd43bf232a63394388e6945f
This commit is contained in:
parent
e1f887ca9f
commit
7ed79c1f78
@ -14,6 +14,7 @@ from neutron_lib.api.definitions import portbindings
|
||||
from neutron_lib.callbacks import events
|
||||
from neutron_lib.callbacks import registry
|
||||
from neutron_lib.callbacks import resources
|
||||
from neutron_lib import constants as n_const
|
||||
from neutron_lib import context as n_context
|
||||
from neutron_lib.db import api as db_api
|
||||
from neutron_lib import exceptions as n_exc
|
||||
@ -51,7 +52,11 @@ class OVNTrunkHandler(object):
|
||||
context = n_context.get_admin_context()
|
||||
db_parent_port = port_obj.Port.get_object(context, id=parent_port)
|
||||
parent_port_status = db_parent_port.status
|
||||
parent_port_bindings = db_parent_port.bindings[0]
|
||||
try:
|
||||
parent_port_bindings = [pb for pb in db_parent_port.bindings
|
||||
if pb.status == n_const.ACTIVE][-1]
|
||||
except IndexError:
|
||||
parent_port_bindings = None
|
||||
for subport in subports:
|
||||
with db_api.CONTEXT_WRITER.using(context), (
|
||||
txn(check_error=True)) as ovn_txn:
|
||||
@ -85,8 +90,10 @@ class OVNTrunkHandler(object):
|
||||
db_port.id, db_port, ovn_const.TYPE_PORTS)
|
||||
ovn_txn.add(check_rev_cmd)
|
||||
parent_binding_host = ''
|
||||
if parent_port_bindings.host:
|
||||
parent_binding_host = parent_port_bindings.host
|
||||
if parent_port_bindings and parent_port_bindings.host:
|
||||
migrating_to = parent_port_bindings.profile.get(
|
||||
ovn_const.MIGRATING_ATTR)
|
||||
parent_binding_host = migrating_to or parent_port_bindings.host
|
||||
try:
|
||||
# NOTE(flaviof): We expect binding's host to be set. Otherwise,
|
||||
# sub-port will not transition from DOWN to ACTIVE.
|
||||
|
@ -97,13 +97,23 @@ class TestOVNTrunkDriver(base.TestOVNFunctionalBase):
|
||||
if trunk.get('status'):
|
||||
self.assertEqual(trunk_consts.TRUNK_ACTIVE_STATUS, trunk['status'])
|
||||
|
||||
def _bind_port(self, port_id, host):
|
||||
def _bind_port(self, port_id, host_source, host_dest=None):
|
||||
with db_api.CONTEXT_WRITER.using(self.context):
|
||||
pb = port_obj.PortBinding.get_object(self.context,
|
||||
port_id=port_id, host='')
|
||||
pb.delete()
|
||||
port_obj.PortBinding(self.context, port_id=port_id, host=host,
|
||||
vif_type=portbindings.VIF_TYPE_OVS).create()
|
||||
for pb in port_obj.PortBinding.get_objects(self.context,
|
||||
port_id=port_id):
|
||||
pb.delete()
|
||||
profile = {}
|
||||
if host_dest:
|
||||
# When "host_dest" there are 2 port bindings, as in a live
|
||||
# migration; the second one (destination host) is inactive.
|
||||
profile[ovn_const.MIGRATING_ATTR] = host_dest
|
||||
port_obj.PortBinding(
|
||||
self.context, port_id=port_id, host=host_dest,
|
||||
vif_type=portbindings.VIF_TYPE_OVS,
|
||||
status=n_consts.INACTIVE).create()
|
||||
port_obj.PortBinding(
|
||||
self.context, port_id=port_id, host=host_source,
|
||||
profile=profile, vif_type=portbindings.VIF_TYPE_OVS).create()
|
||||
|
||||
def test_trunk_create(self):
|
||||
with self.trunk() as trunk:
|
||||
@ -148,6 +158,21 @@ class TestOVNTrunkDriver(base.TestOVNFunctionalBase):
|
||||
self._verify_trunk_info(new_trunk, has_items=True,
|
||||
host='host1')
|
||||
|
||||
def test_subport_add_live_migration_multiple_port_binding(self):
|
||||
with self.subport() as subport:
|
||||
with self.trunk() as trunk:
|
||||
self.trunk_plugin.add_subports(self.context, trunk['id'],
|
||||
{'sub_ports': [subport]})
|
||||
new_trunk = self.trunk_plugin.get_trunk(self.context,
|
||||
trunk['id'])
|
||||
self._verify_trunk_info(new_trunk, has_items=True)
|
||||
# Bind parent port. That will trigger the binding of the
|
||||
# trunk subports too, using the same host ID.
|
||||
self._bind_port(trunk['port_id'], 'host1', host_dest='host2')
|
||||
self.mech_driver.set_port_status_up(trunk['port_id'])
|
||||
self._verify_trunk_info(new_trunk, has_items=True,
|
||||
host='host2')
|
||||
|
||||
def test_subport_delete(self):
|
||||
with self.subport() as subport:
|
||||
with self.trunk([subport]) as trunk:
|
||||
|
Loading…
Reference in New Issue
Block a user