Merge "Adds an option to skip ports on ovs_cleanup"

This commit is contained in:
Jenkins 2017-05-17 09:15:33 +00:00 committed by Gerrit Code Review
commit e69112141d
6 changed files with 59 additions and 11 deletions

View File

@ -307,19 +307,29 @@ class OVSBridge(BaseOVS):
self.run_ofctl("del-flows", [])
@_ovsdb_retry
def _get_port_ofport(self, port_name):
return self.db_get_val("Interface", port_name, "ofport")
def _get_port_val(self, port_name, port_val):
return self.db_get_val("Interface", port_name, port_val)
def get_port_ofport(self, port_name):
"""Get the port's assigned ofport, retrying if not yet assigned."""
ofport = INVALID_OFPORT
try:
ofport = self._get_port_ofport(port_name)
ofport = self._get_port_val(port_name, "ofport")
except tenacity.RetryError:
LOG.exception(_LE("Timed out retrieving ofport on port %s."),
port_name)
return ofport
def get_port_external_ids(self, port_name):
"""Get the port's assigned ofport, retrying if not yet assigned."""
port_external_ids = dict()
try:
port_external_ids = self._get_port_val(port_name, "external_ids")
except tenacity.RetryError:
LOG.exception(_LE("Timed out retrieving external_ids on port %s."),
port_name)
return port_external_ids
def get_port_mac(self, port_name):
"""Get the port's mac address.

View File

@ -24,6 +24,7 @@ from neutron.common import config
from neutron.conf.agent import cmd
from neutron.conf.agent import common as agent_config
from neutron.conf.agent.l3 import config as l3_config
from neutron.plugins.ml2.drivers.openvswitch.agent.common import constants
LOG = logging.getLogger(__name__)
@ -44,12 +45,22 @@ def setup_conf():
return conf
def get_bridge_deletable_ports(br):
"""
Return a list of OVS Bridge ports, excluding the ports who should not be
cleaned. such ports are tagged with the 'skip_cleanup' key in external_ids.
"""
return [port.port_name for port in br.get_vif_ports()
if constants.SKIP_CLEANUP not in
br.get_port_external_ids(port.port_name)]
def collect_neutron_ports(bridges):
"""Collect ports created by Neutron from OVS."""
ports = []
for bridge in bridges:
ovs = ovs_lib.OVSBridge(bridge)
ports += [port.port_name for port in ovs.get_vif_ports()]
ports += get_bridge_deletable_ports(ovs)
return ports
@ -94,7 +105,12 @@ def main():
for bridge in bridges:
LOG.info(_LI("Cleaning bridge: %s"), bridge)
ovs = ovs_lib.OVSBridge(bridge)
ovs.delete_ports(all_ports=conf.ovs_all_ports)
if conf.ovs_all_ports:
port_names = ovs.get_port_name_list()
else:
port_names = get_bridge_deletable_ports(ovs)
for port_name in port_names:
ovs.delete_port(port_name)
# Remove remaining ports created by Neutron (usually veth pair)
delete_neutron_ports(ports)

View File

@ -149,3 +149,7 @@ OVS_BRIDGE_NAME = 'ovs_bridge_name'
# callback resource for notifying to ovsdb handler
OVSDB_RESOURCE = 'ovsdb'
# Used in ovs port 'external_ids' in order mark it for no cleanup when
# ovs_cleanup script is used.
SKIP_CLEANUP = 'skip_cleanup'

View File

@ -124,7 +124,7 @@ class OVSAgentQoSExtensionTestFramework(base.OVSAgentTestFramework):
self.agent.int_br, port['vif_name'], rule)
def _assert_dscp_marking_rule_is_set(self, port, dscp_rule):
port_num = self.agent.int_br._get_port_ofport(port['vif_name'])
port_num = self.agent.int_br._get_port_val(port['vif_name'], 'ofport')
flows = self.agent.int_br.dump_flows_for(table='0',
in_port=str(port_num))
@ -132,7 +132,7 @@ class OVSAgentQoSExtensionTestFramework(base.OVSAgentTestFramework):
self.assertEqual(dscp_rule.dscp_mark << 2, tos_mark)
def _assert_dscp_marking_rule_not_set(self, port):
port_num = self.agent.int_br._get_port_ofport(port['vif_name'])
port_num = self.agent.int_br._get_port_val(port['vif_name'], 'ofport')
flows = self.agent.int_br.dump_flows_for(table='0',
in_port=str(port_num))

View File

@ -875,7 +875,7 @@ class OVS_Lib_Test(base.BaseTestCase):
with mock.patch.object(
self.br, 'db_get_val',
side_effect=[[], [], [], [], 1]):
self.assertEqual(1, self.br._get_port_ofport('1'))
self.assertEqual(1, self.br._get_port_val('1', 'ofport'))
def test_get_port_ofport_retry_fails(self):
# reduce timeout for faster execution
@ -885,7 +885,27 @@ class OVS_Lib_Test(base.BaseTestCase):
self.br, 'db_get_val',
side_effect=[[] for _ in range(7)]):
self.assertRaises(tenacity.RetryError,
self.br._get_port_ofport, '1')
self.br._get_port_val, '1', 'ofport')
def test_get_port_external_ids_retry(self):
external_ids = [["iface-id", "tap99id"],
["iface-status", "active"],
["attached-mac", "de:ad:be:ef:13:37"]]
with mock.patch.object(
self.br, 'db_get_val',
side_effect=[[], [], [], [], external_ids]):
self.assertEqual(external_ids,
self.br._get_port_val('1', 'external_ids'))
def test_get_port_external_ids_retry_fails(self):
# reduce timeout for faster execution
self.br.vsctl_timeout = 1
# after 7 calls the retry will timeout and raise
with mock.patch.object(
self.br, 'db_get_val',
side_effect=[[] for _ in range(7)]):
self.assertRaises(tenacity.RetryError,
self.br._get_port_val, '1', 'external_ids')
class TestDeferredOVSBridge(base.BaseTestCase):

View File

@ -46,8 +46,6 @@ class TestOVSCleanup(base.BaseTestCase):
mock_collect.return_value = ports
util.main()
mock_ovs.assert_has_calls([mock.call().delete_ports(
all_ports=False)])
mock_collect.assert_called_once_with(set(bridges))
mock_delete.assert_called_once_with(ports)