Add 'devname' to nova.network.model.VIF class
Add a 'devname' field to nova.network.model.VIF to allow network drivers to specify a desired TAP device name. Update the Quantum driver to set a device name, and update the libvirt VIF drivers to honour it. Blueprint: libvirt-vif-driver Change-Id: Ia8dd546af36e7f6c22efd7c696fb58b37aac0061 Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
parent
8fddd6ad44
commit
fa96bbf489
@ -32,9 +32,10 @@ VIF_TYPE_802_QBG = '802.1qbg'
|
|||||||
VIF_TYPE_802_QBH = '802.1qbh'
|
VIF_TYPE_802_QBH = '802.1qbh'
|
||||||
VIF_TYPE_OTHER = 'other'
|
VIF_TYPE_OTHER = 'other'
|
||||||
|
|
||||||
# Constant for max length of 'bridge' in Network class
|
# Constant for max length of network interface names
|
||||||
# Chosen to match max Linux NIC name length
|
# eg 'bridge' in the Network class or 'devname' in
|
||||||
BRIDGE_NAME_LEN = 14
|
# the VIF class
|
||||||
|
NIC_NAME_LEN = 14
|
||||||
|
|
||||||
|
|
||||||
class Model(dict):
|
class Model(dict):
|
||||||
@ -206,13 +207,14 @@ class Network(Model):
|
|||||||
class VIF(Model):
|
class VIF(Model):
|
||||||
"""Represents a Virtual Interface in Nova."""
|
"""Represents a Virtual Interface in Nova."""
|
||||||
def __init__(self, id=None, address=None, network=None, type=None,
|
def __init__(self, id=None, address=None, network=None, type=None,
|
||||||
**kwargs):
|
devname=None, **kwargs):
|
||||||
super(VIF, self).__init__()
|
super(VIF, self).__init__()
|
||||||
|
|
||||||
self['id'] = id
|
self['id'] = id
|
||||||
self['address'] = address
|
self['address'] = address
|
||||||
self['network'] = network or None
|
self['network'] = network or None
|
||||||
self['type'] = type
|
self['type'] = type
|
||||||
|
self['devname'] = devname
|
||||||
|
|
||||||
self._set_meta(kwargs)
|
self._set_meta(kwargs)
|
||||||
|
|
||||||
@ -377,6 +379,7 @@ class NetworkInfo(list):
|
|||||||
'broadcast': str(subnet_v4.as_netaddr().broadcast),
|
'broadcast': str(subnet_v4.as_netaddr().broadcast),
|
||||||
'mac': vif['address'],
|
'mac': vif['address'],
|
||||||
'vif_type': vif['type'],
|
'vif_type': vif['type'],
|
||||||
|
'vif_devname': vif.get('devname'),
|
||||||
'vif_uuid': vif['id'],
|
'vif_uuid': vif['id'],
|
||||||
'rxtx_cap': vif.get_meta('rxtx_cap', 0),
|
'rxtx_cap': vif.get_meta('rxtx_cap', 0),
|
||||||
'dns': [get_ip(ip) for ip in subnet_v4['dns']],
|
'dns': [get_ip(ip) for ip in subnet_v4['dns']],
|
||||||
|
@ -593,7 +593,10 @@ class API(base.Base):
|
|||||||
bridge = "brq" + port['network_id']
|
bridge = "brq" + port['network_id']
|
||||||
|
|
||||||
if bridge is not None:
|
if bridge is not None:
|
||||||
bridge = bridge[:network_model.BRIDGE_NAME_LEN]
|
bridge = bridge[:network_model.NIC_NAME_LEN]
|
||||||
|
|
||||||
|
devname = "tap" + port['id']
|
||||||
|
devname = devname[:network_model.NIC_NAME_LEN]
|
||||||
|
|
||||||
network = network_model.Network(
|
network = network_model.Network(
|
||||||
id=port['network_id'],
|
id=port['network_id'],
|
||||||
@ -607,7 +610,8 @@ class API(base.Base):
|
|||||||
id=port['id'],
|
id=port['id'],
|
||||||
address=port['mac_address'],
|
address=port['mac_address'],
|
||||||
network=network,
|
network=network,
|
||||||
type=port.get('binding:vif_type')))
|
type=port.get('binding:vif_type'),
|
||||||
|
devname=devname))
|
||||||
return nw_info
|
return nw_info
|
||||||
|
|
||||||
def _get_subnets_from_port(self, context, port):
|
def _get_subnets_from_port(self, context, port):
|
||||||
|
@ -186,6 +186,7 @@ class FlatNetworkTestCase(test.TestCase):
|
|||||||
'mac': 'DE:AD:BE:EF:00:%02x' % nid,
|
'mac': 'DE:AD:BE:EF:00:%02x' % nid,
|
||||||
'rxtx_cap': 30,
|
'rxtx_cap': 30,
|
||||||
'vif_type': net_model.VIF_TYPE_BRIDGE,
|
'vif_type': net_model.VIF_TYPE_BRIDGE,
|
||||||
|
'vif_devname': None,
|
||||||
'vif_uuid':
|
'vif_uuid':
|
||||||
'00000000-0000-0000-0000-00000000000000%02d' % nid,
|
'00000000-0000-0000-0000-00000000000000%02d' % nid,
|
||||||
'should_create_vlan': False,
|
'should_create_vlan': False,
|
||||||
|
@ -47,7 +47,8 @@ class LibvirtVifTestCase(test.TestCase):
|
|||||||
'gateway_v6': net['gateway_v6'],
|
'gateway_v6': net['gateway_v6'],
|
||||||
'ips': [{'ip': '101.168.1.9'}],
|
'ips': [{'ip': '101.168.1.9'}],
|
||||||
'dhcp_server': '191.168.1.1',
|
'dhcp_server': '191.168.1.1',
|
||||||
'vif_uuid': 'vif-xxx-yyy-zzz'
|
'vif_uuid': 'vif-xxx-yyy-zzz',
|
||||||
|
'vif_devname': 'tap-xxx-yyy-zzz'
|
||||||
}
|
}
|
||||||
|
|
||||||
instance = {
|
instance = {
|
||||||
|
@ -20,6 +20,7 @@ import nova.context
|
|||||||
import nova.db
|
import nova.db
|
||||||
from nova.image import glance
|
from nova.image import glance
|
||||||
from nova.network import minidns
|
from nova.network import minidns
|
||||||
|
from nova.network import model as network_model
|
||||||
from nova.openstack.common import cfg
|
from nova.openstack.common import cfg
|
||||||
|
|
||||||
CONF = cfg.CONF
|
CONF = cfg.CONF
|
||||||
@ -91,6 +92,8 @@ def get_test_network_info(count=1):
|
|||||||
'bridge_interface': fake_bridge_interface,
|
'bridge_interface': fake_bridge_interface,
|
||||||
'injected': False}
|
'injected': False}
|
||||||
mapping = {'mac': fake,
|
mapping = {'mac': fake,
|
||||||
|
'vif_type': network_model.VIF_TYPE_BRIDGE,
|
||||||
|
'vif_uuid': 'vif-xxx-yyy-zzz',
|
||||||
'dhcp_server': fake,
|
'dhcp_server': fake,
|
||||||
'dns': ['fake1', 'fake2'],
|
'dns': ['fake1', 'fake2'],
|
||||||
'gateway': fake,
|
'gateway': fake,
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
from nova import exception
|
from nova import exception
|
||||||
from nova.network import linux_net
|
from nova.network import linux_net
|
||||||
|
from nova.network import model as network_model
|
||||||
from nova.openstack.common import cfg
|
from nova.openstack.common import cfg
|
||||||
from nova.openstack.common import log as logging
|
from nova.openstack.common import log as logging
|
||||||
from nova import utils
|
from nova import utils
|
||||||
@ -41,11 +42,14 @@ CONF.register_opts(libvirt_vif_opts)
|
|||||||
CONF.import_opt('libvirt_type', 'nova.virt.libvirt.driver')
|
CONF.import_opt('libvirt_type', 'nova.virt.libvirt.driver')
|
||||||
CONF.import_opt('use_ipv6', 'nova.netconf')
|
CONF.import_opt('use_ipv6', 'nova.netconf')
|
||||||
|
|
||||||
LINUX_DEV_LEN = 14
|
|
||||||
|
|
||||||
|
|
||||||
class LibvirtBaseVIFDriver(object):
|
class LibvirtBaseVIFDriver(object):
|
||||||
|
|
||||||
|
def get_vif_devname(self, mapping):
|
||||||
|
if 'vif_devname' in mapping:
|
||||||
|
return mapping['vif_devname']
|
||||||
|
return ("nic" + mapping['vif_uuid'])[:network_model.NIC_NAME_LEN]
|
||||||
|
|
||||||
def get_config(self, instance, network, mapping):
|
def get_config(self, instance, network, mapping):
|
||||||
conf = vconfig.LibvirtConfigGuestInterface()
|
conf = vconfig.LibvirtConfigGuestInterface()
|
||||||
model = None
|
model = None
|
||||||
@ -78,7 +82,7 @@ class LibvirtBridgeDriver(LibvirtBaseVIFDriver):
|
|||||||
mapping)
|
mapping)
|
||||||
|
|
||||||
designer.set_vif_host_backend_bridge_config(
|
designer.set_vif_host_backend_bridge_config(
|
||||||
conf, network['bridge'], None)
|
conf, network['bridge'], self.get_vif_devname(mapping))
|
||||||
|
|
||||||
name = "nova-instance-" + instance['name'] + "-" + mac_id
|
name = "nova-instance-" + instance['name'] + "-" + mac_id
|
||||||
primary_addr = mapping['ips'][0]['ip']
|
primary_addr = mapping['ips'][0]['ip']
|
||||||
@ -134,11 +138,8 @@ class LibvirtOpenVswitchDriver(LibvirtBaseVIFDriver):
|
|||||||
OVS virtual port XML (0.9.10 or earlier).
|
OVS virtual port XML (0.9.10 or earlier).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def get_dev_name(self, iface_id):
|
|
||||||
return ("tap" + iface_id)[:LINUX_DEV_LEN]
|
|
||||||
|
|
||||||
def get_config(self, instance, network, mapping):
|
def get_config(self, instance, network, mapping):
|
||||||
dev = self.get_dev_name(mapping['vif_uuid'])
|
dev = self.get_vif_devname(mapping)
|
||||||
|
|
||||||
conf = super(LibvirtOpenVswitchDriver,
|
conf = super(LibvirtOpenVswitchDriver,
|
||||||
self).get_config(instance,
|
self).get_config(instance,
|
||||||
@ -167,7 +168,7 @@ class LibvirtOpenVswitchDriver(LibvirtBaseVIFDriver):
|
|||||||
def plug(self, instance, vif):
|
def plug(self, instance, vif):
|
||||||
network, mapping = vif
|
network, mapping = vif
|
||||||
iface_id = mapping['vif_uuid']
|
iface_id = mapping['vif_uuid']
|
||||||
dev = self.get_dev_name(iface_id)
|
dev = self.get_vif_devname(mapping)
|
||||||
if not linux_net.device_exists(dev):
|
if not linux_net.device_exists(dev):
|
||||||
# Older version of the command 'ip' from the iproute2 package
|
# Older version of the command 'ip' from the iproute2 package
|
||||||
# don't have support for the tuntap option (lp:882568). If it
|
# don't have support for the tuntap option (lp:882568). If it
|
||||||
@ -191,7 +192,7 @@ class LibvirtOpenVswitchDriver(LibvirtBaseVIFDriver):
|
|||||||
try:
|
try:
|
||||||
network, mapping = vif
|
network, mapping = vif
|
||||||
self.delete_ovs_vif_port(network['bridge'],
|
self.delete_ovs_vif_port(network['bridge'],
|
||||||
self.get_dev_name(mapping['vif_uuid']))
|
self.get_vif_devname(mapping))
|
||||||
except exception.ProcessExecutionError:
|
except exception.ProcessExecutionError:
|
||||||
LOG.exception(_("Failed while unplugging vif"), instance=instance)
|
LOG.exception(_("Failed while unplugging vif"), instance=instance)
|
||||||
|
|
||||||
@ -207,11 +208,11 @@ class LibvirtHybridOVSBridgeDriver(LibvirtBridgeDriver,
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def get_br_name(self, iface_id):
|
def get_br_name(self, iface_id):
|
||||||
return ("qbr" + iface_id)[:LINUX_DEV_LEN]
|
return ("qbr" + iface_id)[:network_model.NIC_NAME_LEN]
|
||||||
|
|
||||||
def get_veth_pair_names(self, iface_id):
|
def get_veth_pair_names(self, iface_id):
|
||||||
return (("qvb%s" % iface_id)[:LINUX_DEV_LEN],
|
return (("qvb%s" % iface_id)[:network_model.NIC_NAME_LEN],
|
||||||
("qvo%s" % iface_id)[:LINUX_DEV_LEN])
|
("qvo%s" % iface_id)[:network_model.NIC_NAME_LEN])
|
||||||
|
|
||||||
def get_config(self, instance, network, mapping):
|
def get_config(self, instance, network, mapping):
|
||||||
br_name = self.get_br_name(mapping['vif_uuid'])
|
br_name = self.get_br_name(mapping['vif_uuid'])
|
||||||
@ -280,7 +281,8 @@ class LibvirtOpenVswitchVirtualPortDriver(LibvirtBaseVIFDriver):
|
|||||||
mapping)
|
mapping)
|
||||||
|
|
||||||
designer.set_vif_host_backend_ovs_config(
|
designer.set_vif_host_backend_ovs_config(
|
||||||
conf, network['bridge'], mapping['vif_uuid'])
|
conf, network['bridge'], mapping['vif_uuid'],
|
||||||
|
self.get_vif_devname(mapping))
|
||||||
|
|
||||||
return conf
|
return conf
|
||||||
|
|
||||||
@ -295,15 +297,9 @@ class LibvirtOpenVswitchVirtualPortDriver(LibvirtBaseVIFDriver):
|
|||||||
class QuantumLinuxBridgeVIFDriver(LibvirtBaseVIFDriver):
|
class QuantumLinuxBridgeVIFDriver(LibvirtBaseVIFDriver):
|
||||||
"""VIF driver for Linux Bridge when running Quantum."""
|
"""VIF driver for Linux Bridge when running Quantum."""
|
||||||
|
|
||||||
def get_dev_name(self, iface_id):
|
|
||||||
return ("tap" + iface_id)[:LINUX_DEV_LEN]
|
|
||||||
|
|
||||||
def get_config(self, instance, network, mapping):
|
def get_config(self, instance, network, mapping):
|
||||||
iface_id = mapping['vif_uuid']
|
linux_net.LinuxBridgeInterfaceDriver.ensure_bridge(network['bridge'],
|
||||||
dev = self.get_dev_name(iface_id)
|
None,
|
||||||
|
|
||||||
bridge = network['bridge']
|
|
||||||
linux_net.LinuxBridgeInterfaceDriver.ensure_bridge(bridge, None,
|
|
||||||
filtering=False)
|
filtering=False)
|
||||||
|
|
||||||
conf = super(QuantumLinuxBridgeVIFDriver,
|
conf = super(QuantumLinuxBridgeVIFDriver,
|
||||||
@ -312,7 +308,7 @@ class QuantumLinuxBridgeVIFDriver(LibvirtBaseVIFDriver):
|
|||||||
mapping)
|
mapping)
|
||||||
|
|
||||||
designer.set_vif_host_backend_bridge_config(
|
designer.set_vif_host_backend_bridge_config(
|
||||||
conf, bridge, dev)
|
conf, network['bridge'], self.get_vif_devname(mapping))
|
||||||
|
|
||||||
return conf
|
return conf
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user