Browse Source

Merge "[OVN] Only account for bound ports in metadata agent" into stable/victoria

changes/00/788600/1
Zuul 2 weeks ago
committed by Gerrit Code Review
parent
commit
db49ed52cb
4 changed files with 37 additions and 22 deletions
  1. +2
    -1
      neutron/agent/ovn/metadata/agent.py
  2. +7
    -4
      neutron/agent/ovn/metadata/server.py
  3. +18
    -9
      neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/impl_idl_ovn.py
  4. +10
    -8
      neutron/tests/unit/agent/ovn/metadata/test_server.py

+ 2
- 1
neutron/agent/ovn/metadata/agent.py View File

@ -221,7 +221,8 @@ class MetadataAgent(object):
self._load_config()
# Launch the server that will act as a proxy between the VM's and Nova.
proxy = metadata_server.UnixDomainMetadataProxy(self.conf)
proxy = metadata_server.UnixDomainMetadataProxy(self.conf,
self.chassis)
proxy.run()
tables = ('Encap', 'Port_Binding', 'Datapath_Binding', 'SB_Global',


+ 7
- 4
neutron/agent/ovn/metadata/server.py View File

@ -43,8 +43,9 @@ MODE_MAP = {
class MetadataProxyHandler(object):
def __init__(self, conf):
def __init__(self, conf, chassis):
self.conf = conf
self.chassis = chassis
self.subscribe()
def subscribe(self):
@ -56,7 +57,8 @@ class MetadataProxyHandler(object):
# We need to open a connection to OVN SouthBound database for
# each worker so that we can process the metadata requests.
self.sb_idl = ovsdb.MetadataAgentOvnSbIdl(
tables=('Port_Binding', 'Datapath_Binding')).start()
tables=('Port_Binding', 'Datapath_Binding', 'Chassis'),
chassis=self.chassis).start()
@webob.dec.wsgify(RequestClass=webob.Request)
def __call__(self, req):
@ -173,8 +175,9 @@ class MetadataProxyHandler(object):
class UnixDomainMetadataProxy(object):
def __init__(self, conf):
def __init__(self, conf, chassis):
self.conf = conf
self.chassis = chassis
agent_utils.ensure_directory_exists_without_file(
cfg.CONF.metadata_proxy_socket)
@ -203,7 +206,7 @@ class UnixDomainMetadataProxy(object):
md_workers = self.conf.metadata_workers
if md_workers is None:
md_workers = 2
self.server.start(MetadataProxyHandler(self.conf),
self.server.start(MetadataProxyHandler(self.conf, self.chassis),
self.conf.metadata_proxy_socket,
workers=md_workers,
backlog=self.conf.metadata_backlog,


+ 18
- 9
neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/impl_idl_ovn.py View File

@ -827,15 +827,24 @@ class OvsdbSbOvnIdl(sb_impl_idl.OvnSbApiIdlImpl, Backend):
rows = self.db_list_rows('Port_Binding').execute(check_error=True)
# TODO(twilson) It would be useful to have a db_find that takes a
# comparison function
# TODO(dalvarez): Remove the comparison to r.datapath.uuid in Y cycle
# when we are sure that all namespaces will be created with the
# Neutron network UUID and not anymore with the OVN datapath UUID.
return [r for r in rows
if (r.mac and (
str(r.datapath.uuid) == network or
utils.get_network_name_from_datapath(
r.datapath) == network)) and
ip_address in r.mac[0].split(' ')]
def check_net_and_ip(port):
# If the port is not bound to any chassis it is not relevant
if not port.chassis:
return False
# TODO(dalvarez): Remove the comparison to port.datapath.uuid in Y
# cycle when we are sure that all namespaces will be created with
# the Neutron network UUID and not anymore with the OVN datapath
# UUID.
is_in_network = lambda port: (
str(port.datapath.uuid) == network or
utils.get_network_name_from_datapath(port.datapath) == network)
return port.mac and is_in_network(port) and (
ip_address in port.mac[0].split(' '))
return [r for r in rows if check_net_and_ip(r)]
def set_port_cidrs(self, name, cidrs):
# TODO(twilson) add if_exists to db commands


+ 10
- 8
neutron/tests/unit/agent/ovn/metadata/test_server.py View File

@ -27,7 +27,8 @@ from neutron.conf.agent.metadata import config as meta_conf
from neutron.conf.agent.ovn.metadata import config as ovn_meta_conf
from neutron.tests import base
OvnPortInfo = collections.namedtuple('OvnPortInfo', 'external_ids')
OvnPortInfo = collections.namedtuple(
'OvnPortInfo', ['external_ids', 'chassis'])
class ConfFixture(config_fixture.Config):
@ -54,7 +55,7 @@ class TestMetadataProxyHandler(base.BaseTestCase):
self.useFixture(self.fake_conf_fixture)
self.log_p = mock.patch.object(agent, 'LOG')
self.log = self.log_p.start()
self.handler = agent.MetadataProxyHandler(self.fake_conf)
self.handler = agent.MetadataProxyHandler(self.fake_conf, 'chassis1')
self.handler.sb_idl = mock.Mock()
def test_call(self):
@ -113,7 +114,8 @@ class TestMetadataProxyHandler(base.BaseTestCase):
ovn_port = OvnPortInfo(
external_ids={'neutron:device_id': 'device_id',
'neutron:project_id': 'project_id'})
'neutron:project_id': 'project_id'},
chassis=['chassis1'])
ports = [[ovn_port]]
self.assertEqual(
@ -220,14 +222,14 @@ class TestUnixDomainMetadataProxy(base.BaseTestCase):
@mock.patch.object(fileutils, 'ensure_tree')
def test_init_doesnot_exists(self, ensure_dir):
agent.UnixDomainMetadataProxy(mock.Mock())
agent.UnixDomainMetadataProxy(mock.Mock(), 'chassis1')
ensure_dir.assert_called_once_with('/the', mode=0o755)
def test_init_exists(self):
with mock.patch('os.path.isdir') as isdir:
with mock.patch('os.unlink') as unlink:
isdir.return_value = True
agent.UnixDomainMetadataProxy(mock.Mock())
agent.UnixDomainMetadataProxy(mock.Mock(), 'chassis1')
unlink.assert_called_once_with('/the/path')
def test_init_exists_unlink_no_file(self):
@ -238,7 +240,7 @@ class TestUnixDomainMetadataProxy(base.BaseTestCase):
exists.return_value = False
unlink.side_effect = OSError
agent.UnixDomainMetadataProxy(mock.Mock())
agent.UnixDomainMetadataProxy(mock.Mock(), 'chassis1')
unlink.assert_called_once_with('/the/path')
def test_init_exists_unlink_fails_file_still_exists(self):
@ -250,14 +252,14 @@ class TestUnixDomainMetadataProxy(base.BaseTestCase):
unlink.side_effect = OSError
with testtools.ExpectedException(OSError):
agent.UnixDomainMetadataProxy(mock.Mock())
agent.UnixDomainMetadataProxy(mock.Mock(), 'chassis1')
unlink.assert_called_once_with('/the/path')
@mock.patch.object(agent, 'MetadataProxyHandler')
@mock.patch.object(agent_utils, 'UnixDomainWSGIServer')
@mock.patch.object(fileutils, 'ensure_tree')
def test_run(self, ensure_dir, server, handler):
p = agent.UnixDomainMetadataProxy(self.cfg.CONF)
p = agent.UnixDomainMetadataProxy(self.cfg.CONF, 'chassis1')
p.run()
ensure_dir.assert_called_once_with('/the', mode=0o755)


Loading…
Cancel
Save