Merge "Add support for dnsmasq version 2.48" into stable/grizzly

This commit is contained in:
Jenkins 2013-05-29 13:31:26 +00:00 committed by Gerrit Code Review
commit e5c2c700a9
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):
@ -230,7 +231,7 @@ class Dnsmasq(DhcpLocalProcess):
@classmethod
def check_version(cls):
is_valid_version = None
ver = 0
try:
cmd = ['dnsmasq', '--version']
out = utils.execute(cmd)
@ -245,7 +246,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):
@ -299,8 +300,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))
@ -434,7 +439,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

@ -218,7 +218,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()
@ -233,7 +234,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

@ -450,7 +450,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,
@ -488,7 +489,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)
@ -500,7 +502,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)
@ -512,7 +528,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'}
@ -551,7 +568,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,
@ -593,7 +611,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:
@ -727,13 +745,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)