Remove run-time version checking for openvswitch features
The current method of checking openvswitch and kernel versions for specific feature support is brittle, distro-specific and unsupportable. This patch removes the runtime version checks and implements a test script which allows testing specific neutron features or can test that all features required by a specific configuration are available. For example, to test VXLAN support in openvswitch, either: neutron-sanity-check --ovs_vxlan or pass in the deployed configuration files with AGENT/tunnel_types containing 'vxlan', like: neutron-sanity-check --config-file /etc/neutron/plugins/ml2.conf.ini Deployment tools can then test that the required features exist without relying on version numbers and without incurring a penalty every time the agent is started. Implements: blueprint remove-openvswitch-version-check DocImpact Change-Id: I5e822d97b9bece9242ba5ac8901aa0ca4f090cfechanges/25/96525/10
parent
b33ecb3d16
commit
ab4dc5261e
@ -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
|
@ -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
|
@ -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,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)
|
Loading…
Reference in New Issue