Merge "Remove run-time version checking for openvswitch features"
This commit is contained in:
commit
e100f3a9a1
@ -13,10 +13,6 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import distutils.version as dist_version
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
|
|
||||||
from oslo.config import cfg
|
from oslo.config import cfg
|
||||||
|
|
||||||
from neutron.agent.linux import ip_lib
|
from neutron.agent.linux import ip_lib
|
||||||
@ -176,7 +172,14 @@ class OVSBridge(BaseOVS):
|
|||||||
self.run_ofctl("del-flows", [])
|
self.run_ofctl("del-flows", [])
|
||||||
|
|
||||||
def get_port_ofport(self, port_name):
|
def get_port_ofport(self, port_name):
|
||||||
return self.db_get_val("Interface", port_name, "ofport")
|
ofport = self.db_get_val("Interface", port_name, "ofport")
|
||||||
|
# This can return a non-integer string, like '[]' so ensure a
|
||||||
|
# common failure case
|
||||||
|
try:
|
||||||
|
int(ofport)
|
||||||
|
return ofport
|
||||||
|
except ValueError:
|
||||||
|
return constants.INVALID_OFPORT
|
||||||
|
|
||||||
def get_datapath_id(self):
|
def get_datapath_id(self):
|
||||||
return self.db_get_val('Bridge',
|
return self.db_get_val('Bridge',
|
||||||
@ -250,7 +253,13 @@ class OVSBridge(BaseOVS):
|
|||||||
"options:in_key=flow",
|
"options:in_key=flow",
|
||||||
"options:out_key=flow"])
|
"options:out_key=flow"])
|
||||||
self.run_vsctl(vsctl_command)
|
self.run_vsctl(vsctl_command)
|
||||||
return self.get_port_ofport(port_name)
|
ofport = self.get_port_ofport(port_name)
|
||||||
|
if (tunnel_type == p_const.TYPE_VXLAN and
|
||||||
|
ofport == constants.INVALID_OFPORT):
|
||||||
|
LOG.error(_('Unable to create VXLAN tunnel port. Please ensure '
|
||||||
|
'that an openvswitch version that supports VXLAN is '
|
||||||
|
'installed.'))
|
||||||
|
return ofport
|
||||||
|
|
||||||
def add_patch_port(self, local_name, remote_name):
|
def add_patch_port(self, local_name, remote_name):
|
||||||
self.run_vsctl(["add-port", self.br_name, local_name,
|
self.run_vsctl(["add-port", self.br_name, local_name,
|
||||||
@ -453,6 +462,13 @@ class OVSBridge(BaseOVS):
|
|||||||
msg = _('Unable to determine mac address for %s') % self.br_name
|
msg = _('Unable to determine mac address for %s') % self.br_name
|
||||||
raise Exception(msg)
|
raise Exception(msg)
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
self.create()
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, exc_type, exc_value, exc_tb):
|
||||||
|
self.destroy()
|
||||||
|
|
||||||
|
|
||||||
def get_bridge_for_iface(root_helper, iface):
|
def get_bridge_for_iface(root_helper, iface):
|
||||||
args = ["ovs-vsctl", "--timeout=%d" % cfg.CONF.ovs_vsctl_timeout,
|
args = ["ovs-vsctl", "--timeout=%d" % cfg.CONF.ovs_vsctl_timeout,
|
||||||
@ -474,35 +490,6 @@ def get_bridges(root_helper):
|
|||||||
LOG.exception(_("Unable to retrieve bridges. Exception: %s"), e)
|
LOG.exception(_("Unable to retrieve bridges. Exception: %s"), e)
|
||||||
|
|
||||||
|
|
||||||
def get_installed_ovs_usr_version(root_helper):
|
|
||||||
args = ["ovs-vsctl", "--version"]
|
|
||||||
try:
|
|
||||||
cmd = utils.execute(args, root_helper=root_helper)
|
|
||||||
ver = re.findall("\d+\.\d+", cmd)[0]
|
|
||||||
return ver
|
|
||||||
except Exception:
|
|
||||||
LOG.exception(_("Unable to retrieve OVS userspace version."))
|
|
||||||
|
|
||||||
|
|
||||||
def get_installed_ovs_klm_version():
|
|
||||||
args = ["modinfo", "openvswitch"]
|
|
||||||
try:
|
|
||||||
cmd = utils.execute(args)
|
|
||||||
for line in cmd.split('\n'):
|
|
||||||
if 'version: ' in line and not 'srcversion' in line:
|
|
||||||
ver = re.findall("\d+\.\d+", line)
|
|
||||||
return ver[0]
|
|
||||||
except Exception:
|
|
||||||
LOG.exception(_("Unable to retrieve OVS kernel module version."))
|
|
||||||
|
|
||||||
|
|
||||||
def get_installed_kernel_version():
|
|
||||||
try:
|
|
||||||
return os.uname()[2].split('-', 1)[0]
|
|
||||||
except IndexError:
|
|
||||||
LOG.exception(_("Unable to retrieve installed Linux kernel version."))
|
|
||||||
|
|
||||||
|
|
||||||
def get_bridge_external_bridge_id(root_helper, bridge):
|
def get_bridge_external_bridge_id(root_helper, bridge):
|
||||||
args = ["ovs-vsctl", "--timeout=2", "br-get-external-id",
|
args = ["ovs-vsctl", "--timeout=2", "br-get-external-id",
|
||||||
bridge, "bridge-id"]
|
bridge, "bridge-id"]
|
||||||
@ -513,57 +500,6 @@ def get_bridge_external_bridge_id(root_helper, bridge):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def _compare_installed_and_required_version(
|
|
||||||
installed_kernel_version, installed_version, required_version,
|
|
||||||
check_type, version_type):
|
|
||||||
if installed_kernel_version:
|
|
||||||
if dist_version.StrictVersion(
|
|
||||||
installed_kernel_version) >= dist_version.StrictVersion(
|
|
||||||
constants.MINIMUM_LINUX_KERNEL_OVS_VXLAN):
|
|
||||||
return
|
|
||||||
if installed_version:
|
|
||||||
if dist_version.StrictVersion(
|
|
||||||
installed_version) < dist_version.StrictVersion(
|
|
||||||
required_version):
|
|
||||||
msg = (_('Failed %(ctype)s version check for Open '
|
|
||||||
'vSwitch with %(vtype)s support. To use '
|
|
||||||
'%(vtype)s tunnels with OVS, please ensure '
|
|
||||||
'the OVS version is %(required)s or newer!') %
|
|
||||||
{'ctype': check_type, 'vtype': version_type,
|
|
||||||
'required': required_version})
|
|
||||||
raise SystemError(msg)
|
|
||||||
else:
|
|
||||||
msg = (_('Unable to determine %(ctype)s version for Open '
|
|
||||||
'vSwitch with %(vtype)s support. To use '
|
|
||||||
'%(vtype)s tunnels with OVS, please ensure '
|
|
||||||
'that the version is %(required)s or newer!') %
|
|
||||||
{'ctype': check_type, 'vtype': version_type,
|
|
||||||
'required': required_version})
|
|
||||||
raise SystemError(msg)
|
|
||||||
|
|
||||||
|
|
||||||
def check_ovs_vxlan_version(root_helper):
|
|
||||||
min_required_version = constants.MINIMUM_OVS_VXLAN_VERSION
|
|
||||||
installed_klm_version = get_installed_ovs_klm_version()
|
|
||||||
installed_kernel_version = get_installed_kernel_version()
|
|
||||||
installed_usr_version = get_installed_ovs_usr_version(root_helper)
|
|
||||||
LOG.debug(_("Checking OVS version for VXLAN support "
|
|
||||||
"installed klm version is %(klm)s, installed Linux version is "
|
|
||||||
"%(kernel)s, installed user version is %(usr)s ") %
|
|
||||||
{'klm': installed_klm_version,
|
|
||||||
'kernel': installed_kernel_version,
|
|
||||||
'usr': installed_usr_version})
|
|
||||||
# First check the userspace version
|
|
||||||
_compare_installed_and_required_version(None, installed_usr_version,
|
|
||||||
min_required_version,
|
|
||||||
'userspace', 'VXLAN')
|
|
||||||
# Now check the kernel version
|
|
||||||
_compare_installed_and_required_version(installed_kernel_version,
|
|
||||||
installed_klm_version,
|
|
||||||
min_required_version,
|
|
||||||
'kernel', 'VXLAN')
|
|
||||||
|
|
||||||
|
|
||||||
def _build_flow_expr_str(flow_dict, cmd):
|
def _build_flow_expr_str(flow_dict, cmd):
|
||||||
flow_expr_arr = []
|
flow_expr_arr = []
|
||||||
actions = None
|
actions = None
|
||||||
|
0
neutron/cmd/sanity/__init__.py
Normal file
0
neutron/cmd/sanity/__init__.py
Normal file
28
neutron/cmd/sanity/checks.py
Normal file
28
neutron/cmd/sanity/checks.py
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
# Copyright (c) 2014 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 neutron.agent.linux import ovs_lib
|
||||||
|
from neutron.common import utils
|
||||||
|
from neutron.plugins.common import constants as const
|
||||||
|
from neutron.plugins.openvswitch.common import constants as ovs_const
|
||||||
|
|
||||||
|
|
||||||
|
def vxlan_supported(root_helper, from_ip='192.0.2.1', to_ip='192.0.2.2'):
|
||||||
|
name = "vxlantest-" + utils.get_random_string(6)
|
||||||
|
with ovs_lib.OVSBridge(name, root_helper) as br:
|
||||||
|
port = br.add_tunnel_port(from_ip, to_ip, const.TYPE_VXLAN)
|
||||||
|
return port != ovs_const.INVALID_OFPORT
|
79
neutron/cmd/sanity_check.py
Normal file
79
neutron/cmd/sanity_check.py
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
# Copyright (c) 2014 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.
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from neutron.cmd.sanity import checks
|
||||||
|
from neutron.common import config
|
||||||
|
from neutron.openstack.common import log as logging
|
||||||
|
from oslo.config import cfg
|
||||||
|
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
cfg.CONF.import_group('AGENT', 'neutron.plugins.openvswitch.common.config')
|
||||||
|
|
||||||
|
|
||||||
|
class BoolOptCallback(cfg.BoolOpt):
|
||||||
|
def __init__(self, name, callback, **kwargs):
|
||||||
|
self.callback = callback
|
||||||
|
super(BoolOptCallback, self).__init__(name, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def check_ovs_vxlan():
|
||||||
|
result = checks.vxlan_supported(root_helper=cfg.CONF.AGENT.root_helper)
|
||||||
|
if not result:
|
||||||
|
LOG.error(_('Check for Open vSwitch VXLAN support failed. '
|
||||||
|
'Please ensure that the version of openvswitch '
|
||||||
|
'being used has VXLAN support.'))
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
# Define CLI opts to test specific features, with a calback for the test
|
||||||
|
OPTS = [
|
||||||
|
BoolOptCallback('ovs_vxlan', check_ovs_vxlan, default=False,
|
||||||
|
help=_('Check for vxlan support')),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def enable_tests_from_config():
|
||||||
|
"""If a test can depend on configuration, use this function to set the
|
||||||
|
appropriate CLI option to enable that test. It will then be possible to
|
||||||
|
run all necessary tests, just by passing in the appropriate configs.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if 'vxlan' in cfg.CONF.AGENT.tunnel_types:
|
||||||
|
cfg.CONF.set_override('ovs_vxlan', True)
|
||||||
|
|
||||||
|
|
||||||
|
def all_tests_passed():
|
||||||
|
res = True
|
||||||
|
for opt in OPTS:
|
||||||
|
if cfg.CONF.get(opt.name):
|
||||||
|
res &= opt.callback()
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
cfg.CONF.register_cli_opts(OPTS)
|
||||||
|
cfg.CONF.set_override('use_stderr', True)
|
||||||
|
config.setup_logging(cfg.CONF)
|
||||||
|
config.parse(sys.argv[1:], default_config_files=[])
|
||||||
|
|
||||||
|
if cfg.CONF.config_file:
|
||||||
|
enable_tests_from_config()
|
||||||
|
|
||||||
|
return 0 if all_tests_passed() else 1
|
@ -133,9 +133,10 @@ db_options.set_defaults(sql_connection=_SQL_CONNECTION_DEFAULT,
|
|||||||
max_overflow=20, pool_timeout=10)
|
max_overflow=20, pool_timeout=10)
|
||||||
|
|
||||||
|
|
||||||
def parse(args):
|
def parse(args, **kwargs):
|
||||||
cfg.CONF(args=args, project='neutron',
|
cfg.CONF(args=args, project='neutron',
|
||||||
version='%%prog %s' % version.version_info.release_string())
|
version='%%prog %s' % version.version_info.release_string(),
|
||||||
|
**kwargs)
|
||||||
|
|
||||||
# Validate that the base_mac is of the correct format
|
# Validate that the base_mac is of the correct format
|
||||||
msg = attributes._validate_regex(cfg.CONF.base_mac,
|
msg = attributes._validate_regex(cfg.CONF.base_mac,
|
||||||
|
@ -267,7 +267,6 @@ class OFANeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin):
|
|||||||
self.local_ip = local_ip
|
self.local_ip = local_ip
|
||||||
self.tunnel_count = 0
|
self.tunnel_count = 0
|
||||||
self.vxlan_udp_port = cfg.CONF.AGENT.vxlan_udp_port
|
self.vxlan_udp_port = cfg.CONF.AGENT.vxlan_udp_port
|
||||||
self._check_ovs_version()
|
|
||||||
if self.enable_tunneling:
|
if self.enable_tunneling:
|
||||||
self.setup_tunnel_br(tun_br)
|
self.setup_tunnel_br(tun_br)
|
||||||
# Collect additional bridges to monitor
|
# Collect additional bridges to monitor
|
||||||
@ -280,14 +279,6 @@ class OFANeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin):
|
|||||||
# Initialize iteration counter
|
# Initialize iteration counter
|
||||||
self.iter_num = 0
|
self.iter_num = 0
|
||||||
|
|
||||||
def _check_ovs_version(self):
|
|
||||||
if p_const.TYPE_VXLAN in self.tunnel_types:
|
|
||||||
try:
|
|
||||||
ovs_lib.check_ovs_vxlan_version(self.root_helper)
|
|
||||||
except SystemError:
|
|
||||||
LOG.exception(_("Agent terminated"))
|
|
||||||
raise SystemExit(1)
|
|
||||||
|
|
||||||
def _report_state(self):
|
def _report_state(self):
|
||||||
# How many devices are likely used by a VM
|
# How many devices are likely used by a VM
|
||||||
self.agent_state.get('configurations')['devices'] = (
|
self.agent_state.get('configurations')['devices'] = (
|
||||||
|
@ -223,7 +223,6 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
|
|||||||
self.local_ip = local_ip
|
self.local_ip = local_ip
|
||||||
self.tunnel_count = 0
|
self.tunnel_count = 0
|
||||||
self.vxlan_udp_port = cfg.CONF.AGENT.vxlan_udp_port
|
self.vxlan_udp_port = cfg.CONF.AGENT.vxlan_udp_port
|
||||||
self._check_ovs_version()
|
|
||||||
self.tun_br = None
|
self.tun_br = None
|
||||||
if self.enable_tunneling:
|
if self.enable_tunneling:
|
||||||
self.setup_tunnel_br(tun_br)
|
self.setup_tunnel_br(tun_br)
|
||||||
@ -237,14 +236,6 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
|
|||||||
# Initialize iteration counter
|
# Initialize iteration counter
|
||||||
self.iter_num = 0
|
self.iter_num = 0
|
||||||
|
|
||||||
def _check_ovs_version(self):
|
|
||||||
if p_const.TYPE_VXLAN in self.tunnel_types:
|
|
||||||
try:
|
|
||||||
ovs_lib.check_ovs_vxlan_version(self.root_helper)
|
|
||||||
except SystemError:
|
|
||||||
LOG.exception(_("Agent terminated"))
|
|
||||||
raise SystemExit(1)
|
|
||||||
|
|
||||||
def _check_arp_responder_support(self):
|
def _check_arp_responder_support(self):
|
||||||
'''Check if OVS supports to modify ARP headers.
|
'''Check if OVS supports to modify ARP headers.
|
||||||
|
|
||||||
|
@ -30,12 +30,6 @@ VXLAN_UDP_PORT = 4789
|
|||||||
VETH_INTEGRATION_PREFIX = 'int-'
|
VETH_INTEGRATION_PREFIX = 'int-'
|
||||||
VETH_PHYSICAL_PREFIX = 'phy-'
|
VETH_PHYSICAL_PREFIX = 'phy-'
|
||||||
|
|
||||||
# The minimum version of OVS which supports VXLAN tunneling
|
|
||||||
MINIMUM_OVS_VXLAN_VERSION = "1.10"
|
|
||||||
|
|
||||||
# The first version of the Linux kernel with converged VXLAN code for OVS
|
|
||||||
MINIMUM_LINUX_KERNEL_OVS_VXLAN = "3.13.0"
|
|
||||||
|
|
||||||
# The different types of tunnels
|
# The different types of tunnels
|
||||||
TUNNEL_NETWORK_TYPES = [p_const.TYPE_GRE, p_const.TYPE_VXLAN]
|
TUNNEL_NETWORK_TYPES = [p_const.TYPE_GRE, p_const.TYPE_VXLAN]
|
||||||
|
|
||||||
@ -55,3 +49,6 @@ TUN_TABLE = {p_const.TYPE_GRE: GRE_TUN_TO_LV,
|
|||||||
|
|
||||||
# The default respawn interval for the ovsdb monitor
|
# The default respawn interval for the ovsdb monitor
|
||||||
DEFAULT_OVSDBMON_RESPAWN = 30
|
DEFAULT_OVSDBMON_RESPAWN = 30
|
||||||
|
|
||||||
|
# Special return value for an invalid OVS ofport
|
||||||
|
INVALID_OFPORT = '-1'
|
||||||
|
@ -1,67 +0,0 @@
|
|||||||
# Copyright 2014 Cisco Systems, Inc.
|
|
||||||
#
|
|
||||||
# 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 neutron.agent.linux import ovs_lib
|
|
||||||
from neutron.plugins.common import constants as p_const
|
|
||||||
from neutron.tests.functional.agent.linux import base as base_agent
|
|
||||||
|
|
||||||
|
|
||||||
PORT_PREFIX = 'testp-'
|
|
||||||
INVALID_OFPORT_ID = '-1'
|
|
||||||
|
|
||||||
|
|
||||||
class TestOVSAgentVXLAN(base_agent.BaseOVSLinuxTestCase):
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(TestOVSAgentVXLAN, self).setUp()
|
|
||||||
|
|
||||||
self._check_test_requirements()
|
|
||||||
|
|
||||||
def _check_test_requirements(self):
|
|
||||||
self.check_sudo_enabled()
|
|
||||||
self.check_command(['which', 'ovs-vsctl'],
|
|
||||||
'Exit code: 1', 'ovs-vsctl is not installed')
|
|
||||||
self.check_command(['sudo', '-n', 'ovs-vsctl', 'show'],
|
|
||||||
'Exit code: 1',
|
|
||||||
'password-less sudo not granted for ovs-vsctl')
|
|
||||||
|
|
||||||
def test_ovs_lib_vxlan_version_check(self):
|
|
||||||
"""Verify VXLAN versions match
|
|
||||||
|
|
||||||
This function compares the return values of functionally checking if
|
|
||||||
VXLAN is supported with the ovs_lib programmatic check. It will fail
|
|
||||||
if the two do not align.
|
|
||||||
"""
|
|
||||||
expected = self.is_vxlan_supported()
|
|
||||||
actual = self.is_ovs_lib_vxlan_supported()
|
|
||||||
self.assertEqual(actual, expected)
|
|
||||||
|
|
||||||
def is_ovs_lib_vxlan_supported(self):
|
|
||||||
try:
|
|
||||||
ovs_lib.check_ovs_vxlan_version(self.root_helper)
|
|
||||||
except SystemError:
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
return True
|
|
||||||
|
|
||||||
def is_vxlan_supported(self):
|
|
||||||
bridge = self.create_ovs_bridge()
|
|
||||||
vxlan_port = self.create_resource(
|
|
||||||
PORT_PREFIX,
|
|
||||||
bridge.add_tunnel_port,
|
|
||||||
"10.10.10.10",
|
|
||||||
"10.10.10.20",
|
|
||||||
p_const.TYPE_VXLAN)
|
|
||||||
|
|
||||||
return vxlan_port != INVALID_OFPORT_ID
|
|
0
neutron/tests/functional/sanity/__init__.py
Normal file
0
neutron/tests/functional/sanity/__init__.py
Normal file
39
neutron/tests/functional/sanity/test_ovs_sanity.py
Normal file
39
neutron/tests/functional/sanity/test_ovs_sanity.py
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
# Copyright (c) 2014 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.
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from neutron.cmd.sanity import checks
|
||||||
|
from neutron.tests import base
|
||||||
|
|
||||||
|
|
||||||
|
class OVSSanityTestCase(base.BaseTestCase):
|
||||||
|
def setUp(self):
|
||||||
|
super(OVSSanityTestCase, self).setUp()
|
||||||
|
|
||||||
|
self.root_helper = 'sudo'
|
||||||
|
|
||||||
|
def check_sudo_enabled(self):
|
||||||
|
if os.environ.get('OS_SUDO_TESTING') not in base.TRUE_STRING:
|
||||||
|
self.skipTest('testing with sudo is not enabled')
|
||||||
|
|
||||||
|
def test_ovs_vxlan_support_runs(self):
|
||||||
|
"""This test just ensures that the test in neutron-sanity-check
|
||||||
|
can run through without error, without mocking anything out
|
||||||
|
"""
|
||||||
|
self.check_sudo_enabled()
|
||||||
|
checks.vxlan_supported(self.root_helper)
|
@ -22,7 +22,7 @@ from neutron.agent.linux import utils
|
|||||||
from neutron.common import exceptions
|
from neutron.common import exceptions
|
||||||
from neutron.openstack.common import jsonutils
|
from neutron.openstack.common import jsonutils
|
||||||
from neutron.openstack.common import uuidutils
|
from neutron.openstack.common import uuidutils
|
||||||
from neutron.plugins.openvswitch.common import constants
|
from neutron.plugins.openvswitch.common import constants as const
|
||||||
from neutron.tests import base
|
from neutron.tests import base
|
||||||
from neutron.tests import tools
|
from neutron.tests import tools
|
||||||
|
|
||||||
@ -321,6 +321,15 @@ class OVS_Lib_Test(base.BaseTestCase):
|
|||||||
["ovs-vsctl", self.TO, "get", "Interface", pname, "ofport"],
|
["ovs-vsctl", self.TO, "get", "Interface", pname, "ofport"],
|
||||||
root_helper=self.root_helper)
|
root_helper=self.root_helper)
|
||||||
|
|
||||||
|
def test_get_port_ofport_non_int(self):
|
||||||
|
pname = "tap99"
|
||||||
|
ofport = "[]"
|
||||||
|
self.execute.return_value = ofport
|
||||||
|
self.assertEqual(self.br.get_port_ofport(pname), const.INVALID_OFPORT)
|
||||||
|
self.execute.assert_called_once_with(
|
||||||
|
["ovs-vsctl", self.TO, "get", "Interface", pname, "ofport"],
|
||||||
|
root_helper=self.root_helper)
|
||||||
|
|
||||||
def test_get_datapath_id(self):
|
def test_get_datapath_id(self):
|
||||||
datapath_id = '"0000b67f4fbcc149"'
|
datapath_id = '"0000b67f4fbcc149"'
|
||||||
self.execute.return_value = datapath_id
|
self.execute.return_value = datapath_id
|
||||||
@ -882,68 +891,6 @@ class OVS_Lib_Test(base.BaseTestCase):
|
|||||||
self.assertIsNone(self._test_get_vif_port_by_id('tap99id', data,
|
self.assertIsNone(self._test_get_vif_port_by_id('tap99id', data,
|
||||||
"br-ext"))
|
"br-ext"))
|
||||||
|
|
||||||
def _check_ovs_vxlan_version(self, installed_usr_version,
|
|
||||||
installed_klm_version,
|
|
||||||
installed_kernel_version,
|
|
||||||
expecting_ok):
|
|
||||||
with mock.patch(
|
|
||||||
'neutron.agent.linux.ovs_lib.get_installed_ovs_klm_version'
|
|
||||||
) as klm_cmd:
|
|
||||||
with mock.patch(
|
|
||||||
'neutron.agent.linux.ovs_lib.get_installed_ovs_usr_version'
|
|
||||||
) as usr_cmd:
|
|
||||||
with mock.patch(
|
|
||||||
'neutron.agent.linux.ovs_lib.get_installed_kernel_version'
|
|
||||||
) as kernel_cmd:
|
|
||||||
try:
|
|
||||||
klm_cmd.return_value = installed_klm_version
|
|
||||||
usr_cmd.return_value = installed_usr_version
|
|
||||||
kernel_cmd.return_value = installed_kernel_version
|
|
||||||
ovs_lib.check_ovs_vxlan_version(root_helper='sudo')
|
|
||||||
version_ok = True
|
|
||||||
except SystemError:
|
|
||||||
version_ok = False
|
|
||||||
self.assertEqual(version_ok, expecting_ok)
|
|
||||||
|
|
||||||
def test_check_minimum_version(self):
|
|
||||||
min_vxlan_ver = constants.MINIMUM_OVS_VXLAN_VERSION
|
|
||||||
min_kernel_ver = constants.MINIMUM_LINUX_KERNEL_OVS_VXLAN
|
|
||||||
self._check_ovs_vxlan_version(min_vxlan_ver, min_vxlan_ver,
|
|
||||||
min_kernel_ver, expecting_ok=True)
|
|
||||||
|
|
||||||
def test_check_future_version(self):
|
|
||||||
install_ver = str(float(constants.MINIMUM_OVS_VXLAN_VERSION) + 0.01)
|
|
||||||
min_kernel_ver = constants.MINIMUM_LINUX_KERNEL_OVS_VXLAN
|
|
||||||
self._check_ovs_vxlan_version(install_ver, install_ver,
|
|
||||||
min_kernel_ver, expecting_ok=True)
|
|
||||||
|
|
||||||
def test_check_fail_version(self):
|
|
||||||
install_ver = str(float(constants.MINIMUM_OVS_VXLAN_VERSION) - 0.01)
|
|
||||||
min_kernel_ver = constants.MINIMUM_LINUX_KERNEL_OVS_VXLAN
|
|
||||||
self._check_ovs_vxlan_version(install_ver, install_ver,
|
|
||||||
min_kernel_ver, expecting_ok=False)
|
|
||||||
|
|
||||||
def test_check_fail_no_version(self):
|
|
||||||
min_kernel_ver = constants.MINIMUM_LINUX_KERNEL_OVS_VXLAN
|
|
||||||
self._check_ovs_vxlan_version(None, None,
|
|
||||||
min_kernel_ver,
|
|
||||||
expecting_ok=False)
|
|
||||||
|
|
||||||
def test_check_fail_klm_version(self):
|
|
||||||
min_vxlan_ver = constants.MINIMUM_OVS_VXLAN_VERSION
|
|
||||||
min_kernel_ver = OVS_LINUX_KERN_VERS_WITHOUT_VXLAN
|
|
||||||
install_ver = str(float(min_vxlan_ver) - 0.01)
|
|
||||||
self._check_ovs_vxlan_version(min_vxlan_ver,
|
|
||||||
install_ver,
|
|
||||||
min_kernel_ver,
|
|
||||||
expecting_ok=False)
|
|
||||||
|
|
||||||
def test_check_pass_kernel_version(self):
|
|
||||||
min_vxlan_ver = constants.MINIMUM_OVS_VXLAN_VERSION
|
|
||||||
min_kernel_ver = constants.MINIMUM_LINUX_KERNEL_OVS_VXLAN
|
|
||||||
self._check_ovs_vxlan_version(min_vxlan_ver, min_vxlan_ver,
|
|
||||||
min_kernel_ver, expecting_ok=True)
|
|
||||||
|
|
||||||
def test_ofctl_arg_supported(self):
|
def test_ofctl_arg_supported(self):
|
||||||
with mock.patch('neutron.common.utils.get_random_string') as utils:
|
with mock.patch('neutron.common.utils.get_random_string') as utils:
|
||||||
utils.return_value = 'test'
|
utils.return_value = 'test'
|
||||||
|
@ -291,24 +291,12 @@ class TunnelTest(base.BaseTestCase):
|
|||||||
self._verify_mock_calls()
|
self._verify_mock_calls()
|
||||||
|
|
||||||
def test_construct_vxlan(self):
|
def test_construct_vxlan(self):
|
||||||
with mock.patch.object(ovs_lib, 'get_installed_ovs_klm_version',
|
ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE,
|
||||||
return_value="1.10") as klm_ver:
|
self.TUN_BRIDGE,
|
||||||
with mock.patch.object(ovs_lib, 'get_installed_ovs_usr_version',
|
'10.0.0.1',
|
||||||
return_value="1.10") as usr_ver:
|
self.NET_MAPPING,
|
||||||
with mock.patch.object(ovs_lib, 'get_installed_kernel_version',
|
'sudo', 2, ['vxlan'],
|
||||||
return_value=(
|
self.VETH_MTU)
|
||||||
constants.
|
|
||||||
MINIMUM_LINUX_KERNEL_OVS_VXLAN
|
|
||||||
)) as kernel_ver:
|
|
||||||
ovs_neutron_agent.OVSNeutronAgent(self.INT_BRIDGE,
|
|
||||||
self.TUN_BRIDGE,
|
|
||||||
'10.0.0.1',
|
|
||||||
self.NET_MAPPING,
|
|
||||||
'sudo', 2, ['vxlan'],
|
|
||||||
self.VETH_MTU)
|
|
||||||
klm_ver.assert_called_once_with()
|
|
||||||
kernel_ver.assert_called_once_with()
|
|
||||||
usr_ver.assert_called_once_with('sudo')
|
|
||||||
self._verify_mock_calls()
|
self._verify_mock_calls()
|
||||||
|
|
||||||
def test_provision_local_vlan(self):
|
def test_provision_local_vlan(self):
|
||||||
|
@ -115,6 +115,7 @@ console_scripts =
|
|||||||
neutron-vpn-agent = neutron.services.vpn.agent:main
|
neutron-vpn-agent = neutron.services.vpn.agent:main
|
||||||
neutron-metering-agent = neutron.services.metering.agents.metering_agent:main
|
neutron-metering-agent = neutron.services.metering.agents.metering_agent:main
|
||||||
neutron-ofagent-agent = ryu.cmd.ofa_neutron_agent:main
|
neutron-ofagent-agent = ryu.cmd.ofa_neutron_agent:main
|
||||||
|
neutron-sanity-check = neutron.cmd.sanity_check:main
|
||||||
neutron.core_plugins =
|
neutron.core_plugins =
|
||||||
bigswitch = neutron.plugins.bigswitch.plugin:NeutronRestProxyV2
|
bigswitch = neutron.plugins.bigswitch.plugin:NeutronRestProxyV2
|
||||||
brocade = neutron.plugins.brocade.NeutronPlugin:BrocadePluginV2
|
brocade = neutron.plugins.brocade.NeutronPlugin:BrocadePluginV2
|
||||||
|
Loading…
x
Reference in New Issue
Block a user