]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
DHCP agent should check interface is UP before adding route
authorrossella <rsblendido@suse.com>
Mon, 7 Apr 2014 15:53:34 +0000 (15:53 +0000)
committerrossella <rsblendido@suse.com>
Mon, 14 Apr 2014 13:57:33 +0000 (13:57 +0000)
The DHCP agent should check not only that an interface for
network's DHCP exists but also make sure that is UP before
adding a default route.
For this purpose a method "ensure_device_is_ready" was
added to ip_lib.

Change-Id: I9af06aa0f39634fe7b63c064337cd4191db5c026
Closes-bug: #1302312

neutron/agent/linux/dhcp.py
neutron/agent/linux/ip_lib.py
neutron/tests/unit/test_dhcp_agent.py
neutron/tests/unit/test_linux_ip_lib.py

index 81a9b17dab914b9f30d459e313fe9042f139b8da..3a26dc263b98f1c0fd3d8774150db6e3975445ee 100644 (file)
@@ -815,9 +815,9 @@ class DeviceManager(object):
         port = self.setup_dhcp_port(network)
         interface_name = self.get_interface_name(network, port)
 
-        if ip_lib.device_exists(interface_name,
-                                self.root_helper,
-                                network.namespace):
+        if ip_lib.ensure_device_is_ready(interface_name,
+                                         self.root_helper,
+                                         network.namespace):
             LOG.debug(_('Reusing existing device: %s.'), interface_name)
         else:
             self.driver.plug(network.id,
index 9b7f2c8615e569c2d554ed4078ab42f0931f09d3..9b259a163c8e121f1fbc118422b9869fb95a4c37 100644 (file)
@@ -482,6 +482,17 @@ def device_exists(device_name, root_helper=None, namespace=None):
     return bool(address)
 
 
+def ensure_device_is_ready(device_name, root_helper=None, namespace=None):
+    dev = IPDevice(device_name, root_helper, namespace)
+    try:
+        # Ensure the device is up, even if it is already up. If the device
+        # doesn't exist, a RuntimeError will be raised.
+        dev.link.set_up()
+    except RuntimeError:
+        return False
+    return True
+
+
 def iproute_arg_supported(command, arg, root_helper=None):
     command += ['help']
     stdout, stderr = utils.execute(command, root_helper=root_helper,
index 61b63d4b256d5090981c54c668427c705e740efe..f34a1650485cccfa86f44d4e8837bfb156d5e4e5 100644 (file)
@@ -1088,9 +1088,9 @@ class TestDeviceManager(base.BaseTestCase):
         cfg.CONF.set_override('use_namespaces', True)
         cfg.CONF.set_override('enable_isolated_metadata', True)
 
-        self.device_exists_p = mock.patch(
-            'neutron.agent.linux.ip_lib.device_exists')
-        self.device_exists = self.device_exists_p.start()
+        self.ensure_device_is_ready_p = mock.patch(
+            'neutron.agent.linux.ip_lib.ensure_device_is_ready')
+        self.ensure_device_is_ready = (self.ensure_device_is_ready_p.start())
 
         self.dvr_cls_p = mock.patch('neutron.agent.linux.interface.NullDriver')
         self.iproute_cls_p = mock.patch('neutron.agent.linux.'
@@ -1104,13 +1104,13 @@ class TestDeviceManager(base.BaseTestCase):
         driver_cls.return_value = self.mock_driver
         iproute_cls.return_value = self.mock_iproute
 
-    def _test_setup_helper(self, device_exists, net=None, port=None):
+    def _test_setup_helper(self, device_is_ready, net=None, port=None):
         net = net or fake_network
         port = port or fake_port1
         plugin = mock.Mock()
         plugin.create_dhcp_port.return_value = port or fake_port1
         plugin.get_dhcp_port.return_value = port or fake_port1
-        self.device_exists.return_value = device_exists
+        self.ensure_device_is_ready.return_value = device_is_ready
         self.mock_driver.get_device_name.return_value = 'tap12345678-12'
 
         dh = dhcp.DeviceManager(cfg.CONF, cfg.CONF.root_helper, plugin)
@@ -1135,7 +1135,7 @@ class TestDeviceManager(base.BaseTestCase):
                 expected_ips,
                 namespace=net.namespace)]
 
-        if not device_exists:
+        if not device_is_ready:
             expected.insert(1,
                             mock.call.plug(net.id,
                                            port.id,
@@ -1152,7 +1152,7 @@ class TestDeviceManager(base.BaseTestCase):
         cfg.CONF.set_override('enable_metadata_network', True)
         self._test_setup_helper(False)
 
-    def test_setup_device_exists(self):
+    def test_setup_device_is_ready(self):
         self._test_setup_helper(True)
 
     def test_create_dhcp_port_raise_conflict(self):
index 7d56c01b0f4cf713359749570571a4a6c621a917..c0ae7f4a9e12b4534cdfe51959cc87acbc01ef20 100644 (file)
@@ -789,3 +789,13 @@ class TestDeviceExists(base.BaseTestCase):
             _execute.return_value = ''
             _execute.side_effect = RuntimeError
             self.assertFalse(ip_lib.device_exists('eth0'))
+
+    def test_ensure_device_is_ready(self):
+        ip_lib_mock = mock.Mock()
+        with mock.patch.object(ip_lib, 'IPDevice', return_value=ip_lib_mock):
+            self.assertTrue(ip_lib.ensure_device_is_ready("eth0"))
+            self.assertTrue(ip_lib_mock.link.set_up.called)
+            ip_lib_mock.reset_mock()
+            # device doesn't exists
+            ip_lib_mock.link.set_up.side_effect = RuntimeError
+            self.assertFalse(ip_lib.ensure_device_is_ready("eth0"))