From 9595e7516c337f9c1f0522a7dbee9ac511c4d8c4 Mon Sep 17 00:00:00 2001 From: Liam Young Date: Tue, 8 Sep 2015 13:17:28 +0100 Subject: [PATCH 1/9] Enable metadata --- config.yaml | 4 +++- hooks/neutron_ovs_context.py | 4 ++-- hooks/neutron_ovs_hooks.py | 10 +++++++++- hooks/neutron_ovs_utils.py | 28 ++++++++++++++++++++++------ templates/icehouse/dhcp_agent.ini | 14 ++++++++++++++ 5 files changed, 50 insertions(+), 10 deletions(-) create mode 100644 templates/icehouse/dhcp_agent.ini diff --git a/config.yaml b/config.yaml index 966189af..f4bf404f 100644 --- a/config.yaml +++ b/config.yaml @@ -98,4 +98,6 @@ options: traffic to the external public network. Valid values are either MAC addresses (in which case only MAC addresses for interfaces without an IP address already assigned will be used), or interfaces (eth0) - + enable-metadata: + type: boolean + default: false diff --git a/hooks/neutron_ovs_context.py b/hooks/neutron_ovs_context.py index 8b804c09..3b24ef79 100644 --- a/hooks/neutron_ovs_context.py +++ b/hooks/neutron_ovs_context.py @@ -108,10 +108,10 @@ def get_shared_secret(): return secret -class DVRSharedSecretContext(OSContextGenerator): +class SharedSecretContext(OSContextGenerator): def __call__(self): - if NeutronAPIContext()()['enable_dvr']: + if NeutronAPIContext()()['enable_dvr'] or config('enable-metadata'): ctxt = { 'shared_secret': get_shared_secret(), 'local_ip': resolve_address(), diff --git a/hooks/neutron_ovs_hooks.py b/hooks/neutron_ovs_hooks.py index 887e3801..8c4b1a6b 100755 --- a/hooks/neutron_ovs_hooks.py +++ b/hooks/neutron_ovs_hooks.py @@ -39,6 +39,7 @@ from neutron_ovs_utils import ( register_configs, restart_map, use_dvr, + enable_metadata, ) hooks = Hooks() @@ -71,6 +72,8 @@ def config_changed(): CONFIGS.write_all() for rid in relation_ids('zeromq-configuration'): zeromq_configuration_relation_joined(rid) + for rid in relation_ids('neutron-plugin'): + neutron_plugin_joined(relation_id=rid) @hooks.hook('neutron-plugin-api-relation-changed') @@ -90,10 +93,15 @@ def neutron_plugin_api_changed(): @hooks.hook('neutron-plugin-relation-joined') def neutron_plugin_joined(relation_id=None): - secret = get_shared_secret() if use_dvr() else None + print "Enable metadata: {}".format(enable_metadata()) + if config('enable-metadata'): + apt_install('neutron-metadata-agent', fatal=True) + apt_install('neutron-dhcp-agent', fatal=True) + secret = get_shared_secret() if enable_metadata() else None rel_data = { 'metadata-shared-secret': secret, } + print rel_data relation_set(relation_id=relation_id, **rel_data) diff --git a/hooks/neutron_ovs_utils.py b/hooks/neutron_ovs_utils.py index 21d64767..1e98c397 100644 --- a/hooks/neutron_ovs_utils.py +++ b/hooks/neutron_ovs_utils.py @@ -66,6 +66,7 @@ GIT_PACKAGE_BLACKLIST = [ ] NOVA_CONF_DIR = "/etc/nova" +NEUTRON_DHCP_AGENT_CONF = "/etc/neutron/dhcp_agent.ini" NEUTRON_CONF_DIR = "/etc/neutron" NEUTRON_CONF = '%s/neutron.conf' % NEUTRON_CONF_DIR NEUTRON_DEFAULT = '/etc/default/neutron-server' @@ -95,6 +96,17 @@ BASE_RESOURCE_MAP = OrderedDict([ 'contexts': [context.PhyNICMTUContext()], }), ]) +METADATA_RESOURCE_MAP = OrderedDict([ + (NEUTRON_METADATA_AGENT_CONF, { + 'services': ['neutron-metadata-agent'], + 'contexts': [neutron_ovs_context.SharedSecretContext(), + neutron_ovs_context.APIIdentityServiceContext()], + }), + (NEUTRON_DHCP_AGENT_CONF, { + 'services': ['neutron-dhcp-agent'], + 'contexts': [], + }), +]) DVR_RESOURCE_MAP = OrderedDict([ (NEUTRON_L3_AGENT_CONF, { 'services': ['neutron-l3-agent'], @@ -108,11 +120,6 @@ DVR_RESOURCE_MAP = OrderedDict([ 'services': ['neutron-l3-agent'], 'contexts': [context.ExternalPortContext()], }), - (NEUTRON_METADATA_AGENT_CONF, { - 'services': ['neutron-metadata-agent'], - 'contexts': [neutron_ovs_context.DVRSharedSecretContext(), - neutron_ovs_context.APIIdentityServiceContext()], - }), ]) TEMPLATES = 'templates/' INT_BRIDGE = "br-int" @@ -158,8 +165,13 @@ def resource_map(): resource_map = deepcopy(BASE_RESOURCE_MAP) if use_dvr(): resource_map.update(DVR_RESOURCE_MAP) + resource_map.update(METADATA_RESOURCE_MAP) dvr_services = ['neutron-metadata-agent', 'neutron-l3-agent'] resource_map[NEUTRON_CONF]['services'] += dvr_services + if enable_metadata(): + resource_map.update(METADATA_RESOURCE_MAP) + metadata_services = ['neutron-metadata-agent'] + resource_map[NEUTRON_CONF]['services'] += metadata_services return resource_map @@ -209,7 +221,7 @@ def configure_ovs(): def get_shared_secret(): - ctxt = neutron_ovs_context.DVRSharedSecretContext()() + ctxt = neutron_ovs_context.SharedSecretContext()() if 'shared_secret' in ctxt: return ctxt['shared_secret'] @@ -218,6 +230,10 @@ def use_dvr(): return context.NeutronAPIContext()()['enable_dvr'] +def enable_metadata(): + return use_dvr() or config('enable-metadata') + + def git_install(projects_yaml): """Perform setup, and install git repos specified in yaml parameter.""" if git_install_requested(): diff --git a/templates/icehouse/dhcp_agent.ini b/templates/icehouse/dhcp_agent.ini new file mode 100644 index 00000000..9fe627a5 --- /dev/null +++ b/templates/icehouse/dhcp_agent.ini @@ -0,0 +1,14 @@ +############################################################################### +# [ WARNING ] +# Configuration file maintained by Juju. Local changes may be overwritten. +############################################################################### +[DEFAULT] +state_path = /var/lib/neutron +interface_driver = neutron.agent.linux.interface.OVSInterfaceDriver +dhcp_driver = neutron.agent.linux.dhcp.Dnsmasq +root_helper = sudo /usr/bin/neutron-rootwrap /etc/neutron/rootwrap.conf + +enable_metadata_network = True +enable_isolated_metadata = True + +ovs_use_veth = True From 806049e08f202e657e2cf7229f349bffb2eeae40 Mon Sep 17 00:00:00 2001 From: Liam Young Date: Tue, 8 Sep 2015 13:23:26 +0100 Subject: [PATCH 2/9] Metadata tidy --- config.yaml | 2 +- hooks/neutron_ovs_hooks.py | 5 ++--- hooks/neutron_ovs_utils.py | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/config.yaml b/config.yaml index f4bf404f..47dae983 100644 --- a/config.yaml +++ b/config.yaml @@ -98,6 +98,6 @@ options: traffic to the external public network. Valid values are either MAC addresses (in which case only MAC addresses for interfaces without an IP address already assigned will be used), or interfaces (eth0) - enable-metadata: + enable-local-dhcp-and-metadata: type: boolean default: false diff --git a/hooks/neutron_ovs_hooks.py b/hooks/neutron_ovs_hooks.py index 8c4b1a6b..2b31e3ce 100755 --- a/hooks/neutron_ovs_hooks.py +++ b/hooks/neutron_ovs_hooks.py @@ -94,9 +94,8 @@ def neutron_plugin_api_changed(): @hooks.hook('neutron-plugin-relation-joined') def neutron_plugin_joined(relation_id=None): print "Enable metadata: {}".format(enable_metadata()) - if config('enable-metadata'): - apt_install('neutron-metadata-agent', fatal=True) - apt_install('neutron-dhcp-agent', fatal=True) + if config('enable-local-dhcp-and-metadata'): + apt_install(['neutron-metadata-agent', 'neutron-dhcp-agent'] fatal=True) secret = get_shared_secret() if enable_metadata() else None rel_data = { 'metadata-shared-secret': secret, diff --git a/hooks/neutron_ovs_utils.py b/hooks/neutron_ovs_utils.py index 1e98c397..8ab4ad35 100644 --- a/hooks/neutron_ovs_utils.py +++ b/hooks/neutron_ovs_utils.py @@ -231,7 +231,7 @@ def use_dvr(): def enable_metadata(): - return use_dvr() or config('enable-metadata') + return use_dvr() or config('enable-local-dhcp-and-metadata') def git_install(projects_yaml): From 883c01903a5e6258ec1a9693269147452676cbd8 Mon Sep 17 00:00:00 2001 From: Liam Young Date: Tue, 8 Sep 2015 15:12:14 +0100 Subject: [PATCH 3/9] Unit test updates --- hooks/neutron_ovs_hooks.py | 30 +++++--------- hooks/neutron_ovs_utils.py | 32 ++++++++++----- unit_tests/test_neutron_ovs_context.py | 10 ++--- unit_tests/test_neutron_ovs_hooks.py | 40 +++++++++--------- unit_tests/test_neutron_ovs_utils.py | 56 +++++++++++++++++++++++++- 5 files changed, 113 insertions(+), 55 deletions(-) diff --git a/hooks/neutron_ovs_hooks.py b/hooks/neutron_ovs_hooks.py index 2b31e3ce..064c711b 100755 --- a/hooks/neutron_ovs_hooks.py +++ b/hooks/neutron_ovs_hooks.py @@ -21,7 +21,7 @@ from charmhelpers.core.host import ( ) from charmhelpers.fetch import ( - apt_install, apt_update, apt_purge + apt_purge, ) from charmhelpers.contrib.openstack.utils import ( @@ -31,15 +31,15 @@ from charmhelpers.contrib.openstack.utils import ( from neutron_ovs_utils import ( DVR_PACKAGES, configure_ovs, - determine_packages, git_install, get_topics, - determine_dvr_packages, get_shared_secret, register_configs, restart_map, use_dvr, - enable_metadata, + enable_nova_metadata, + enable_local_dhcp, + install_packages, ) hooks = Hooks() @@ -48,11 +48,7 @@ CONFIGS = register_configs() @hooks.hook() def install(): - apt_update() - pkgs = determine_packages() - for pkg in pkgs: - apt_install(pkg, fatal=True) - + install_packages() git_install(config('openstack-origin-git')) @@ -60,10 +56,7 @@ def install(): @hooks.hook('config-changed') @restart_on_change(restart_map()) def config_changed(): - if determine_dvr_packages(): - apt_update() - apt_install(determine_dvr_packages(), fatal=True) - + install_packages() if git_install_requested(): if config_value_changed('openstack-origin-git'): git_install(config('openstack-origin-git')) @@ -80,8 +73,7 @@ def config_changed(): @restart_on_change(restart_map()) def neutron_plugin_api_changed(): if use_dvr(): - apt_update() - apt_install(DVR_PACKAGES, fatal=True) + install_packages() else: apt_purge(DVR_PACKAGES, fatal=True) configure_ovs() @@ -93,14 +85,12 @@ def neutron_plugin_api_changed(): @hooks.hook('neutron-plugin-relation-joined') def neutron_plugin_joined(relation_id=None): - print "Enable metadata: {}".format(enable_metadata()) - if config('enable-local-dhcp-and-metadata'): - apt_install(['neutron-metadata-agent', 'neutron-dhcp-agent'] fatal=True) - secret = get_shared_secret() if enable_metadata() else None + if enable_local_dhcp(): + install_packages() + secret = get_shared_secret() if enable_nova_metadata() else None rel_data = { 'metadata-shared-secret': secret, } - print rel_data relation_set(relation_id=relation_id, **rel_data) diff --git a/hooks/neutron_ovs_utils.py b/hooks/neutron_ovs_utils.py index 8ab4ad35..996cc54b 100644 --- a/hooks/neutron_ovs_utils.py +++ b/hooks/neutron_ovs_utils.py @@ -43,6 +43,12 @@ from charmhelpers.core.host import ( from charmhelpers.core.templating import render +from charmhelpers.fetch import ( + apt_install, + apt_update, + filter_installed_packages, +) + BASE_GIT_PACKAGES = [ 'libffi-dev', 'libssl-dev', @@ -102,6 +108,8 @@ METADATA_RESOURCE_MAP = OrderedDict([ 'contexts': [neutron_ovs_context.SharedSecretContext(), neutron_ovs_context.APIIdentityServiceContext()], }), +]) +DHCP_RESOURCE_MAP = OrderedDict([ (NEUTRON_DHCP_AGENT_CONF, { 'services': ['neutron-dhcp-agent'], 'contexts': [], @@ -127,16 +135,17 @@ EXT_BRIDGE = "br-ex" DATA_BRIDGE = 'br-data' -def determine_dvr_packages(): - if not git_install_requested(): - if use_dvr(): - return DVR_PACKAGES - return [] +def install_packages(): + apt_update() + apt_install(filter_installed_packages(determine_packages())) def determine_packages(): pkgs = neutron_plugin_attribute('ovs', 'packages', 'neutron') - pkgs.extend(determine_dvr_packages()) + if use_dvr(): + pkgs.extend(DVR_PACKAGES) + if enable_local_dhcp(): + pkgs.extend(['neutron-metadata-agent', 'neutron-dhcp-agent']) if git_install_requested(): pkgs.extend(BASE_GIT_PACKAGES) @@ -168,9 +177,10 @@ def resource_map(): resource_map.update(METADATA_RESOURCE_MAP) dvr_services = ['neutron-metadata-agent', 'neutron-l3-agent'] resource_map[NEUTRON_CONF]['services'] += dvr_services - if enable_metadata(): + if enable_local_dhcp(): resource_map.update(METADATA_RESOURCE_MAP) - metadata_services = ['neutron-metadata-agent'] + resource_map.update(DHCP_RESOURCE_MAP) + metadata_services = ['neutron-metadata-agent', 'neutron-dhcp-agent'] resource_map[NEUTRON_CONF]['services'] += metadata_services return resource_map @@ -230,10 +240,14 @@ def use_dvr(): return context.NeutronAPIContext()()['enable_dvr'] -def enable_metadata(): +def enable_nova_metadata(): return use_dvr() or config('enable-local-dhcp-and-metadata') +def enable_local_dhcp(): + return config('enable-local-dhcp-and-metadata') + + def git_install(projects_yaml): """Perform setup, and install git repos specified in yaml parameter.""" if git_install_requested(): diff --git a/unit_tests/test_neutron_ovs_context.py b/unit_tests/test_neutron_ovs_context.py index 6bd54936..6a33cbc0 100644 --- a/unit_tests/test_neutron_ovs_context.py +++ b/unit_tests/test_neutron_ovs_context.py @@ -250,11 +250,11 @@ class L3AgentContextTest(CharmTestCase): self.assertEquals(context.L3AgentContext()(), {'agent_mode': 'legacy'}) -class DVRSharedSecretContext(CharmTestCase): +class SharedSecretContext(CharmTestCase): def setUp(self): - super(DVRSharedSecretContext, self).setUp(context, - TO_PATCH) + super(SharedSecretContext, self).setUp(context, + TO_PATCH) self.config.side_effect = self.test_config.get @patch('os.path') @@ -286,7 +286,7 @@ class DVRSharedSecretContext(CharmTestCase): _NeutronAPIContext.side_effect = fake_context({'enable_dvr': True}) _shared_secret.return_value = 'secret_thing' self.resolve_address.return_value = '10.0.0.10' - self.assertEquals(context.DVRSharedSecretContext()(), + self.assertEquals(context.SharedSecretContext()(), {'shared_secret': 'secret_thing', 'local_ip': '10.0.0.10'}) @@ -297,4 +297,4 @@ class DVRSharedSecretContext(CharmTestCase): _NeutronAPIContext.side_effect = fake_context({'enable_dvr': False}) _shared_secret.return_value = 'secret_thing' self.resolve_address.return_value = '10.0.0.10' - self.assertEquals(context.DVRSharedSecretContext()(), {}) + self.assertEquals(context.SharedSecretContext()(), {}) diff --git a/unit_tests/test_neutron_ovs_hooks.py b/unit_tests/test_neutron_ovs_hooks.py index 342b7c8c..3df985ca 100644 --- a/unit_tests/test_neutron_ovs_hooks.py +++ b/unit_tests/test_neutron_ovs_hooks.py @@ -1,4 +1,4 @@ -from mock import MagicMock, patch, call +from mock import MagicMock, patch import yaml from test_utils import CharmTestCase @@ -19,13 +19,9 @@ utils.register_configs = _reg utils.restart_map = _map TO_PATCH = [ - 'apt_update', - 'apt_install', 'apt_purge', 'config', 'CONFIGS', - 'determine_packages', - 'determine_dvr_packages', 'get_shared_secret', 'git_install', 'log', @@ -33,6 +29,9 @@ TO_PATCH = [ 'relation_set', 'configure_ovs', 'use_dvr', + 'install_packages', + 'enable_nova_metadata', + 'enable_local_dhcp', ] NEUTRON_CONF_DIR = "/etc/neutron" @@ -54,19 +53,12 @@ class NeutronOVSHooksTests(CharmTestCase): @patch.object(hooks, 'git_install_requested') def test_install_hook(self, git_requested): git_requested.return_value = False - _pkgs = ['foo', 'bar'] - self.determine_packages.return_value = [_pkgs] self._call_hook('install') - self.apt_update.assert_called_with() - self.apt_install.assert_has_calls([ - call(_pkgs, fatal=True), - ]) + self.install_packages.assert_called_with() @patch.object(hooks, 'git_install_requested') def test_install_hook_git(self, git_requested): git_requested.return_value = True - _pkgs = ['foo', 'bar'] - self.determine_packages.return_value = _pkgs openstack_origin_git = { 'repositories': [ {'name': 'requirements', @@ -81,8 +73,7 @@ class NeutronOVSHooksTests(CharmTestCase): projects_yaml = yaml.dump(openstack_origin_git) self.test_config.set('openstack-origin-git', projects_yaml) self._call_hook('install') - self.apt_update.assert_called_with() - self.assertTrue(self.determine_packages) + self.install_packages.assert_called_with() self.git_install.assert_called_with(projects_yaml) @patch.object(hooks, 'git_install_requested') @@ -124,13 +115,9 @@ class NeutronOVSHooksTests(CharmTestCase): @patch.object(hooks, 'git_install_requested') def test_config_changed_dvr(self, git_requested): git_requested.return_value = False - self.determine_dvr_packages.return_value = ['dvr'] self._call_hook('config-changed') - self.apt_update.assert_called_with() + self.install_packages.assert_called_with() self.assertTrue(self.CONFIGS.write_all.called) - self.apt_install.assert_has_calls([ - call(['dvr'], fatal=True), - ]) self.configure_ovs.assert_called_with() @patch.object(hooks, 'neutron_plugin_joined') @@ -140,9 +127,22 @@ class NeutronOVSHooksTests(CharmTestCase): self.configure_ovs.assert_called_with() self.assertTrue(self.CONFIGS.write_all.called) _plugin_joined.assert_called_with(relation_id='rid') + self.install_packages.assert_called_with() + + @patch.object(hooks, 'neutron_plugin_joined') + def test_neutron_plugin_api_nodvr(self, _plugin_joined): + self.use_dvr.return_value = False + self.relation_ids.return_value = ['rid'] + self._call_hook('neutron-plugin-api-relation-changed') + self.configure_ovs.assert_called_with() + self.assertTrue(self.CONFIGS.write_all.called) + _plugin_joined.assert_called_with(relation_id='rid') + self.apt_purge.assert_called_with(['neutron-l3-agent'], fatal=True) @patch.object(hooks, 'git_install_requested') def test_neutron_plugin_joined(self, git_requested): + self.enable_nova_metadata.return_value = True + self.enable_local_dhcp.return_value = True git_requested.return_value = False self.get_shared_secret.return_value = 'secret' self._call_hook('neutron-plugin-relation-joined') diff --git a/unit_tests/test_neutron_ovs_utils.py b/unit_tests/test_neutron_ovs_utils.py index 20e6208c..058a9c45 100644 --- a/unit_tests/test_neutron_ovs_utils.py +++ b/unit_tests/test_neutron_ovs_utils.py @@ -18,8 +18,11 @@ import charmhelpers.core.hookenv as hookenv TO_PATCH = [ 'add_bridge', 'add_bridge_port', + 'apt_install', + 'apt_update', 'config', 'os_release', + 'filter_installed_packages', 'neutron_plugin_attribute', 'full_restart', 'service_restart', @@ -75,12 +78,20 @@ class TestNeutronOVSUtils(CharmTestCase): # Reset cached cache hookenv.cache = {} + @patch.object(nutils, 'determine_packages') + def test_install_packages(self, _determine_packages): + _determine_packages.return_value = 'randompkg' + nutils.install_packages() + self.apt_update.assert_called_with() + self.apt_install.assert_called_with(self.filter_installed_packages()) + @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_packages(self, _head_pkgs, _os_rel, _git_requested, _use_dvr): + self.test_config.set('enable-local-dhcp-and-metadata', False) _git_requested.return_value = False _use_dvr.return_value = False _os_rel.return_value = 'trusty' @@ -89,6 +100,36 @@ class TestNeutronOVSUtils(CharmTestCase): expect = [['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_packages_metadata(self, _head_pkgs, _os_rel, + _git_requested, _use_dvr): + self.test_config.set('enable-local-dhcp-and-metadata', True) + _git_requested.return_value = False + _use_dvr.return_value = False + _os_rel.return_value = 'trusty' + _head_pkgs.return_value = head_pkg + pkg_list = nutils.determine_packages() + expect = [['neutron-plugin-openvswitch-agent'], [head_pkg], + 'neutron-metadata-agent', 'neutron-dhcp-agent'] + 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_packages_git(self, _head_pkgs, _os_rel, + _git_requested, _use_dvr): + self.test_config.set('enable-local-dhcp-and-metadata', False) + _git_requested.return_value = True + _use_dvr.return_value = True + _os_rel.return_value = 'trusty' + _head_pkgs.return_value = head_pkg + pkg_list = nutils.determine_packages() + self.assertFalse('neutron-l3-agent' in pkg_list) + @patch.object(nutils, 'use_dvr') def test_register_configs(self, _use_dvr): class _mock_OSConfigRenderer(): @@ -128,6 +169,19 @@ 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_local_dhcp') + @patch.object(nutils, 'use_dvr') + def test_resource_map_dhcp(self, _use_dvr, _enable_local_dhcp): + _enable_local_dhcp.return_value = True + _use_dvr.return_value = False + _map = nutils.resource_map() + svcs = ['neutron-plugin-openvswitch-agent', 'neutron-metadata-agent', + 'neutron-dhcp-agent'] + confs = [nutils.NEUTRON_CONF, nutils.NEUTRON_METADATA_AGENT_CONF, + nutils.NEUTRON_DHCP_AGENT_CONF] + [self.assertIn(q_conf, _map.keys()) for q_conf in confs] + self.assertEqual(_map[nutils.NEUTRON_CONF]['services'], svcs) + @patch.object(nutils, 'use_dvr') def test_restart_map(self, _use_dvr): _use_dvr.return_value = False @@ -213,7 +267,7 @@ class TestNeutronOVSUtils(CharmTestCase): ]) self.add_bridge_port.assert_called_with('br-ex', 'eth0') - @patch.object(neutron_ovs_context, 'DVRSharedSecretContext') + @patch.object(neutron_ovs_context, 'SharedSecretContext') def test_get_shared_secret(self, _dvr_secret_ctxt): _dvr_secret_ctxt.return_value = \ DummyContext(return_value={'shared_secret': 'supersecret'}) From b07b9bb64b997d7d2378c28636e98125a7cbfc63 Mon Sep 17 00:00:00 2001 From: Liam Young Date: Tue, 8 Sep 2015 15:36:08 +0100 Subject: [PATCH 4/9] Fix determine_packages --- hooks/neutron_ovs_utils.py | 5 ++++- unit_tests/test_neutron_ovs_utils.py | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/hooks/neutron_ovs_utils.py b/hooks/neutron_ovs_utils.py index 996cc54b..41255044 100644 --- a/hooks/neutron_ovs_utils.py +++ b/hooks/neutron_ovs_utils.py @@ -141,7 +141,10 @@ def install_packages(): def determine_packages(): - pkgs = neutron_plugin_attribute('ovs', 'packages', 'neutron') + pkgs = [] + plugin_pkgs = neutron_plugin_attribute('ovs', 'packages', 'neutron') + for plugin_pkg in plugin_pkgs: + pkgs.extend(plugin_pkg) if use_dvr(): pkgs.extend(DVR_PACKAGES) if enable_local_dhcp(): diff --git a/unit_tests/test_neutron_ovs_utils.py b/unit_tests/test_neutron_ovs_utils.py index 058a9c45..085ed405 100644 --- a/unit_tests/test_neutron_ovs_utils.py +++ b/unit_tests/test_neutron_ovs_utils.py @@ -97,7 +97,7 @@ class TestNeutronOVSUtils(CharmTestCase): _os_rel.return_value = 'trusty' _head_pkgs.return_value = head_pkg pkg_list = nutils.determine_packages() - expect = [['neutron-plugin-openvswitch-agent'], [head_pkg]] + expect = ['neutron-plugin-openvswitch-agent', head_pkg] self.assertItemsEqual(pkg_list, expect) @patch.object(nutils, 'use_dvr') @@ -112,7 +112,7 @@ class TestNeutronOVSUtils(CharmTestCase): _os_rel.return_value = 'trusty' _head_pkgs.return_value = head_pkg pkg_list = nutils.determine_packages() - expect = [['neutron-plugin-openvswitch-agent'], [head_pkg], + expect = ['neutron-plugin-openvswitch-agent', head_pkg, 'neutron-metadata-agent', 'neutron-dhcp-agent'] self.assertItemsEqual(pkg_list, expect) From a50e1024df12b3e94a3b4b1544f76b6199b2869c Mon Sep 17 00:00:00 2001 From: Liam Young Date: Tue, 8 Sep 2015 15:52:52 +0100 Subject: [PATCH 5/9] Fix sharedsecret context bug looking for wrong param --- hooks/neutron_ovs_context.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hooks/neutron_ovs_context.py b/hooks/neutron_ovs_context.py index 3b24ef79..1ba8a84a 100644 --- a/hooks/neutron_ovs_context.py +++ b/hooks/neutron_ovs_context.py @@ -111,7 +111,8 @@ def get_shared_secret(): class SharedSecretContext(OSContextGenerator): def __call__(self): - if NeutronAPIContext()()['enable_dvr'] or config('enable-metadata'): + if NeutronAPIContext()()['enable_dvr'] or \ + config('enable-local-dhcp-and-metadata'): ctxt = { 'shared_secret': get_shared_secret(), 'local_ip': resolve_address(), From 8a01f1ee271d9bd60934d2bab7c56ca40bdddbae Mon Sep 17 00:00:00 2001 From: Liam Young Date: Wed, 9 Sep 2015 11:07:43 +0100 Subject: [PATCH 6/9] Add discription to enable-local-dhcp-and-metadata config option --- config.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config.yaml b/config.yaml index 47dae983..0eb8e891 100644 --- a/config.yaml +++ b/config.yaml @@ -101,3 +101,6 @@ options: enable-local-dhcp-and-metadata: type: boolean default: false + description: | + Enable a local dhcp server which also serves metadata. Useful for + deployments which do not include a neutron-gateway. From d87daa8805398eaba6e3b57ab19b296e6b69a2d4 Mon Sep 17 00:00:00 2001 From: Liam Young Date: Sat, 12 Sep 2015 09:58:58 +0100 Subject: [PATCH 7/9] Purge dhcp packages when no longer required --- hooks/neutron_ovs_hooks.py | 10 +++++----- hooks/neutron_ovs_utils.py | 14 +++++++++++++- unit_tests/test_neutron_ovs_hooks.py | 4 ++-- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/hooks/neutron_ovs_hooks.py b/hooks/neutron_ovs_hooks.py index 064c711b..6f656368 100755 --- a/hooks/neutron_ovs_hooks.py +++ b/hooks/neutron_ovs_hooks.py @@ -20,15 +20,12 @@ from charmhelpers.core.host import ( restart_on_change ) -from charmhelpers.fetch import ( - apt_purge, -) - from charmhelpers.contrib.openstack.utils import ( os_requires_version, ) from neutron_ovs_utils import ( + DHCP_PACKAGES, DVR_PACKAGES, configure_ovs, git_install, @@ -40,6 +37,7 @@ from neutron_ovs_utils import ( enable_nova_metadata, enable_local_dhcp, install_packages, + purge_packages, ) hooks = Hooks() @@ -75,7 +73,7 @@ def neutron_plugin_api_changed(): if use_dvr(): install_packages() else: - apt_purge(DVR_PACKAGES, fatal=True) + purge_packages(DVR_PACKAGES) configure_ovs() CONFIGS.write_all() # If dvr setting has changed, need to pass that on @@ -87,6 +85,8 @@ def neutron_plugin_api_changed(): def neutron_plugin_joined(relation_id=None): if enable_local_dhcp(): install_packages() + else: + purge_packages(DHCP_PACKAGES) secret = get_shared_secret() if enable_nova_metadata() else None rel_data = { 'metadata-shared-secret': secret, diff --git a/hooks/neutron_ovs_utils.py b/hooks/neutron_ovs_utils.py index 41255044..b53f8df1 100644 --- a/hooks/neutron_ovs_utils.py +++ b/hooks/neutron_ovs_utils.py @@ -45,6 +45,7 @@ from charmhelpers.core.templating import render from charmhelpers.fetch import ( apt_install, + apt_purge, apt_update, filter_installed_packages, ) @@ -82,6 +83,7 @@ ML2_CONF = '%s/plugins/ml2/ml2_conf.ini' % NEUTRON_CONF_DIR EXT_PORT_CONF = '/etc/init/ext-port.conf' NEUTRON_METADATA_AGENT_CONF = "/etc/neutron/metadata_agent.ini" DVR_PACKAGES = ['neutron-l3-agent'] +DHCP_PACKAGES = ['neutron-metadata-agent', 'neutron-dhcp-agent'] PHY_NIC_MTU_CONF = '/etc/init/os-charm-phy-nic-mtu.conf' TEMPLATES = 'templates/' @@ -140,6 +142,16 @@ def install_packages(): apt_install(filter_installed_packages(determine_packages())) +def purge_packages(pkg_list): + purge_pkgs = [] + required_packages = determine_packages() + for pkg in pkg_list: + if pkg not in required_packages: + purge_pkgs.append(pkg) + if purge_pkgs: + apt_purge(purge_pkgs, fatal=True) + + def determine_packages(): pkgs = [] plugin_pkgs = neutron_plugin_attribute('ovs', 'packages', 'neutron') @@ -148,7 +160,7 @@ def determine_packages(): if use_dvr(): pkgs.extend(DVR_PACKAGES) if enable_local_dhcp(): - pkgs.extend(['neutron-metadata-agent', 'neutron-dhcp-agent']) + pkgs.extend(DHCP_PACKAGES) if git_install_requested(): pkgs.extend(BASE_GIT_PACKAGES) diff --git a/unit_tests/test_neutron_ovs_hooks.py b/unit_tests/test_neutron_ovs_hooks.py index 3df985ca..06cb4450 100644 --- a/unit_tests/test_neutron_ovs_hooks.py +++ b/unit_tests/test_neutron_ovs_hooks.py @@ -19,7 +19,6 @@ utils.register_configs = _reg utils.restart_map = _map TO_PATCH = [ - 'apt_purge', 'config', 'CONFIGS', 'get_shared_secret', @@ -30,6 +29,7 @@ TO_PATCH = [ 'configure_ovs', 'use_dvr', 'install_packages', + 'purge_packages', 'enable_nova_metadata', 'enable_local_dhcp', ] @@ -137,7 +137,7 @@ class NeutronOVSHooksTests(CharmTestCase): self.configure_ovs.assert_called_with() self.assertTrue(self.CONFIGS.write_all.called) _plugin_joined.assert_called_with(relation_id='rid') - self.apt_purge.assert_called_with(['neutron-l3-agent'], fatal=True) + self.purge_packages.assert_called_with(['neutron-l3-agent']) @patch.object(hooks, 'git_install_requested') def test_neutron_plugin_joined(self, git_requested): From 8f41b9a7227bf268e50f47e96f70a1bc13e2d00c Mon Sep 17 00:00:00 2001 From: Liam Young Date: Sat, 12 Sep 2015 10:02:12 +0100 Subject: [PATCH 8/9] Fix new config option description following mp feedback --- config.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config.yaml b/config.yaml index 0eb8e891..c0a26c33 100644 --- a/config.yaml +++ b/config.yaml @@ -103,4 +103,5 @@ options: default: false description: | Enable a local dhcp server which also serves metadata. Useful for - deployments which do not include a neutron-gateway. + deployments which do not include a neutron-gateway. This is a good option + for VLAN provider network management. From b395aa4e90dfbb4960e7dfc8eac43e980fc21497 Mon Sep 17 00:00:00 2001 From: Liam Young Date: Sat, 12 Sep 2015 10:03:56 +0100 Subject: [PATCH 9/9] Fix enable_nova_metadata() after mp feedback --- hooks/neutron_ovs_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hooks/neutron_ovs_utils.py b/hooks/neutron_ovs_utils.py index b53f8df1..1acd1c4a 100644 --- a/hooks/neutron_ovs_utils.py +++ b/hooks/neutron_ovs_utils.py @@ -256,7 +256,7 @@ def use_dvr(): def enable_nova_metadata(): - return use_dvr() or config('enable-local-dhcp-and-metadata') + return use_dvr() or enable_local_dhcp() def enable_local_dhcp():