Merge "Move registration "ChassisBandwidthConfigEvent" to OvnSbIdl init"
This commit is contained in:
commit
e2d14b4209
@ -110,8 +110,8 @@ def dict_chassis_config(state):
|
||||
class ChassisBandwidthConfigEvent(row_event.RowEvent):
|
||||
"""Chassis create update event to track the bandwidth config changes."""
|
||||
|
||||
def __init__(self, placement_extension):
|
||||
self._placement_extension = placement_extension
|
||||
def __init__(self, driver):
|
||||
self._driver = driver
|
||||
# NOTE(ralonsoh): BW resource provider information is stored in
|
||||
# "Chassis", not "Chassis_Private".
|
||||
table = 'Chassis'
|
||||
@ -119,9 +119,30 @@ class ChassisBandwidthConfigEvent(row_event.RowEvent):
|
||||
super().__init__(events, table, None)
|
||||
self.event_name = 'ChassisBandwidthConfigEvent'
|
||||
|
||||
@property
|
||||
def placement_extension(self):
|
||||
if self._driver._post_fork_event.is_set():
|
||||
return self._driver._ovn_client.placement_extension
|
||||
|
||||
def match_fn(self, event, row, old=None):
|
||||
# If the OVNMechanismDriver OVNClient has not been instantiated, the
|
||||
# event is skipped. All chassis configurations are read during the
|
||||
# OVN placement extension initialization.
|
||||
if (not self.placement_extension or
|
||||
not self.placement_extension.enabled):
|
||||
return False
|
||||
elif event == self.ROW_CREATE:
|
||||
return True
|
||||
elif event == self.ROW_UPDATE and old and hasattr(old, 'other_config'):
|
||||
row_bw = _parse_ovn_cms_options(row)
|
||||
old_bw = _parse_ovn_cms_options(old)
|
||||
if row_bw != old_bw:
|
||||
return True
|
||||
return False
|
||||
|
||||
def run(self, event, row, old):
|
||||
name2uuid = self._placement_extension.name2uuid()
|
||||
state = self._placement_extension.build_placement_state(row, name2uuid)
|
||||
name2uuid = self.placement_extension.name2uuid()
|
||||
state = self.placement_extension.build_placement_state(row, name2uuid)
|
||||
if not state:
|
||||
return
|
||||
|
||||
@ -153,18 +174,6 @@ class OVNClientPlacementExtension(object):
|
||||
self._plugin = None
|
||||
self.uuid_ns = ovn_const.OVN_RP_UUID
|
||||
self.supported_vnic_types = ovn_const.OVN_SUPPORTED_VNIC_TYPES
|
||||
if not self.enabled:
|
||||
return
|
||||
|
||||
if not self._config_event:
|
||||
self._config_event = ChassisBandwidthConfigEvent(self)
|
||||
try:
|
||||
self._driver._sb_idl.idl.notify_handler.watch_events(
|
||||
[self._config_event])
|
||||
except AttributeError:
|
||||
# "sb_idl.idl.notify_handler" is not present in the
|
||||
# MaintenanceWorker.
|
||||
pass
|
||||
|
||||
@property
|
||||
def placement_plugin(self):
|
||||
|
@ -35,6 +35,8 @@ from neutron.common.ovn import utils
|
||||
from neutron.conf.plugins.ml2.drivers.ovn import ovn_conf
|
||||
from neutron.db import ovn_hash_ring_db
|
||||
from neutron.plugins.ml2.drivers.ovn.agent import neutron_agent as n_agent
|
||||
from neutron.plugins.ml2.drivers.ovn.mech_driver.ovsdb.extensions import \
|
||||
placement
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
@ -808,6 +810,7 @@ class OvnSbIdl(OvnIdlDistributedLock):
|
||||
ChassisAgentTypeChangeEvent(self.driver),
|
||||
ChassisMetadataAgentWriteEvent(self.driver),
|
||||
PortBindingUpdateVirtualPortsEvent(driver),
|
||||
placement.ChassisBandwidthConfigEvent(driver),
|
||||
])
|
||||
|
||||
@classmethod
|
||||
|
@ -16,15 +16,18 @@ from unittest import mock
|
||||
|
||||
from neutron_lib import constants as n_const
|
||||
from neutron_lib.plugins import constants as plugins_constants
|
||||
from oslo_utils import uuidutils
|
||||
|
||||
from neutron.common.ovn import constants as ovn_const
|
||||
from neutron.common import utils as common_utils
|
||||
from neutron.plugins.ml2.drivers.ovn.mech_driver.ovsdb.extensions \
|
||||
import placement as placement_extension
|
||||
from neutron.tests.functional import base
|
||||
from neutron.tests.functional.plugins.ml2.drivers.ovn.mech_driver.ovsdb \
|
||||
import test_ovsdb_monitor
|
||||
|
||||
|
||||
class TestOVNClientQosExtension(base.TestOVNFunctionalBase):
|
||||
class TestOVNClientPlacementExtension(base.TestOVNFunctionalBase):
|
||||
|
||||
EMPTY_CHASSIS = {n_const.RP_BANDWIDTHS: {},
|
||||
n_const.RP_INVENTORY_DEFAULTS: {},
|
||||
@ -186,3 +189,39 @@ class TestOVNClientQosExtension(base.TestOVNFunctionalBase):
|
||||
inventory_defaults='allocation_ratio:1.1;min_unit:1',
|
||||
hypervisors='br-provider0:host2')
|
||||
self._check_placement_config({**self.CHASSIS1, **self.CHASSIS2_B})
|
||||
|
||||
@mock.patch.object(placement_extension, '_send_deferred_batch')
|
||||
def test_chassis_bandwidth_config_event(self, mock_send_placement):
|
||||
ch_host = 'fake-chassis-host'
|
||||
ch_name = uuidutils.generate_uuid()
|
||||
ch_event = test_ovsdb_monitor.WaitForChassisPrivateCreateEvent(
|
||||
ch_name, self.mech_driver.agent_chassis_table)
|
||||
self.mech_driver.sb_ovn.idl.notify_handler.watch_event(ch_event)
|
||||
self.chassis_name = self.add_fake_chassis(ch_host, name=ch_name)
|
||||
self.assertTrue(ch_event.wait())
|
||||
common_utils.wait_until_true(lambda: mock_send_placement.called,
|
||||
timeout=2)
|
||||
mock_send_placement.reset_mock()
|
||||
|
||||
# Once the chassis registger has been created, this new event will
|
||||
# catch any chassis BW update.
|
||||
self._update_chassis(
|
||||
ch_name,
|
||||
bandwidths='br-provider0:3000:4000',
|
||||
inventory_defaults='allocation_ratio:3.0;min_unit:1',
|
||||
hypervisors='br-provider0:host2')
|
||||
common_utils.wait_until_true(lambda: mock_send_placement.called,
|
||||
timeout=2)
|
||||
mock_send_placement.reset_mock()
|
||||
|
||||
# The chassis BW information is written again without any change.
|
||||
# That should not trigger the placement update.
|
||||
self._update_chassis(
|
||||
ch_name,
|
||||
bandwidths='br-provider0:3000:4000',
|
||||
inventory_defaults='allocation_ratio:3.0;min_unit:1',
|
||||
hypervisors='br-provider0:host2')
|
||||
self.assertRaises(common_utils.WaitTimeout,
|
||||
common_utils.wait_until_true,
|
||||
lambda: mock_send_placement.called,
|
||||
timeout=2)
|
||||
|
Loading…
Reference in New Issue
Block a user