def _ovs_add_port(self, bridge, device_name, port_id, mac_address,
internal=True):
- cmd = ['ovs-vsctl', '--', '--if-exists', 'del-port', device_name, '--',
- 'add-port', bridge, device_name]
+ attrs = [('external-ids:iface-id', port_id),
+ ('external-ids:iface-status', 'active'),
+ ('external-ids:attached-mac', mac_address)]
if internal:
- cmd += ['--', 'set', 'Interface', device_name, 'type=internal']
- cmd += ['--', 'set', 'Interface', device_name,
- 'external-ids:iface-id=%s' % port_id,
- '--', 'set', 'Interface', device_name,
- 'external-ids:iface-status=active',
- '--', 'set', 'Interface', device_name,
- 'external-ids:attached-mac=%s' % mac_address]
- utils.execute(cmd, self.root_helper)
+ attrs.insert(0, ('type', 'internal'))
+
+ ovs = ovs_lib.OVSBridge(bridge, self.root_helper)
+ ovs.replace_port(device_name, *attrs)
def plug(self, network_id, port_id, device_name, mac_address,
bridge=None, namespace=None, prefix=None):
port_name])
return self.get_port_ofport(port_name)
+ def replace_port(self, port_name, *interface_attr_tuples):
+ """Replace existing port or create it, and configure port interface."""
+ cmd = ['--', '--if-exists', 'del-port', port_name,
+ '--', 'add-port', self.br_name, port_name]
+ if interface_attr_tuples:
+ cmd += ['--', 'set', 'Interface', port_name]
+ cmd += ['%s=%s' % kv for kv in interface_attr_tuples]
+ self.run_vsctl(cmd)
+
def delete_port(self, port_name):
self.run_vsctl(["--", "--if-exists", "del-port", self.br_name,
port_name])
def _build_timeout_opt(self, exp_timeout):
return "--timeout=%d" % exp_timeout if exp_timeout else self.TO
+ def test_replace_port(self):
+ pname = "tap5"
+ self.br.replace_port(pname)
+ self.execute.assert_called_once_with(
+ ["ovs-vsctl", self.TO,
+ "--", "--if-exists", "del-port", pname,
+ "--", "add-port", self.BR_NAME, pname],
+ root_helper=self.root_helper)
+
+ def test_replace_port_with_attrs(self):
+ pname = "tap5"
+ self.br.replace_port(pname, ('type', 'internal'),
+ ('external-ids:iface-status', 'active'))
+ self.execute.assert_called_once_with(
+ ["ovs-vsctl", self.TO,
+ "--", "--if-exists", "del-port", pname,
+ "--", "add-port", self.BR_NAME, pname,
+ "--", "set", "Interface", pname,
+ "type=internal", "external-ids:iface-status=active"],
+ root_helper=self.root_helper)
+
def _test_delete_port(self, exp_timeout=None):
exp_timeout_str = self._build_timeout_opt(exp_timeout)
pname = "tap5"
from neutron.agent.linux import dhcp
from neutron.agent.linux import interface
from neutron.agent.linux import ip_lib
+from neutron.agent.linux import ovs_lib
from neutron.agent.linux import utils
from neutron.extensions import flavor
from neutron.openstack.common import uuidutils
def device_exists(dev, root_helper=None, namespace=None):
return dev == bridge
- vsctl_cmd = ['ovs-vsctl', '--', '--if-exists', 'del-port',
- 'tap0', '--', 'add-port',
- bridge, 'tap0', '--', 'set', 'Interface', 'tap0',
- 'type=internal', '--', 'set', 'Interface', 'tap0',
- 'external-ids:iface-id=port-1234', '--', 'set',
- 'Interface', 'tap0',
- 'external-ids:iface-status=active', '--', 'set',
- 'Interface', 'tap0',
- 'external-ids:attached-mac=aa:bb:cc:dd:ee:ff']
-
- with mock.patch.object(utils, 'execute') as execute:
+ with mock.patch.object(ovs_lib.OVSBridge, 'replace_port') as replace:
ovs = interface.OVSInterfaceDriver(self.conf)
self.device_exists.side_effect = device_exists
ovs.plug('01234567-1234-1234-99',
'aa:bb:cc:dd:ee:ff',
bridge=bridge,
namespace=namespace)
- execute.assert_called_once_with(vsctl_cmd, 'sudo')
+ replace.assert_called_once_with(
+ 'tap0',
+ ('type', 'internal'),
+ ('external-ids:iface-id', 'port-1234'),
+ ('external-ids:iface-status', 'active'),
+ ('external-ids:attached-mac', 'aa:bb:cc:dd:ee:ff'))
expected = [mock.call('sudo'),
mock.call().device('tap0'),
mock.call().add_veth('tap0', devname,
namespace2=namespace)]
- vsctl_cmd = ['ovs-vsctl', '--', '--if-exists', 'del-port',
- 'tap0', '--', 'add-port',
- bridge, 'tap0', '--', 'set', 'Interface', 'tap0',
- 'external-ids:iface-id=port-1234', '--', 'set',
- 'Interface', 'tap0',
- 'external-ids:iface-status=active', '--', 'set',
- 'Interface', 'tap0',
- 'external-ids:attached-mac=aa:bb:cc:dd:ee:ff']
- with mock.patch.object(utils, 'execute') as execute:
+ with mock.patch.object(ovs_lib.OVSBridge, 'replace_port') as replace:
ovs.plug('01234567-1234-1234-99',
'port-1234',
devname,
bridge=bridge,
namespace=namespace,
prefix=prefix)
- execute.assert_called_once_with(vsctl_cmd, 'sudo')
+ replace.assert_called_once_with(
+ 'tap0',
+ ('external-ids:iface-id', 'port-1234'),
+ ('external-ids:iface-status', 'active'),
+ ('external-ids:attached-mac', 'aa:bb:cc:dd:ee:ff'))
ns_dev.assert_has_calls(
[mock.call.link.set_address('aa:bb:cc:dd:ee:ff')])