Plug Vif into Midonet using Neutron port binding

Currently Midokura uses its own script (mm-ctl) to bind ports. However, support
for using this script is left out of the nova and neutron projects. This causes
confusion and makes deployments unnecessarily complicated for customers using
Havana. This fix is to change nova to properly use mm-ctl. Corresponding
changes will be submitted to devstack and neutron.

Change-Id: I7c9edded5ab6fe19b63e54cd6905d9242e4a90cc
Closes-Bug: 1235132
This commit is contained in:
Joe Mills 2013-10-01 00:52:10 +09:00
parent 021175291b
commit 3fb9c58138
4 changed files with 77 additions and 0 deletions

View File

@ -45,6 +45,9 @@ ifc_ctl: CommandFilter, /opt/pg/bin/ifc_ctl, root
# nova/virt/libvirt/vif.py: 'ebrctl', ...
ebrctl: CommandFilter, ebrctl, root
# nova/virt/libvirt/vif.py: 'mm-ctl', ...
mm-ctl: CommandFilter, mm-ctl, root
# nova/network/linux_net.py: 'ebtables', '-D' ...
# nova/network/linux_net.py: 'ebtables', '-I' ...
ebtables: CommandFilter, ebtables, root

View File

@ -37,6 +37,7 @@ VIF_TYPE_BRIDGE = 'bridge'
VIF_TYPE_802_QBG = '802.1qbg'
VIF_TYPE_802_QBH = '802.1qbh'
VIF_TYPE_MLNX_DIRECT = 'mlnx_direct'
VIF_TYPE_MIDONET = 'midonet'
VIF_TYPE_OTHER = 'other'
# Constant for max length of network interface names

View File

@ -164,12 +164,24 @@ class LibvirtVifTestCase(test.TestCase):
subnet_bridge_6],
interface='eth0')
network_midonet = network_model.Network(id='network-id-xxx-yyy-zzz',
label=None,
bridge=None,
subnets=[subnet_bridge_4],
interface='eth0')
vif_mlnx = network_model.VIF(id='vif-xxx-yyy-zzz',
address='ca:fe:de:ad:be:ef',
network=network_mlnx,
type=network_model.VIF_TYPE_MLNX_DIRECT,
devname='tap-xxx-yyy-zzz')
vif_midonet = network_model.VIF(id='vif-xxx-yyy-zzz',
address='ca:fe:de:ad:be:ef',
network=network_midonet,
type=network_model.VIF_TYPE_MIDONET,
devname='tap-xxx-yyy-zzz')
instance = {
'name': 'instance-name',
'uuid': 'instance-uuid'
@ -514,6 +526,15 @@ class LibvirtVifTestCase(test.TestCase):
self._assertMacEquals(node, self.vif_mlnx)
self._assertModel(xml, "virtio")
def test_midonet_ethernet_vif_driver(self):
d = vif.LibvirtGenericVIFDriver(self._get_conn())
self.flags(firewall_driver="nova.virt.firewall.NoopFirewallDriver")
br_want = self.vif_midonet['devname']
xml = self._get_instance_xml(d, self.vif_midonet)
node = self._get_node(xml)
self._assertTypeAndMacEquals(node, "ethernet", "target", "dev",
self.vif_midonet, br_want)
def test_generic_8021qbh_driver(self):
d = vif.LibvirtGenericVIFDriver(self._get_conn())
xml = self._get_instance_xml(d, self.vif_8021qbh)

View File

@ -301,6 +301,17 @@ class LibvirtGenericVIFDriver(LibvirtBaseVIFDriver):
return conf
def get_config_midonet(self, instance, vif, image_meta,
inst_type):
conf = super(LibvirtGenericVIFDriver,
self).get_config(instance, vif,
image_meta, inst_type)
dev = self.get_vif_devname(vif)
designer.set_vif_host_backend_ethernet_config(conf, dev)
return conf
def get_config_mlnx_direct(self, instance, vif, image_meta,
inst_type):
conf = super(LibvirtGenericVIFDriver,
@ -359,6 +370,11 @@ class LibvirtGenericVIFDriver(LibvirtBaseVIFDriver):
vif,
image_meta,
inst_type)
elif vif_type == network_model.VIF_TYPE_MIDONET:
return self.get_config_midonet(instance,
vif,
image_meta,
inst_type)
else:
raise exception.NovaException(
_("Unexpected vif_type=%s") % vif_type)
@ -511,6 +527,22 @@ class LibvirtGenericVIFDriver(LibvirtBaseVIFDriver):
super(LibvirtGenericVIFDriver,
self).plug(instance, vif)
def plug_midonet(self, instance, vif):
"""Plug into MidoNet's network port
Bind the vif to a MidoNet virtual port.
"""
super(LibvirtGenericVIFDriver,
self).plug(instance, vif)
dev = self.get_vif_devname(vif)
port_id = vif['id']
try:
linux_net.create_tap_dev(dev)
utils.execute('mm-ctl', '--bind-port', port_id, dev,
run_as_root=True)
except processutils.ProcessExecutionError:
LOG.exception(_("Failed while plugging vif"), instance=instance)
def plug_iovisor(self, instance, vif):
"""Plug using PLUMgrid IO Visor Driver
@ -561,6 +593,8 @@ class LibvirtGenericVIFDriver(LibvirtBaseVIFDriver):
self.plug_iovisor(instance, vif)
elif vif_type == network_model.VIF_TYPE_MLNX_DIRECT:
self.plug_mlnx_direct(instance, vif)
elif vif_type == network_model.VIF_TYPE_MIDONET:
self.plug_midonet(instance, vif)
else:
raise exception.NovaException(
_("Unexpected vif_type=%s") % vif_type)
@ -675,6 +709,22 @@ class LibvirtGenericVIFDriver(LibvirtBaseVIFDriver):
super(LibvirtGenericVIFDriver,
self).unplug(instance, vif)
def unplug_midonet(self, instance, vif):
"""Unplug from MidoNet network port
Unbind the vif from a MidoNet virtual port.
"""
super(LibvirtGenericVIFDriver,
self).unplug(instance, vif)
dev = self.get_vif_devname(vif)
port_id = vif['id']
try:
utils.execute('mm-ctl', '--unbind-port', port_id,
run_as_root=True)
linux_net.delete_net_dev(dev)
except processutils.ProcessExecutionError:
LOG.exception(_("Failed while unplugging vif"), instance=instance)
def unplug_iovisor(self, instance, vif):
"""Unplug using PLUMgrid IO Visor Driver
@ -722,6 +772,8 @@ class LibvirtGenericVIFDriver(LibvirtBaseVIFDriver):
self.unplug_iovisor(instance, vif)
elif vif_type == network_model.VIF_TYPE_MLNX_DIRECT:
self.unplug_mlnx_direct(instance, vif)
elif vif_type == network_model.VIF_TYPE_MIDONET:
self.unplug_midonet(instance, vif)
else:
raise exception.NovaException(
_("Unexpected vif_type=%s") % vif_type)