diff --git a/quantum/agent/linux/interface.py b/quantum/agent/linux/interface.py index 21a251a0d0..496f090545 100644 --- a/quantum/agent/linux/interface.py +++ b/quantum/agent/linux/interface.py @@ -265,18 +265,22 @@ class MetaInterfaceDriver(LinuxInterfaceDriver): self.conf.meta_flavor_driver_mappings.split(',')]: self.flavor_driver_map[flavor] = self._load_driver(driver_name) - def _get_driver_by_network_id(self, network_id): + def _get_flavor_by_network_id(self, network_id): network = self.quantum.show_network(network_id) - flavor = network['network'][FLAVOR_NETWORK] + return network['network'][FLAVOR_NETWORK] + + def _get_driver_by_network_id(self, network_id): + flavor = self._get_flavor_by_network_id(network_id) return self.flavor_driver_map[flavor] - def _get_driver_by_device_name(self, device_name, namespace=None): - device = ip_lib.IPDevice(device_name, self.root_helper, namespace) - mac_address = device.link.address - ports = self.quantum.list_ports(mac_address=mac_address) - if not ports.get('ports'): - raise Exception(_('No port for this device %s') % device_name) - return self._get_driver_by_network_id(ports['ports'][0]['network_id']) + def _set_device_plugin_tag(self, network_id, device_name, namespace=None): + plugin_tag = self._get_flavor_by_network_id(network_id) + device = ip_lib.IPDevice(device_name, self.conf.root_helper, namespace) + device.link.set_alias(plugin_tag) + + def _get_device_plugin_tag(self, device_name, namespace=None): + device = ip_lib.IPDevice(device_name, self.conf.root_helper, namespace) + return device.link.alias def get_device_name(self, port): driver = self._get_driver_by_network_id(port.network_id) @@ -285,11 +289,14 @@ class MetaInterfaceDriver(LinuxInterfaceDriver): def plug(self, network_id, port_id, device_name, mac_address, bridge=None, namespace=None, prefix=None): driver = self._get_driver_by_network_id(network_id) - return driver.plug(network_id, port_id, device_name, mac_address, - bridge=bridge, namespace=namespace, prefix=prefix) + ret = driver.plug(network_id, port_id, device_name, mac_address, + bridge=bridge, namespace=namespace, prefix=prefix) + self._set_device_plugin_tag(network_id, device_name, namespace) + return ret def unplug(self, device_name, bridge=None, namespace=None, prefix=None): - driver = self._get_driver_by_device_name(device_name, namespace=None) + plugin_tag = self._get_device_plugin_tag(device_name, namespace) + driver = self.flavor_driver_map[plugin_tag] return driver.unplug(device_name, bridge, namespace, prefix) def _load_driver(self, driver_provider): diff --git a/quantum/agent/linux/ip_lib.py b/quantum/agent/linux/ip_lib.py index 31337087e6..1f618c3f95 100644 --- a/quantum/agent/linux/ip_lib.py +++ b/quantum/agent/linux/ip_lib.py @@ -189,6 +189,9 @@ class IpLinkCommand(IpDeviceCommandBase): self._as_root('set', self.name, 'name', name) self._parent.name = name + def set_alias(self, alias_name): + self._as_root('set', self.name, 'alias', alias_name) + def delete(self): self._as_root('delete', self.name) @@ -212,6 +215,10 @@ class IpLinkCommand(IpDeviceCommandBase): def qlen(self): return self.attributes.get('qlen') + @property + def alias(self): + return self.attributes.get('alias') + @property def attributes(self): return self._parse_line(self._run('show', self.name, options='o')) diff --git a/quantum/plugins/metaplugin/meta_quantum_plugin.py b/quantum/plugins/metaplugin/meta_quantum_plugin.py index 7ec3ffe8f2..3c9cde6e66 100644 --- a/quantum/plugins/metaplugin/meta_quantum_plugin.py +++ b/quantum/plugins/metaplugin/meta_quantum_plugin.py @@ -258,7 +258,7 @@ class MetaPluginV2(db_base_plugin_v2.QuantumDbPluginV2, if l3_port_check: self.prevent_l3_port_deletion(context, id) self.disassociate_floatingips(context, id) - return plugin.delete_port(context, id) + return plugin.delete_port(context, id, l3_port_check) def create_subnet(self, context, subnet): s = subnet['subnet'] diff --git a/quantum/tests/unit/test_linux_interface.py b/quantum/tests/unit/test_linux_interface.py index 9e3ed5262b..f1c60f23b2 100644 --- a/quantum/tests/unit/test_linux_interface.py +++ b/quantum/tests/unit/test_linux_interface.py @@ -380,15 +380,35 @@ class TestMetaInterfaceDriver(TestBase): driver, interface.OVSInterfaceDriver)) - def test_get_driver_by_device_name(self): - device_address_p = mock.patch( - 'quantum.agent.linux.ip_lib.IpLinkCommand.address') - device_address = device_address_p.start() - device_address.return_value = 'aa:bb:cc:dd:ee:ffa' - + def test_set_device_plugin_tag(self): meta_interface = interface.MetaInterfaceDriver(self.conf) - driver = meta_interface._get_driver_by_device_name('test') - self.assertTrue(isinstance( - driver, - interface.OVSInterfaceDriver)) - device_address_p.stop() + driver = meta_interface._get_driver_by_network_id('test') + meta_interface._set_device_plugin_tag(driver, + 'tap0', + namespace=None) + expected = [mock.call('tap0', 'sudo', None), + mock.call().link.set_alias('fake1')] + self.ip_dev.assert_has_calls(expected) + namespace = '01234567-1234-1234-99' + meta_interface._set_device_plugin_tag(driver, + 'tap1', + namespace=namespace) + expected = [mock.call('tap1', 'sudo', '01234567-1234-1234-99'), + mock.call().link.set_alias('fake1')] + self.ip_dev.assert_has_calls(expected) + + def test_get_device_plugin_tag(self): + meta_interface = interface.MetaInterfaceDriver(self.conf) + self.ip_dev().link.alias = 'fake1' + plugin_tag0 = meta_interface._get_device_plugin_tag('tap0', + namespace=None) + expected = [mock.call('tap0', 'sudo', None)] + self.ip_dev.assert_has_calls(expected) + self.assertEquals('fake1', plugin_tag0) + namespace = '01234567-1234-1234-99' + expected = [mock.call('tap1', 'sudo', '01234567-1234-1234-99')] + plugin_tag1 = meta_interface._get_device_plugin_tag( + 'tap1', + namespace=namespace) + self.ip_dev.assert_has_calls(expected) + self.assertEquals('fake1', plugin_tag1) diff --git a/quantum/tests/unit/test_linux_ip_lib.py b/quantum/tests/unit/test_linux_ip_lib.py index cc54ff23cd..9d97a3a092 100644 --- a/quantum/tests/unit/test_linux_ip_lib.py +++ b/quantum/tests/unit/test_linux_ip_lib.py @@ -30,7 +30,8 @@ LINK_SAMPLE = [ '1: lo: mtu 16436 qdisc noqueue state UNKNOWN \\' 'link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00', '2: eth0: mtu 1500 qdisc mq state UP ' - 'qlen 1000\ link/ether cc:dd:ee:ff:ab:cd brd ff:ff:ff:ff:ff:ff', + 'qlen 1000\ link/ether cc:dd:ee:ff:ab:cd brd ff:ff:ff:ff:ff:ff' + '\ alias openvswitch', '3: br-int: mtu 1500 qdisc noop state DOWN ' '\ link/ether aa:bb:cc:dd:ee:ff brd ff:ff:ff:ff:ff:ff', '4: gw-ddc717df-49: mtu 1500 qdisc noop ' @@ -426,6 +427,10 @@ class TestIpLinkCommand(TestIPCmdBase): self._assert_sudo([], ('set', 'eth0', 'name', 'tap1')) self.assertEqual(self.parent.name, 'tap1') + def test_set_alias(self): + self.link_cmd.set_alias('openvswitch') + self._assert_sudo([], ('set', 'eth0', 'alias', 'openvswitch')) + def test_delete(self): self.link_cmd.delete() self._assert_sudo([], ('delete', 'eth0')) @@ -446,6 +451,10 @@ class TestIpLinkCommand(TestIPCmdBase): self.parent._execute = mock.Mock(return_value=LINK_SAMPLE[1]) self.assertEqual(self.link_cmd.qlen, 1000) + def test_alias_property(self): + self.parent._execute = mock.Mock(return_value=LINK_SAMPLE[1]) + self.assertEqual(self.link_cmd.alias, 'openvswitch') + def test_state_property(self): self.parent._execute = mock.Mock(return_value=LINK_SAMPLE[1]) self.assertEqual(self.link_cmd.state, 'UP') @@ -456,7 +465,8 @@ class TestIpLinkCommand(TestIPCmdBase): 'state': 'UP', 'qdisc': 'mq', 'brd': 'ff:ff:ff:ff:ff:ff', - 'link/ether': 'cc:dd:ee:ff:ab:cd'} + 'link/ether': 'cc:dd:ee:ff:ab:cd', + 'alias': 'openvswitch'} self.parent._execute = mock.Mock(return_value=LINK_SAMPLE[1]) self.assertEqual(self.link_cmd.attributes, expected) self._assert_call('o', ('show', 'eth0'))