From: rossella Date: Mon, 7 Apr 2014 15:53:34 +0000 (+0000) Subject: DHCP agent should check interface is UP before adding route X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=4e9d4824050eedfd1495469a69e28864b6fec757;p=openstack-build%2Fneutron-build.git DHCP agent should check interface is UP before adding route 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 --- diff --git a/neutron/agent/linux/dhcp.py b/neutron/agent/linux/dhcp.py index 81a9b17da..3a26dc263 100644 --- a/neutron/agent/linux/dhcp.py +++ b/neutron/agent/linux/dhcp.py @@ -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, diff --git a/neutron/agent/linux/ip_lib.py b/neutron/agent/linux/ip_lib.py index 9b7f2c861..9b259a163 100644 --- a/neutron/agent/linux/ip_lib.py +++ b/neutron/agent/linux/ip_lib.py @@ -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, diff --git a/neutron/tests/unit/test_dhcp_agent.py b/neutron/tests/unit/test_dhcp_agent.py index 61b63d4b2..f34a16504 100644 --- a/neutron/tests/unit/test_dhcp_agent.py +++ b/neutron/tests/unit/test_dhcp_agent.py @@ -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): diff --git a/neutron/tests/unit/test_linux_ip_lib.py b/neutron/tests/unit/test_linux_ip_lib.py index 7d56c01b0..c0ae7f4a9 100644 --- a/neutron/tests/unit/test_linux_ip_lib.py +++ b/neutron/tests/unit/test_linux_ip_lib.py @@ -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"))