From 25450d27fa02f747fdad5a7f6141200c8bd10f9e Mon Sep 17 00:00:00 2001 From: Frode Nordahl Date: Fri, 9 Jun 2017 14:07:13 +0200 Subject: [PATCH] Handle neutron-sriov-agent on Kilo and Liberty On Kilo and Liberty the agent is called 'neutron-plugin-sriov-agent'. Add unit-test to verify package determination. Add functional test to verify that configuration is written. Change-Id: I8a40c12cbb7f6a692b19105d5c029fd7f2829504 Closes-Bug: #1696691 --- hooks/neutron_ovs_utils.py | 25 ++++++-- templates/{mitaka => kilo}/sriov_agent.ini | 1 - tests/basic_deployment.py | 47 +++++++++++++- unit_tests/test_neutron_ovs_utils.py | 74 ++++++++++++++++++++++ 4 files changed, 139 insertions(+), 8 deletions(-) rename templates/{mitaka => kilo}/sriov_agent.ini (98%) diff --git a/hooks/neutron_ovs_utils.py b/hooks/neutron_ovs_utils.py index 541e6230..14eff4ad 100644 --- a/hooks/neutron_ovs_utils.py +++ b/hooks/neutron_ovs_utils.py @@ -278,7 +278,10 @@ def determine_packages(): pkgs.append('openvswitch-switch-dpdk') if enable_sriov_agent(): - pkgs.append('neutron-sriov-agent') + if cmp_release >= 'mitaka': + pkgs.append('neutron-sriov-agent') + else: + pkgs.append('neutron-plugin-sriov-agent') return pkgs @@ -323,13 +326,23 @@ def resource_map(): ) if not use_dpdk(): drop_config.append(DPDK_INTERFACES) - if enable_sriov_agent(): - resource_map.update(SRIOV_RESOURCE_MAP) - resource_map[NEUTRON_CONF]['services'].append( - 'neutron-sriov-agent') else: drop_config.extend([OVS_CONF, DPDK_INTERFACES]) + if enable_sriov_agent(): + sriov_agent_name = 'neutron-sriov-agent' + sriov_resource_map = SRIOV_RESOURCE_MAP + + if CompareOpenStackReleases(_os_release) < 'mitaka': + sriov_agent_name = 'neutron-plugin-sriov-agent' + # Patch resource_map for Kilo and Liberty + sriov_resource_map[NEUTRON_SRIOV_AGENT_CONF]['services'] = \ + [sriov_agent_name] + + resource_map.update(sriov_resource_map) + resource_map[NEUTRON_CONF]['services'].append( + sriov_agent_name) + # Use MAAS1.9 for MTU and external port config on xenial and above if CompareHostReleases(lsb_release()['DISTRIB_CODENAME']) >= 'xenial': drop_config.extend([EXT_PORT_CONF, PHY_NIC_MTU_CONF]) @@ -522,7 +535,7 @@ def enable_sriov_agent(): '''Determine with SR-IOV agent should be used''' cmp_release = CompareOpenStackReleases( os_release('neutron-common', base='icehouse')) - return (cmp_release >= 'mitaka' and config('enable-sriov')) + return (cmp_release >= 'kilo' and config('enable-sriov')) # TODO: update into charm-helpers to add port_type parameter diff --git a/templates/mitaka/sriov_agent.ini b/templates/kilo/sriov_agent.ini similarity index 98% rename from templates/mitaka/sriov_agent.ini rename to templates/kilo/sriov_agent.ini index 3c7b1383..0187e30a 100644 --- a/templates/mitaka/sriov_agent.ini +++ b/templates/kilo/sriov_agent.ini @@ -1,4 +1,3 @@ -# mitaka ############################################################################### # [ WARNING ] # Configuration file maintained by Juju. Local changes may be overwritten. diff --git a/tests/basic_deployment.py b/tests/basic_deployment.py index bc4f1d15..645a93a9 100644 --- a/tests/basic_deployment.py +++ b/tests/basic_deployment.py @@ -54,7 +54,10 @@ class NeutronOVSBasicDeployment(OpenStackAmuletDeployment): self._deploy() u.log.info('Waiting on extended status checks...') - exclude_services = [] + # We delay check for services running on neutron-openvswitch unit to + # after verification of sriov configuration. See comment in function + # test_301_neutron_sriov_config() + exclude_services = ['neutron-openvswitch'] self._auto_wait_for_status(exclude_services=exclude_services) self.d.sentry.wait() @@ -155,6 +158,9 @@ class NeutronOVSBasicDeployment(OpenStackAmuletDeployment): } neutron_ovs_config['openstack-origin-git'] = yaml.dump(openstack_origin_git) + neutron_ovs_config['enable-sriov'] = True + neutron_ovs_config['sriov-device-mappings'] = 'physnet42:eth42' + pxc_config = { 'dataset-size': '25%', 'max-connections': 1000, @@ -199,6 +205,45 @@ class NeutronOVSBasicDeployment(OpenStackAmuletDeployment): u.log.debug('OK') + def test_301_neutron_sriov_config(self): + """Verify data in the sriov agent config file. This is supported since + Kilo""" + if self._get_openstack_release() < self.trusty_kilo: + u.log.debug('Skipping test, sriov agent not supported on < ' + 'trusty/kilo') + return + u.log.debug('Checking sriov agent config file data...') + unit = self.n_ovs_sentry + conf = '/etc/neutron/plugins/ml2/sriov_agent.ini' + expected = { + 'sriov_nic': { + 'physical_device_mappings': 'physnet42:eth42', + }, + } + for section, pairs in expected.iteritems(): + ret = u.validate_config_data(unit, conf, section, pairs) + if ret: + message = "sriov agent config error: {}".format(ret) + amulet.raise_status(amulet.FAIL, msg=message) + + # the CI environment does not expose an actual SR-IOV NIC to the + # functional tests. consequently the neutron-sriov agent will not + # run, and the charm will update its status as such. this will prevent + # the success of pause/resume test. + # + # disable sriov after validation of config file is complete. + u.log.info('Disabling SR-IOV after verifying config file data...') + configs = { + 'neutron-openvswitch': { 'enable-sriov': False } + } + super(NeutronOVSBasicDeployment, self)._configure_services(configs) + + u.log.info('Waiting for config-change to complete...') + self._auto_wait_for_status() + self.d.sentry.wait() + + u.log.debug('OK') + def test_rabbitmq_amqp_relation(self): """Verify data in rabbitmq-server/neutron-openvswitch amqp relation""" unit = self.rabbitmq_sentry diff --git a/unit_tests/test_neutron_ovs_utils.py b/unit_tests/test_neutron_ovs_utils.py index e292bc4a..0863d1af 100644 --- a/unit_tests/test_neutron_ovs_utils.py +++ b/unit_tests/test_neutron_ovs_utils.py @@ -192,6 +192,48 @@ class TestNeutronOVSUtils(CharmTestCase): pkg_list = nutils.determine_packages() self.assertFalse('neutron-l3-agent' in pkg_list) + @patch.object(nutils, 'use_dvr') + @patch.object(nutils, 'git_install_requested') + @patch.object(charmhelpers.contrib.openstack.neutron, 'os_release') + @patch.object(charmhelpers.contrib.openstack.neutron, 'headers_package') + def test_determine_pkgs_sriov(self, _head_pkgs, _os_rel, _git_requested, + _use_dvr): + self.test_config.set('enable-local-dhcp-and-metadata', False) + self.test_config.set('enable-sriov', True) + _git_requested.return_value = False + _use_dvr.return_value = False + _os_rel.return_value = 'kilo' + self.os_release.return_value = 'kilo' + _head_pkgs.return_value = head_pkg + pkg_list = nutils.determine_packages() + expect = [ + 'neutron-plugin-sriov-agent', + 'neutron-plugin-openvswitch-agent', + head_pkg, + ] + self.assertItemsEqual(pkg_list, expect) + + @patch.object(nutils, 'use_dvr') + @patch.object(nutils, 'git_install_requested') + @patch.object(charmhelpers.contrib.openstack.neutron, 'os_release') + @patch.object(charmhelpers.contrib.openstack.neutron, 'headers_package') + def test_determine_pkgs_sriov_mitaka(self, _head_pkgs, _os_rel, + _git_requested, _use_dvr): + self.test_config.set('enable-local-dhcp-and-metadata', False) + self.test_config.set('enable-sriov', True) + _git_requested.return_value = False + _use_dvr.return_value = False + _os_rel.return_value = 'mitaka' + self.os_release.return_value = 'mitaka' + _head_pkgs.return_value = head_pkg + pkg_list = nutils.determine_packages() + expect = [ + 'neutron-sriov-agent', + 'neutron-openvswitch-agent', + head_pkg + ] + self.assertItemsEqual(pkg_list, expect) + @patch.object(nutils, 'use_dvr') def test_register_configs(self, _use_dvr): class _mock_OSConfigRenderer(): @@ -247,6 +289,22 @@ class TestNeutronOVSUtils(CharmTestCase): [self.assertIn(q_conf, _map.keys()) for q_conf in confs] self.assertEqual(_map[nutils.NEUTRON_CONF]['services'], svcs) + @patch.object(nutils, 'enable_sriov_agent') + @patch.object(nutils, 'use_dvr') + def test_resource_map_kilo_sriov(self, _use_dvr, _enable_sriov_agent): + _use_dvr.return_value = False + _enable_sriov_agent.return_value = True + self.os_release.return_value = 'kilo' + self.lsb_release.return_value = {'DISTRIB_CODENAME': 'trusty'} + _map = nutils.resource_map() + svcs = ['neutron-plugin-openvswitch-agent', + 'neutron-plugin-sriov-agent'] + confs = [nutils.NEUTRON_CONF, nutils.NEUTRON_SRIOV_AGENT_CONF] + [self.assertIn(q_conf, _map.keys()) for q_conf in confs] + self.assertEqual(_map[nutils.NEUTRON_CONF]['services'], svcs) + self.assertEqual(_map[nutils.NEUTRON_SRIOV_AGENT_CONF]['services'], + ['neutron-plugin-sriov-agent']) + @patch.object(nutils, 'use_dvr') def test_resource_map_mitaka(self, _use_dvr): _use_dvr.return_value = False @@ -258,6 +316,22 @@ class TestNeutronOVSUtils(CharmTestCase): [self.assertIn(q_conf, _map.keys()) for q_conf in confs] self.assertEqual(_map[nutils.NEUTRON_CONF]['services'], svcs) + @patch.object(nutils, 'enable_sriov_agent') + @patch.object(nutils, 'use_dvr') + def test_resource_map_mitaka_sriov(self, _use_dvr, _enable_sriov_agent): + _use_dvr.return_value = False + _enable_sriov_agent.return_value = True + self.os_release.return_value = 'mitaka' + self.lsb_release.return_value = {'DISTRIB_CODENAME': 'xenial'} + _map = nutils.resource_map() + svcs = ['neutron-openvswitch-agent', + 'neutron-sriov-agent'] + confs = [nutils.NEUTRON_CONF, nutils.NEUTRON_SRIOV_AGENT_CONF] + [self.assertIn(q_conf, _map.keys()) for q_conf in confs] + self.assertEqual(_map[nutils.NEUTRON_CONF]['services'], svcs) + self.assertEqual(_map[nutils.NEUTRON_SRIOV_AGENT_CONF]['services'], + ['neutron-sriov-agent']) + @patch.object(nutils, 'use_dvr') def test_resource_map_dvr(self, _use_dvr): _use_dvr.return_value = True