New RPC to set HA network port status to DOWN

In commit 500b255278 we are using
"get_router_ids" RPC to update HA network port status. But that
was needed to backport that commit to other branches.
As "get_router_ids" RPC is expected to fetch only router ids and
not to have any other processing, we are adding new RPC
"update_ha_network_port_status". L3 agent will call this new RPC
to set HA network port status to DOWN.

Related-bug: #1597461
Change-Id: I8f34c4f5178d2b422cfcfd082dfc9cf3f89a5d95
This commit is contained in:
venkata anil 2017-07-05 16:35:37 +03:00
parent df762b0d46
commit 9647d68fdb
3 changed files with 41 additions and 27 deletions

View File

@ -90,6 +90,7 @@ class L3PluginApi(object):
- delete_agent_gateway_port
1.8 - Added address scope information
1.9 - Added get_router_ids
1.10 Added update_all_ha_network_port_statuses
"""
def __init__(self, topic, host):
@ -103,6 +104,12 @@ class L3PluginApi(object):
return cctxt.call(context, 'sync_routers', host=self.host,
router_ids=router_ids)
def update_all_ha_network_port_statuses(self, context):
"""Make a remote process call to update HA network port status."""
cctxt = self.client.prepare(version='1.10')
return cctxt.call(context, 'update_all_ha_network_port_statuses',
host=self.host)
def get_router_ids(self, context):
"""Make a remote process call to retrieve scheduled routers ids."""
cctxt = self.client.prepare(version='1.9')
@ -569,6 +576,10 @@ class L3NATAgent(ha.AgentMixin,
lib_const.L3_AGENT_MODE_DVR)
try:
router_ids = self.plugin_rpc.get_router_ids(context)
# We set HA network port status to DOWN to let l2 agent update it
# to ACTIVE after wiring. This allows us to spawn keepalived only
# when l2 agent finished wiring the port.
self.plugin_rpc.update_all_ha_network_port_statuses(context)
# fetch routers by chunks to reduce the load on server and to
# start router processing earlier
for i in range(0, len(router_ids), self.sync_routers_chunk_size):

View File

@ -46,7 +46,8 @@ class L3RpcCallback(object):
# 1.7 Added method delete_agent_gateway_port for DVR Routers
# 1.8 Added address scope information
# 1.9 Added get_router_ids
target = oslo_messaging.Target(version='1.9')
# 1.10 Added update_all_ha_network_port_statuses
target = oslo_messaging.Target(version='1.10')
@property
def plugin(self):
@ -60,29 +61,10 @@ class L3RpcCallback(object):
self._l3plugin = directory.get_plugin(plugin_constants.L3)
return self._l3plugin
def _update_ha_network_port_status(self, context, host_id):
# set HA network port status to DOWN.
device_filter = {
'device_owner': [constants.DEVICE_OWNER_ROUTER_HA_INTF],
'status': [constants.PORT_STATUS_ACTIVE]}
ports = self.plugin.get_ports(context, filters=device_filter)
ha_ports = [p['id'] for p in ports
if p.get(portbindings.HOST_ID) == host_id]
if not ha_ports:
return
LOG.debug("L3 agent on host %(host)s requested for fullsync, so "
"setting HA network ports %(ha_ports)s status to DOWN.",
{"host": host_id, "ha_ports": ha_ports})
for p in ha_ports:
self.plugin.update_port(
context, p, {'port': {'status': constants.PORT_STATUS_DOWN}})
def update_all_ha_network_port_statuses(self, context, host):
"""Set HA network port to DOWN for HA routers hosted on <host>
def get_router_ids(self, context, host):
"""Returns IDs of routers scheduled to l3 agent on <host>
This will autoschedule unhosted routers to l3 agent on <host> and then
return all ids of routers scheduled to it.
This will also update HA network port status to down for all HA routers
This will update HA network port status to down for all HA routers
hosted on <host>. This is needed to avoid l3 agent spawning keepalived
when l2 agent not yet wired the port. This can happen after a system
reboot that has wiped out flows, etc and the L2 agent hasn't started up
@ -92,9 +74,30 @@ class L3RpcCallback(object):
that the port is indeed ACTIVE by reacting to the port update and
calling update_device_up.
"""
if utils.is_extension_supported(
if not utils.is_extension_supported(
self.plugin, constants.PORT_BINDING_EXT_ALIAS):
self._update_ha_network_port_status(context, host)
return
device_filter = {
'device_owner': [constants.DEVICE_OWNER_ROUTER_HA_INTF],
'status': [constants.PORT_STATUS_ACTIVE]}
ports = self.plugin.get_ports(context, filters=device_filter)
ha_ports = [p['id'] for p in ports
if p.get(portbindings.HOST_ID) == host]
if not ha_ports:
return
LOG.debug("L3 agent on host %(host)s requested for fullsync, so "
"setting HA network ports %(ha_ports)s status to DOWN.",
{"host": host, "ha_ports": ha_ports})
for p in ha_ports:
self.plugin.update_port(
context, p, {'port': {'status': constants.PORT_STATUS_DOWN}})
def get_router_ids(self, context, host):
"""Returns IDs of routers scheduled to l3 agent on <host>
This will autoschedule unhosted routers to l3 agent on <host> and then
return all ids of routers scheduled to it.
"""
if utils.is_extension_supported(
self.l3plugin, constants.L3_AGENT_SCHEDULER_EXT_ALIAS):
if cfg.CONF.router_auto_schedule:

View File

@ -1044,7 +1044,7 @@ class L3HAModeDbTestCase(L3HATestFramework):
for port in self._get_router_port_bindings(router['id']):
self.assertEqual(self.agent2['host'], port[portbindings.HOST_ID])
def test_get_router_ids_updates_ha_network_port_status(self):
def test_update_all_ha_network_port_statuses(self):
router = self._create_router(ha=True)
callback = l3_rpc.L3RpcCallback()
callback._l3plugin = self.plugin
@ -1071,7 +1071,7 @@ class L3HAModeDbTestCase(L3HATestFramework):
ctx, port['id'], constants.PORT_STATUS_ACTIVE, host=host)
port = self.core_plugin.get_port(ctx, port['id'])
self.assertEqual(constants.PORT_STATUS_ACTIVE, port['status'])
callback.get_router_ids(ctx, host)
callback.update_all_ha_network_port_statuses(ctx, host)
port = self.core_plugin.get_port(ctx, port['id'])
self.assertEqual(constants.PORT_STATUS_DOWN, port['status'])