Merge "Add support for dnsmasq version 2.48"

This commit is contained in:
Jenkins 2013-05-17 09:00:57 +00:00 committed by Gerrit Code Review
commit 40aea92fcf
4 changed files with 53 additions and 20 deletions

View File

@ -80,7 +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.dhcp_version = self.dhcp_driver_cls.check_version()
self._populate_networks_cache()
def _populate_networks_cache(self):
@ -126,7 +126,8 @@ class DhcpAgent(manager.Manager):
network,
self.root_helper,
self.device_manager,
self._ns_name(network))
self._ns_name(network),
self.dhcp_version)
getattr(driver, action)()
return True

View File

@ -66,12 +66,13 @@ class DhcpBase(object):
__metaclass__ = abc.ABCMeta
def __init__(self, conf, network, root_helper='sudo',
device_delegate=None, namespace=None):
device_delegate=None, namespace=None, version=None):
self.conf = conf
self.network = network
self.root_helper = root_helper
self.device_delegate = device_delegate
self.namespace = namespace
self.version = version
@abc.abstractmethod
def enable(self):
@ -225,7 +226,7 @@ class Dnsmasq(DhcpLocalProcess):
@classmethod
def check_version(cls):
is_valid_version = None
ver = 0
try:
cmd = ['dnsmasq', '--version']
out = utils.execute(cmd)
@ -240,7 +241,7 @@ class Dnsmasq(DhcpLocalProcess):
LOG.warning(_('Unable to determine dnsmasq version. '
'Please ensure that its version is %s '
'or above!'), cls.MINIMUM_VERSION)
return is_valid_version
return float(ver)
@classmethod
def existing_dhcp_networks(cls, conf, root_helper):
@ -294,8 +295,12 @@ class Dnsmasq(DhcpLocalProcess):
# TODO(mark): how do we indicate other options
# ra-only, slaac, ra-nameservers, and ra-stateless.
mode = 'static'
cmd.append('--dhcp-range=set:%s,%s,%s,%ss' %
(self._TAG_PREFIX % i,
if self.version >= self.MINIMUM_VERSION:
set_tag = 'set:'
else:
set_tag = ''
cmd.append('--dhcp-range=%s%s,%s,%s,%ss' %
(set_tag, self._TAG_PREFIX % i,
netaddr.IPNetwork(subnet.cidr).network,
mode,
self.conf.dhcp_lease_time))
@ -423,7 +428,11 @@ class Dnsmasq(DhcpLocalProcess):
'quantum-dhcp-agent-dnsmasq-lease-update')
def _format_option(self, index, option_name, *args):
return ','.join(('tag:' + self._TAG_PREFIX % index,
if self.version >= self.MINIMUM_VERSION:
set_tag = 'tag:'
else:
set_tag = ''
return ','.join((set_tag + self._TAG_PREFIX % index,
'option:%s' % option_name) + args)
@classmethod

View File

@ -216,7 +216,8 @@ class TestDhcpAgent(base.BaseTestCase):
mock.ANY,
'sudo',
mock.ANY,
'qdhcp-1')
'qdhcp-1',
mock.ANY)
def test_call_driver_failure(self):
network = mock.Mock()
@ -231,7 +232,8 @@ class TestDhcpAgent(base.BaseTestCase):
mock.ANY,
'sudo',
mock.ANY,
'qdhcp-1')
'qdhcp-1',
mock.ANY)
self.assertEqual(log.call_count, 1)
self.assertTrue(dhcp.needs_resync)

View File

@ -448,7 +448,8 @@ class TestDnsmasq(TestBase):
argv.__getitem__.side_effect = fake_argv
dm = dhcp.Dnsmasq(self.conf, FakeDualNetwork(),
device_delegate=delegate,
namespace='qdhcp-ns')
namespace='qdhcp-ns',
version=float(2.59))
dm.spawn_process()
self.assertTrue(mocks['_output_opts_file'].called)
self.execute.assert_called_once_with(expected,
@ -486,7 +487,8 @@ tag:tag1,option:classless-static-route,%s,%s""".lstrip() % (fake_v6,
with mock.patch.object(dhcp.Dnsmasq, 'get_conf_file_name') as conf_fn:
conf_fn.return_value = '/foo/opts'
dm = dhcp.Dnsmasq(self.conf, FakeDualNetwork())
dm = dhcp.Dnsmasq(self.conf, FakeDualNetwork(),
version=float(2.59))
dm._output_opts_file()
self.safe.assert_called_once_with('/foo/opts', expected)
@ -498,7 +500,21 @@ tag:tag0,option:classless-static-route,20.0.0.1/24,20.0.0.1
tag:tag0,option:router,192.168.0.1""".lstrip()
with mock.patch.object(dhcp.Dnsmasq, 'get_conf_file_name') as conf_fn:
conf_fn.return_value = '/foo/opts'
dm = dhcp.Dnsmasq(self.conf, FakeDualNetworkSingleDHCP())
dm = dhcp.Dnsmasq(self.conf, FakeDualNetworkSingleDHCP(),
version=float(2.59))
dm._output_opts_file()
self.safe.assert_called_once_with('/foo/opts', expected)
def test_output_opts_file_single_dhcp_ver2_48(self):
expected = """
tag0,option:dns-server,8.8.8.8
tag0,option:classless-static-route,20.0.0.1/24,20.0.0.1
tag0,option:router,192.168.0.1""".lstrip()
with mock.patch.object(dhcp.Dnsmasq, 'get_conf_file_name') as conf_fn:
conf_fn.return_value = '/foo/opts'
dm = dhcp.Dnsmasq(self.conf, FakeDualNetworkSingleDHCP(),
version=float(2.48))
dm._output_opts_file()
self.safe.assert_called_once_with('/foo/opts', expected)
@ -510,7 +526,8 @@ tag:tag0,option:router""".lstrip()
with mock.patch.object(dhcp.Dnsmasq, 'get_conf_file_name') as conf_fn:
conf_fn.return_value = '/foo/opts'
dm = dhcp.Dnsmasq(self.conf, FakeV4NoGatewayNetwork())
dm = dhcp.Dnsmasq(self.conf, FakeV4NoGatewayNetwork(),
version=float(2.59))
with mock.patch.object(dm, '_make_subnet_interface_ip_map') as ipm:
ipm.return_value = {FakeV4SubnetNoGateway.id: '192.168.1.1'}
@ -549,7 +566,8 @@ tag:tag1,option:classless-static-route,%s,%s""".lstrip() % (fake_v6,
with mock.patch.object(dhcp.Dnsmasq, 'pid') as pid:
pid.__get__ = mock.Mock(return_value=5)
dm = dhcp.Dnsmasq(self.conf, FakeDualNetwork(),
namespace='qdhcp-ns')
namespace='qdhcp-ns',
version=float(2.59))
method_name = '_make_subnet_interface_ip_map'
with mock.patch.object(dhcp.Dnsmasq,
@ -590,7 +608,7 @@ tag:tag1,option:classless-static-route,%s,%s""".lstrip() % (fake_v6,
with mock.patch.object(dhcp.Dnsmasq, 'pid') as pid:
pid.__get__ = mock.Mock(return_value=5)
dm = dhcp.Dnsmasq(self.conf, FakeDualNetwork(),
namespace='qdhcp-ns')
namespace='qdhcp-ns', version=float(2.59))
method_name = '_make_subnet_interface_ip_map'
with mock.patch.object(dhcp.Dnsmasq, method_name) as ip_map:
@ -724,13 +742,16 @@ tag:tag1,option:classless-static-route,%s,%s""".lstrip() % (fake_v6,
self.assertEqual(result, expected_value)
def test_check_minimum_version(self):
self._check_version('Dnsmasq version 2.59 Copyright (c)...', True)
self._check_version('Dnsmasq version 2.59 Copyright (c)...',
float(2.59))
def test_check_future_version(self):
self._check_version('Dnsmasq version 2.65 Copyright (c)...', True)
self._check_version('Dnsmasq version 2.65 Copyright (c)...',
float(2.65))
def test_check_fail_version(self):
self._check_version('Dnsmasq version 2.48 Copyright (c)...', False)
self._check_version('Dnsmasq version 2.48 Copyright (c)...',
float(2.48))
def test_check_version_failed_cmd_execution(self):
self._check_version('Error while executing command', None)
self._check_version('Error while executing command', 0)