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
This commit is contained in:
parent
f94126739a
commit
3640328972
|
@ -11,7 +11,9 @@
|
||||||
# dhcp-agent
|
# dhcp-agent
|
||||||
ip_exec_dnsmasq: DnsmasqNetnsFilter, /sbin/ip, root
|
ip_exec_dnsmasq: DnsmasqNetnsFilter, /sbin/ip, root
|
||||||
dnsmasq: DnsmasqFilter, /sbin/dnsmasq, root
|
dnsmasq: DnsmasqFilter, /sbin/dnsmasq, root
|
||||||
|
dnsmasq_ver: DnsmasqVersionFilter, /sbin/dnsmasq, root
|
||||||
dnsmasq_usr: DnsmasqFilter, /usr/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
|
# dhcp-agent uses kill as well, that's handled by the generic KillFilter
|
||||||
# it looks like these are the only signals needed, per
|
# it looks like these are the only signals needed, per
|
||||||
# quantum/agent/linux/dhcp.py
|
# quantum/agent/linux/dhcp.py
|
||||||
|
|
|
@ -80,6 +80,7 @@ class DhcpAgent(manager.Manager):
|
||||||
self.device_manager = DeviceManager(self.conf, self.plugin_rpc)
|
self.device_manager = DeviceManager(self.conf, self.plugin_rpc)
|
||||||
self.lease_relay = DhcpLeaseRelay(self.update_lease)
|
self.lease_relay = DhcpLeaseRelay(self.update_lease)
|
||||||
|
|
||||||
|
self.dhcp_driver_cls.check_version(self.root_helper)
|
||||||
self._populate_networks_cache()
|
self._populate_networks_cache()
|
||||||
|
|
||||||
def _populate_networks_cache(self):
|
def _populate_networks_cache(self):
|
||||||
|
|
|
@ -100,6 +100,12 @@ class DhcpBase(object):
|
||||||
|
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def check_version(cls, root_helper):
|
||||||
|
"""Execute version checks on DHCP server."""
|
||||||
|
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
class DhcpLocalProcess(DhcpBase):
|
class DhcpLocalProcess(DhcpBase):
|
||||||
PORTS = []
|
PORTS = []
|
||||||
|
@ -215,6 +221,26 @@ class Dnsmasq(DhcpLocalProcess):
|
||||||
|
|
||||||
QUANTUM_NETWORK_ID_KEY = 'QUANTUM_NETWORK_ID'
|
QUANTUM_NETWORK_ID_KEY = 'QUANTUM_NETWORK_ID'
|
||||||
QUANTUM_RELAY_SOCKET_PATH_KEY = 'QUANTUM_RELAY_SOCKET_PATH'
|
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
|
@classmethod
|
||||||
def existing_dhcp_networks(cls, conf, root_helper):
|
def existing_dhcp_networks(cls, conf, root_helper):
|
||||||
|
|
|
@ -106,6 +106,12 @@ class DnsmasqFilter(CommandFilter):
|
||||||
return env
|
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):
|
class DnsmasqNetnsFilter(DnsmasqFilter):
|
||||||
"""Specific filter for the dnsmasq call (which includes env)."""
|
"""Specific filter for the dnsmasq call (which includes env)."""
|
||||||
|
|
||||||
|
|
|
@ -140,6 +140,10 @@ class TestDhcpBase(base.BaseTestCase):
|
||||||
dhcp.DhcpBase.existing_dhcp_networks,
|
dhcp.DhcpBase.existing_dhcp_networks,
|
||||||
None, None)
|
None, None)
|
||||||
|
|
||||||
|
def test_check_version_abstract_error(self):
|
||||||
|
self.assertRaises(NotImplementedError,
|
||||||
|
dhcp.DhcpBase.check_version, None)
|
||||||
|
|
||||||
def test_base_abc_error(self):
|
def test_base_abc_error(self):
|
||||||
self.assertRaises(TypeError, dhcp.DhcpBase, None)
|
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)
|
mock_listdir.assert_called_once_with(path)
|
||||||
self.assertEquals(['aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'],
|
self.assertEquals(['aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'],
|
||||||
result)
|
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)
|
||||||
|
|
Loading…
Reference in New Issue