From: armando-migliaccio Date: Wed, 8 May 2013 00:10:22 +0000 (-0700) Subject: Log a warning if dnsmasq version is below the minimum required X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=364032897293256436647cb89c61a3dffb408946;p=openstack-build%2Fneutron-build.git Log a warning if dnsmasq version is below the minimum required It has been noted that older versions of dnsmasq may have unexpected behavior, so this patch introduces a check on dnsmasq version; if the minimum version is not met, a warning is logged. This is less invasive than raising an Exception and abort the dhcp agent, even though this also seems like a perfectly acceptable behavior. Fixes bug 1170793 Change-Id: Idd91c3753fb05f223ed0e3c53ad692ee65ea4905 --- diff --git a/etc/quantum/rootwrap.d/dhcp.filters b/etc/quantum/rootwrap.d/dhcp.filters index 89abb02ad..8e78063cf 100644 --- a/etc/quantum/rootwrap.d/dhcp.filters +++ b/etc/quantum/rootwrap.d/dhcp.filters @@ -11,7 +11,9 @@ # dhcp-agent ip_exec_dnsmasq: DnsmasqNetnsFilter, /sbin/ip, root dnsmasq: DnsmasqFilter, /sbin/dnsmasq, root +dnsmasq_ver: DnsmasqVersionFilter, /sbin/dnsmasq, root dnsmasq_usr: DnsmasqFilter, /usr/sbin/dnsmasq, root +dnsmasq_usr_ver: DnsmasqVersionFilter, /usr/sbin/dnsmasq, root # dhcp-agent uses kill as well, that's handled by the generic KillFilter # it looks like these are the only signals needed, per # quantum/agent/linux/dhcp.py diff --git a/quantum/agent/dhcp_agent.py b/quantum/agent/dhcp_agent.py index 7c64d8d82..00629c2a2 100644 --- a/quantum/agent/dhcp_agent.py +++ b/quantum/agent/dhcp_agent.py @@ -80,6 +80,7 @@ class DhcpAgent(manager.Manager): self.device_manager = DeviceManager(self.conf, self.plugin_rpc) self.lease_relay = DhcpLeaseRelay(self.update_lease) + self.dhcp_driver_cls.check_version(self.root_helper) self._populate_networks_cache() def _populate_networks_cache(self): diff --git a/quantum/agent/linux/dhcp.py b/quantum/agent/linux/dhcp.py index 4f834a1ea..95c9f14ed 100644 --- a/quantum/agent/linux/dhcp.py +++ b/quantum/agent/linux/dhcp.py @@ -100,6 +100,12 @@ class DhcpBase(object): raise NotImplementedError + @classmethod + def check_version(cls, root_helper): + """Execute version checks on DHCP server.""" + + raise NotImplementedError + class DhcpLocalProcess(DhcpBase): PORTS = [] @@ -215,6 +221,26 @@ class Dnsmasq(DhcpLocalProcess): QUANTUM_NETWORK_ID_KEY = 'QUANTUM_NETWORK_ID' QUANTUM_RELAY_SOCKET_PATH_KEY = 'QUANTUM_RELAY_SOCKET_PATH' + MINIMUM_VERSION = 2.59 + + @classmethod + def check_version(cls, root_helper): + is_valid_version = None + try: + cmd = ['dnsmasq', '--version'] + out = utils.execute(cmd, root_helper) + ver = re.findall("\d+.\d+", out)[0] + is_valid_version = float(ver) >= cls.MINIMUM_VERSION + if not is_valid_version: + LOG.warning(_('FAILED VERSION REQUIREMENT FOR DNSMASQ. ' + 'DHCP AGENT MAY NOT RUN CORRECTLY! ' + 'Please ensure that its version is %s ' + 'or above!'), cls.MINIMUM_VERSION) + except (RuntimeError, IndexError, ValueError): + LOG.warning(_('Unable to determine dnsmasq version. ' + 'Please ensure that its version is %s ' + 'or above!'), cls.MINIMUM_VERSION) + return is_valid_version @classmethod def existing_dhcp_networks(cls, conf, root_helper): diff --git a/quantum/rootwrap/filters.py b/quantum/rootwrap/filters.py index 28b5e1bd3..3aee87a78 100644 --- a/quantum/rootwrap/filters.py +++ b/quantum/rootwrap/filters.py @@ -106,6 +106,12 @@ class DnsmasqFilter(CommandFilter): return env +class DnsmasqVersionFilter(CommandFilter): + """Specific filter to check dnsmasq version.""" + def match(self, userargs): + return userargs[0] == "dnsmasq" and userargs[1] == "--version" + + class DnsmasqNetnsFilter(DnsmasqFilter): """Specific filter for the dnsmasq call (which includes env).""" diff --git a/quantum/tests/unit/test_linux_dhcp.py b/quantum/tests/unit/test_linux_dhcp.py index 414b197b1..c5331b169 100644 --- a/quantum/tests/unit/test_linux_dhcp.py +++ b/quantum/tests/unit/test_linux_dhcp.py @@ -140,6 +140,10 @@ class TestDhcpBase(base.BaseTestCase): dhcp.DhcpBase.existing_dhcp_networks, None, None) + def test_check_version_abstract_error(self): + self.assertRaises(NotImplementedError, + dhcp.DhcpBase.check_version, None) + def test_base_abc_error(self): self.assertRaises(TypeError, dhcp.DhcpBase, None) @@ -712,3 +716,21 @@ tag:tag1,option:classless-static-route,%s,%s""".lstrip() % (fake_v6, mock_listdir.assert_called_once_with(path) self.assertEquals(['aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'], result) + + def _check_version(self, cmd_out, expected_value): + with mock.patch('quantum.agent.linux.utils.execute') as cmd: + cmd.return_value = cmd_out + result = dhcp.Dnsmasq.check_version('sudo') + self.assertEqual(result, expected_value) + + def test_check_minimum_version(self): + self._check_version('Dnsmasq version 2.59 Copyright (c)...', True) + + def test_check_future_version(self): + self._check_version('Dnsmasq version 2.65 Copyright (c)...', True) + + def test_check_fail_version(self): + self._check_version('Dnsmasq version 2.48 Copyright (c)...', False) + + def test_check_version_failed_cmd_execution(self): + self._check_version('Error while executing command', None)