Files
neutron/neutron/cmd/ovs_cleanup.py
T
Sławek Kapłoński 806d96cbbe Override ovsdb_timeout default value in ovs_cleanup tool
In case when there is a lot of ports to clean in bridge, default
ovsdb_timeout which is set for 10 seconds is not enough.
This patch overrides default 10 seconds timeout in neutron-ovs-cleanup
tool to 600 seconds.
600 seconds value was tested experimentally on my dev environment for
at least 10000 ports in bridge.

In case when user will have more ports to delete with this script,
it will be required to increase this ovsdb_timeout value in
configuration.

Change-Id: I79a554acdb1d6d61903be0c42d0215d302884e93
Closes-Bug: #1763604
2018-04-17 19:36:41 +00:00

130 lines
4.4 KiB
Python

# Copyright (c) 2012 OpenStack Foundation.
# 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.
from oslo_config import cfg
from oslo_log import log as logging
from neutron.agent.common import ovs_lib
from neutron.agent.linux import ip_lib
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__)
# Default ovsdb_timeout value for this script.
# It allows to clean bridges with even thousands of ports.
CLEANUP_OVSDB_TIMEOUT = 600
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.
"""
conf = cfg.CONF
cmd.register_cmd_opts(cmd.ovs_opts, conf)
l3_config.register_l3_agent_config_opts(l3_config.OPTS, conf)
agent_config.register_interface_driver_opts_helper(conf)
agent_config.register_interface_opts()
conf.set_default("ovsdb_timeout", CLEANUP_OVSDB_TIMEOUT, "OVS")
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 += get_bridge_deletable_ports(ovs)
return ports
def delete_neutron_ports(ports):
"""Delete non-internal ports created by Neutron
Non-internal OVS ports need to be removed manually.
"""
for port in ports:
device = ip_lib.IPDevice(port)
if device.exists():
device.link.delete()
LOG.info("Deleting port: %s", port)
def main():
"""Main method for cleaning up OVS bridges.
The utility cleans up the integration bridges used by Neutron.
"""
conf = setup_conf()
conf()
config.setup_logging()
do_main(conf)
def do_main(conf):
configuration_bridges = set([conf.ovs_integration_bridge,
conf.external_network_bridge])
ovs = ovs_lib.BaseOVS()
ovs_bridges = set(ovs.get_bridges())
available_configuration_bridges = configuration_bridges & ovs_bridges
if conf.ovs_all_ports:
bridges = ovs_bridges
else:
bridges = available_configuration_bridges
try:
# The ovs_cleanup method not added to the deprecated vsctl backend
for bridge in bridges:
LOG.info("Cleaning bridge: %s", bridge)
ovs.ovsdb.ovs_cleanup(bridge,
conf.ovs_all_ports).execute(check_error=True)
except AttributeError:
# Collect existing ports created by Neutron on configuration bridges.
# After deleting ports from OVS bridges, we cannot determine which
# ports were created by Neutron, so port information is collected now.
ports = collect_neutron_ports(available_configuration_bridges)
for bridge in bridges:
LOG.info("Cleaning bridge: %s", bridge)
ovs = ovs_lib.OVSBridge(bridge)
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)
LOG.info("OVS cleanup completed successfully")