diff --git a/nova/network/model.py b/nova/network/model.py index 399bcb4b5ef1..7207cba546e2 100644 --- a/nova/network/model.py +++ b/nova/network/model.py @@ -44,6 +44,15 @@ VIF_TYPE_OTHER = 'other' VIF_DETAIL_PORT_FILTER = 'port_filter' VIF_DETAIL_OVS_HYBRID_PLUG = 'ovs_hybrid_plug' +# Constants for the 'vif_model' values +VIF_MODEL_VIRTIO = 'virtio' +VIF_MODEL_NE2K_PCI = 'ne2k_pci' +VIF_MODEL_PCNET = 'pcnet' +VIF_MODEL_RTL8139 = 'rtl8139' +VIF_MODEL_E1000 = 'e1000' +VIF_MODEL_E1000E = 'e1000e' +VIF_MODEL_NETFRONT = 'netfront' + # Constant for max length of network interface names # eg 'bridge' in the Network class or 'devname' in # the VIF class diff --git a/nova/tests/virt/libvirt/test_libvirt_vif.py b/nova/tests/virt/libvirt/test_libvirt_vif.py index ed78a5c9baf3..f6d41a3d0508 100644 --- a/nova/tests/virt/libvirt/test_libvirt_vif.py +++ b/nova/tests/virt/libvirt/test_libvirt_vif.py @@ -356,7 +356,7 @@ class LibvirtVifTestCase(test.TestCase): d = vif.LibvirtGenericVIFDriver(self._get_conn()) xml = self._get_instance_xml(d, self.vif_bridge) - self._assertModel(xml, "virtio") + self._assertModel(xml, network_model.VIF_MODEL_VIRTIO) def test_model_kvm_custom(self): self.flags(use_virtio_for_bridges=True, @@ -364,10 +364,11 @@ class LibvirtVifTestCase(test.TestCase): group='libvirt') d = vif.LibvirtGenericVIFDriver(self._get_conn()) - image_meta = {'properties': {'hw_vif_model': 'e1000'}} + image_meta = {'properties': {'hw_vif_model': + network_model.VIF_MODEL_E1000}} xml = self._get_instance_xml(d, self.vif_bridge, image_meta) - self._assertModel(xml, "e1000") + self._assertModel(xml, network_model.VIF_MODEL_E1000) def test_model_kvm_bogus(self): self.flags(use_virtio_for_bridges=True, @@ -416,7 +417,7 @@ class LibvirtVifTestCase(test.TestCase): self.assertEqual(outbound.get("burst"), self.bandwidth['quota:vif_outbound_burst']) - self._assertModel(xml, "virtio", "qemu") + self._assertModel(xml, network_model.VIF_MODEL_VIRTIO, "qemu") def test_model_qemu_no_firewall(self): self.flags(firewall_driver="nova.virt.firewall.NoopFirewallDriver") @@ -760,7 +761,7 @@ class LibvirtVifTestCase(test.TestCase): self._assertTypeEquals(node, "direct", "source", "mode", "passthrough") self._assertMacEquals(node, self.vif_mlnx) - self._assertModel(xml, "virtio") + self._assertModel(xml, network_model.VIF_MODEL_VIRTIO) def test_midonet_ethernet_vif_driver(self): d = vif.LibvirtGenericVIFDriver(self._get_conn()) diff --git a/nova/tests/virt/vmwareapi/test_vm_util.py b/nova/tests/virt/vmwareapi/test_vm_util.py index d608272bb567..84392dc38b24 100644 --- a/nova/tests/virt/vmwareapi/test_vm_util.py +++ b/nova/tests/virt/vmwareapi/test_vm_util.py @@ -20,6 +20,7 @@ import re import mock from nova import exception +from nova.network import model as network_model from nova.openstack.common.gettextutils import _ from nova.openstack.common import units from nova.openstack.common import uuidutils @@ -630,3 +631,19 @@ class VMwareVMUtilTestCase(test.NoDBTestCase): expected = re.sub(r'\s+', '', expected) result = re.sub(r'\s+', '', repr(result)) self.assertEqual(expected, result) + + def test_convert_vif_model(self): + expected = "VirtualE1000" + result = vm_util._convert_vif_model(network_model.VIF_MODEL_E1000) + self.assertEqual(expected, result) + expected = "VirtualE1000e" + result = vm_util._convert_vif_model(network_model.VIF_MODEL_E1000E) + self.assertEqual(expected, result) + types = ["VirtualE1000", "VirtualE1000e", "VirtualPCNet32", + "VirtualVmxnet"] + for type in types: + self.assertEqual(type, + vm_util._convert_vif_model(type)) + self.assertRaises(exception.Invalid, + vm_util._convert_vif_model, + "InvalidVifModel") diff --git a/nova/virt/libvirt/vif.py b/nova/virt/libvirt/vif.py index f37b769e408a..3a1b2f75f2de 100644 --- a/nova/virt/libvirt/vif.py +++ b/nova/virt/libvirt/vif.py @@ -54,9 +54,21 @@ DEV_PREFIX_ETH = 'eth' def is_vif_model_valid_for_virt(virt_type, vif_model): valid_models = { - 'qemu': ['virtio', 'ne2k_pci', 'pcnet', 'rtl8139', 'e1000'], - 'kvm': ['virtio', 'ne2k_pci', 'pcnet', 'rtl8139', 'e1000'], - 'xen': ['netfront', 'ne2k_pci', 'pcnet', 'rtl8139', 'e1000'], + 'qemu': [network_model.VIF_MODEL_VIRTIO, + network_model.VIF_MODEL_NE2K_PCI, + network_model.VIF_MODEL_PCNET, + network_model.VIF_MODEL_RTL8139, + network_model.VIF_MODEL_E1000], + 'kvm': [network_model.VIF_MODEL_VIRTIO, + network_model.VIF_MODEL_NE2K_PCI, + network_model.VIF_MODEL_PCNET, + network_model.VIF_MODEL_RTL8139, + network_model.VIF_MODEL_E1000], + 'xen': [network_model.VIF_MODEL_NETFRONT, + network_model.VIF_MODEL_NE2K_PCI, + network_model.VIF_MODEL_PCNET, + network_model.VIF_MODEL_RTL8139, + network_model.VIF_MODEL_E1000], 'lxc': [], 'uml': [], } @@ -113,11 +125,12 @@ class LibvirtBaseVIFDriver(object): if (model is None and CONF.libvirt.virt_type in ('kvm', 'qemu') and CONF.libvirt.use_virtio_for_bridges): - model = "virtio" + model = network_model.VIF_MODEL_VIRTIO # Workaround libvirt bug, where it mistakenly # enables vhost mode, even for non-KVM guests - if model == "virtio" and CONF.libvirt.virt_type == "qemu": + if (model == network_model.VIF_MODEL_VIRTIO and + CONF.libvirt.virt_type == "qemu"): driver = "qemu" if not is_vif_model_valid_for_virt(CONF.libvirt.virt_type, diff --git a/nova/virt/vmwareapi/vm_util.py b/nova/virt/vmwareapi/vm_util.py index e6a1db1bbadf..73168c4e742c 100644 --- a/nova/virt/vmwareapi/vm_util.py +++ b/nova/virt/vmwareapi/vm_util.py @@ -25,6 +25,7 @@ import functools from oslo.config import cfg from nova import exception +from nova.network import model as network_model from nova.openstack.common.gettextutils import _ from nova.openstack.common import log as logging from nova.openstack.common import units @@ -35,6 +36,9 @@ from nova.virt.vmwareapi import vim_util CONF = cfg.CONF LOG = logging.getLogger(__name__) +ALL_SUPPORTED_NETWORK_DEVICES = ['VirtualE1000', 'VirtualE1000e', + 'VirtualPCNet32', 'VirtualSriovEthernetCard', + 'VirtualVmxnet'] DSRecord = collections.namedtuple( 'DSRecord', ['datastore', 'name', 'capacity', 'freespace']) @@ -183,6 +187,18 @@ def create_controller_spec(client_factory, key, adapter_type="lsiLogic"): return virtual_device_config +def _convert_vif_model(name): + """Converts standard VIF_MODEL types to the internal VMware ones.""" + if name == network_model.VIF_MODEL_E1000: + return 'VirtualE1000' + if name == network_model.VIF_MODEL_E1000E: + return 'VirtualE1000e' + if name not in ALL_SUPPORTED_NETWORK_DEVICES: + msg = _('%s is not supported.') % name + raise exception.Invalid(msg) + return name + + def create_network_spec(client_factory, vif_info): """Builds a config spec for the addition of a new network adapter to the VM. @@ -191,8 +207,7 @@ def create_network_spec(client_factory, vif_info): network_spec.operation = "add" # Keep compatible with other Hyper vif model parameter. - if vif_info['vif_model'] == "e1000": - vif_info['vif_model'] = "VirtualE1000" + vif_info['vif_model'] = _convert_vif_model(vif_info['vif_model']) vif = 'ns0:' + vif_info['vif_model'] net_device = client_factory.create(vif) diff --git a/nova/virt/vmwareapi/vmops.py b/nova/virt/vmwareapi/vmops.py index d5471ead9c2c..d898b1fbe6bd 100644 --- a/nova/virt/vmwareapi/vmops.py +++ b/nova/virt/vmwareapi/vmops.py @@ -31,6 +31,7 @@ from nova.compute import power_state from nova.compute import task_states from nova import context as nova_context from nova import exception +from nova.network import model as network_model from nova.openstack.common import excutils from nova.openstack.common.gettextutils import _ from nova.openstack.common import lockutils @@ -235,7 +236,8 @@ class VMwareVMOps(object): disk_type = image_properties.get("vmware_disktype", "preallocated") # Get the network card type from the image properties. - vif_model = image_properties.get("hw_vif_model", "VirtualE1000") + vif_model = image_properties.get("hw_vif_model", + network_model.VIF_MODEL_E1000) # Fetch the image_linked_clone data here. It is retrieved # with the above network based API call. To retrieve it