--- /dev/null
+#!/usr/bin/env python
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright (c) 2012 Openstack, LLC.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import os
+import sys
+sys.path.insert(0, os.getcwd())
+
+from quantum.agent.ovs_cleanup_util import main
+
+
+main()
LOG.info(_("Unable to parse regex results. Exception: %s"), e)
return
+ def delete_ports(self, all_ports=False):
+ if all_ports:
+ port_names = self.get_port_name_list()
+ else:
+ port_names = (port.port_name for port in self.get_vif_ports())
+
+ for port_name in port_names:
+ self.delete_port(port_name)
+
def get_bridge_for_iface(root_helper, iface):
args = ["ovs-vsctl", "--timeout=2", "iface-to-br", iface]
except Exception, e:
LOG.error(_("iface %s not found. Exception: %s"), iface, e)
return None
+
+
+def get_bridges(root_helper):
+ args = ["ovs-vsctl", "--timeout=2", "list-br"]
+ try:
+ return utils.execute(args, root_helper=root_helper).strip().split("\n")
+ except Exception, e:
+ LOG.error(_("Unable to retrieve bridges. Exception: %s"), e)
+ return []
--- /dev/null
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright (c) 2012 OpenStack LLC.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import sys
+
+from quantum.agent import l3_agent
+from quantum.agent.linux import interface
+from quantum.agent.linux import ovs_lib
+from quantum.common import config
+from quantum.openstack.common import cfg
+from quantum.openstack.common import log as logging
+
+
+LOG = logging.getLogger(__name__)
+
+
+def setup_conf():
+ """Setup the cfg for the clean up utility.
+
+ Use separate setup_conf for the utility because there are many options
+ from the main config that do not apply during clean-up.
+ """
+ opts = [
+ cfg.BoolOpt('ovs_all_ports',
+ default=False,
+ help='True deletes all ports on the bridge. False deletes '
+ 'those created by Quantum.'),
+ ]
+
+ conf = cfg.CommonConfigOpts()
+ conf.register_opts(opts)
+ conf.register_opts(l3_agent.L3NATAgent.OPTS)
+ conf.register_opts(interface.OPTS)
+ config.setup_logging(conf)
+ return conf
+
+
+def main():
+ """Main method for cleaning up OVS bridges.
+
+ The utility cleans up the integration bridges used by Quantum.
+ """
+
+ conf = setup_conf()
+ conf(sys.argv)
+
+ configuration_bridges = set([conf.ovs_integration_bridge,
+ conf.external_network_bridge])
+ ovs_bridges = set(ovs_lib.get_bridges(conf.root_helper))
+
+ if conf.ovs_all_ports:
+ bridges = ovs_bridges
+ else:
+ bridges = configuration_bridges & ovs_bridges
+
+ for bridge in bridges:
+ LOG.info(_("Cleaning %s"), bridge)
+ ovs = ovs_lib.OVSBridge(bridge, conf.root_helper)
+ ovs.delete_ports(all_ports=conf.ovs_all_ports)
+
+ LOG.info(_("OVS cleanup completed successfully"))
self.mox.ReplayAll()
self.assertIsNone(ovs_lib.get_bridge_for_iface(root_helper, iface))
self.mox.VerifyAll()
+
+ def test_delete_all_ports(self):
+ self.mox.StubOutWithMock(self.br, 'get_port_name_list')
+ self.br.get_port_name_list().AndReturn(['port1'])
+ self.mox.StubOutWithMock(self.br, 'delete_port')
+ self.br.delete_port('port1')
+ self.mox.ReplayAll()
+ self.br.delete_ports(all_ports=True)
+ self.mox.VerifyAll()
+
+ def test_delete_quantum_ports(self):
+ port1 = ovs_lib.VifPort('tap1234', 1, uuidutils.generate_uuid(),
+ 'ca:fe:de:ad:be:ef', 'br')
+ port2 = ovs_lib.VifPort('tap5678', 2, uuidutils.generate_uuid(),
+ 'ca:ee:de:ad:be:ef', 'br')
+ ports = [port1, port2]
+ self.mox.StubOutWithMock(self.br, 'get_vif_ports')
+ self.br.get_vif_ports().AndReturn([port1, port2])
+ self.mox.StubOutWithMock(self.br, 'delete_port')
+ self.br.delete_port('tap1234')
+ self.br.delete_port('tap5678')
+ self.mox.ReplayAll()
+ self.br.delete_ports(all_ports=False)
+ self.mox.VerifyAll()
+
+ def test_get_bridges(self):
+ bridges = ['br-int', 'br-ex']
+ root_helper = 'sudo'
+ utils.execute(["ovs-vsctl", self.TO, "list-br"],
+ root_helper=root_helper).AndReturn('br-int\nbr-ex\n')
+
+ self.mox.ReplayAll()
+ self.assertEqual(ovs_lib.get_bridges(root_helper), bridges)
+ self.mox.VerifyAll()
--- /dev/null
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright (c) 2012 OpenStack LLC.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import mock
+import unittest2 as unittest
+
+from quantum.agent.linux import ovs_lib
+from quantum.agent import ovs_cleanup_util as util
+from quantum.openstack.common import uuidutils
+
+
+class TestOVSCleanup(unittest.TestCase):
+ def test_setup_conf(self):
+ with mock.patch('quantum.common.config.setup_logging'):
+ conf = util.setup_conf()
+ self.assertEqual(conf.external_network_bridge, 'br-ex')
+ self.assertEqual(conf.ovs_integration_bridge, 'br-int')
+ self.assertFalse(conf.ovs_all_ports)
+
+ def test_main(self):
+ with mock.patch('quantum.common.config.setup_logging'):
+ br_patch = mock.patch('quantum.agent.linux.ovs_lib.get_bridges')
+ with br_patch as mock_get_bridges:
+ mock_get_bridges.return_value = ['br-int', 'br-ex']
+ with mock.patch(
+ 'quantum.agent.linux.ovs_lib.OVSBridge') as ovs:
+ util.main()
+ ovs.assert_has_calls([mock.call().delete_ports(
+ all_ports=False)])
'quantum.plugins.nec.agent.nec_quantum_agent:main',
'quantum-server = quantum.server:main',
'quantum-debug = quantum.debug.shell:main',
+ 'quantum-ovs-cleanup = quantum.agent.ovs_cleanup_util:main',
]
},
)