]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Add support for dnsmasq version 2.48
authorGary Kotton <gkotton@redhat.com>
Tue, 14 May 2013 13:20:44 +0000 (13:20 +0000)
committerGary Kotton <gkotton@redhat.com>
Tue, 14 May 2013 13:53:31 +0000 (13:53 +0000)
Following the bug fix for bug 1170793 we are able to add
in support for dnsmasq versions that do not support tags.

2.48 is the version shipped in RHEL 6.4

Change-Id: Ia7d2b1c0adb477159ce146bcd4323d4b2795bff5

quantum/agent/dhcp_agent.py
quantum/agent/linux/dhcp.py
quantum/tests/unit/test_dhcp_agent.py
quantum/tests/unit/test_linux_dhcp.py

index f8f342c41deb1a2310fd40bd98f9e2e423ed4662..88d6e442a11cdf3d644863c4d34265deac61f527 100644 (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
 
index dde040f64bf3677c774ecde8900ae9ed3d3685e6..732fc1dc5a6f36f0fd4e8dcb959df967637b8787 100644 (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
index 2c96d6b800200ef338433e5328d45d403bf044cb..92be06c787c7fd65724ce3840a89a3a4bb183506 100644 (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)
 
index 7a4426fb6640638a500ed8fe8e9d3750d074ff08..5d745df347abcff19c69448fe0af8ca387616f21 100644 (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)