Skip to content

Commit ecb8c9c

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "vif: Stop using getattr for VIF lookups"
2 parents 9f9ff03 + b4f3b2b commit ecb8c9c

File tree

2 files changed

+129
-152
lines changed

2 files changed

+129
-152
lines changed

nova/network/os_vif_util.py

Lines changed: 43 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@
1818
versioned object model os_vif.objects.*
1919
'''
2020

21-
import sys
22-
2321
from os_vif import objects
2422
from oslo_config import cfg
2523
from oslo_log import log as logging
@@ -32,6 +30,13 @@
3230
LOG = logging.getLogger(__name__)
3331
CONF = cfg.CONF
3432

33+
LEGACY_VIFS = {
34+
model.VIF_TYPE_DVS, model.VIF_TYPE_IOVISOR, model.VIF_TYPE_802_QBG,
35+
model.VIF_TYPE_802_QBH, model.VIF_TYPE_HW_VEB, model.VIF_TYPE_HOSTDEV,
36+
model.VIF_TYPE_IB_HOSTDEV, model.VIF_TYPE_MIDONET, model.VIF_TYPE_TAP,
37+
model.VIF_TYPE_MACVTAP
38+
}
39+
3540

3641
def _get_vif_name(vif):
3742
"""Get a VIF device name
@@ -495,82 +500,6 @@ def _nova_to_osvif_vif_vrouter(vif):
495500
return obj
496501

497502

498-
# VIF_TYPE_DVS = 'dvs'
499-
def _nova_to_osvif_vif_dvs(vif):
500-
raise NotImplementedError()
501-
502-
503-
# VIF_TYPE_IOVISOR = 'iovisor'
504-
def _nova_to_osvif_vif_iovisor(vif):
505-
raise NotImplementedError()
506-
507-
508-
# VIF_TYPE_802_QBG = '802.1qbg'
509-
def _nova_to_osvif_vif_802_1qbg(vif):
510-
raise NotImplementedError()
511-
512-
513-
# VIF_TYPE_802_QBH = '802.1qbh'
514-
def _nova_to_osvif_vif_802_1qbh(vif):
515-
raise NotImplementedError()
516-
517-
518-
# VIF_TYPE_HW_VEB = 'hw_veb'
519-
def _nova_to_osvif_vif_hw_veb(vif):
520-
raise NotImplementedError()
521-
522-
523-
# VIF_TYPE_IB_HOSTDEV = 'ib_hostdev'
524-
def _nova_to_osvif_vif_ib_hostdev(vif):
525-
raise NotImplementedError()
526-
527-
528-
# VIF_TYPE_MIDONET = 'midonet'
529-
def _nova_to_osvif_vif_midonet(vif):
530-
raise NotImplementedError()
531-
532-
533-
# VIF_TYPE_TAP = 'tap'
534-
def _nova_to_osvif_vif_tap(vif):
535-
raise NotImplementedError()
536-
537-
538-
# VIF_TYPE_MACVTAP = 'macvtap'
539-
def _nova_to_osvif_vif_macvtap(vif):
540-
raise NotImplementedError()
541-
542-
543-
# VIF_TYPE_HOSTDEV = 'hostdev_physical'
544-
def _nova_to_osvif_vif_hostdev_physical(vif):
545-
raise NotImplementedError()
546-
547-
548-
# VIF_TYPE_BINDING_FAILED = 'binding_failed'
549-
def _nova_to_osvif_vif_binding_failed(vif):
550-
"""Special handler for the "binding_failed" vif type.
551-
552-
The "binding_failed" vif type indicates port binding to a host failed
553-
and we are trying to plug the vifs again, which will fail because we
554-
do not know the actual real vif type, like ovs, bridge, etc. We raise
555-
NotImplementedError to indicate to the caller that we cannot handle
556-
this type of vif rather than the generic "Unsupported VIF type" error
557-
in nova_to_osvif_vif.
558-
"""
559-
raise NotImplementedError()
560-
561-
562-
# VIF_TYPE_UNBOUND = 'unbound'
563-
def _nova_to_osvif_vif_unbound(vif):
564-
"""Special handler for the "unbound" vif type.
565-
566-
The "unbound" vif type indicates a port has not been hooked up to backend
567-
network driver (OVS, linux bridge, ...). We raise NotImplementedError to
568-
indicate to the caller that we cannot handle this type of vif rather than
569-
the generic "Unsupported VIF type" error in nova_to_osvif_vif.
570-
"""
571-
raise NotImplementedError()
572-
573-
574503
def nova_to_osvif_vif(vif):
575504
"""Convert a Nova VIF model to an os-vif object
576505
@@ -586,19 +515,40 @@ def nova_to_osvif_vif(vif):
586515

587516
LOG.debug("Converting VIF %s", vif)
588517

589-
funcname = "_nova_to_osvif_vif_" + vif['type'].replace(".", "_")
590-
func = getattr(sys.modules[__name__], funcname, None)
591-
592-
if not func:
593-
raise exception.NovaException(
594-
"Unsupported VIF type %(type)s convert '%(func)s'" %
595-
{'type': vif['type'], 'func': funcname})
596-
597-
try:
598-
vifobj = func(vif)
599-
LOG.debug("Converted object %s", vifobj)
600-
return vifobj
601-
except NotImplementedError:
602-
LOG.debug("No conversion for VIF type %s yet",
603-
vif['type'])
518+
vif_type = vif['type']
519+
520+
if vif_type in LEGACY_VIFS:
521+
# We want to explicitly fall back to the legacy path for these VIF
522+
# types
523+
LOG.debug('No conversion for VIF type %s yet', vif_type)
604524
return None
525+
526+
if vif_type in {model.VIF_TYPE_BINDING_FAILED, model.VIF_TYPE_UNBOUND}:
527+
# These aren't real VIF types. VIF_TYPE_BINDING_FAILED indicates port
528+
# binding to a host failed and we are trying to plug the VIFs again,
529+
# which will fail because we do not know the actual real VIF type, like
530+
# VIF_TYPE_OVS, VIF_TYPE_BRIDGE, etc. VIF_TYPE_UNBOUND, by comparison,
531+
# is the default VIF type of a driver when it is not bound to any host,
532+
# i.e. we have not set the host ID in the binding driver. This should
533+
# also only happen in error cases.
534+
# TODO(stephenfin): We probably want a more meaningful log here
535+
LOG.debug('No conversion for VIF type %s yet', vif_type)
536+
return None
537+
538+
if vif_type == model.VIF_TYPE_OVS:
539+
vif_obj = _nova_to_osvif_vif_ovs(vif)
540+
elif vif_type == model.VIF_TYPE_IVS:
541+
vif_obj = _nova_to_osvif_vif_ivs(vif)
542+
elif vif_type == model.VIF_TYPE_BRIDGE:
543+
vif_obj = _nova_to_osvif_vif_bridge(vif)
544+
elif vif_type == model.VIF_TYPE_AGILIO_OVS:
545+
vif_obj = _nova_to_osvif_vif_agilio_ovs(vif)
546+
elif vif_type == model.VIF_TYPE_VHOSTUSER:
547+
vif_obj = _nova_to_osvif_vif_vhostuser(vif)
548+
elif vif_type == model.VIF_TYPE_VROUTER:
549+
vif_obj = _nova_to_osvif_vif_vrouter(vif)
550+
else:
551+
raise exception.NovaException('Unsupported VIF type %s' % vif_type)
552+
553+
LOG.debug('Converted object %s', vif_obj)
554+
return vif_obj

nova/virt/libvirt/vif.py

Lines changed: 86 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import os_vif
2424
from os_vif import exception as osv_exception
2525
from os_vif.objects import fields as osv_fields
26+
from os_vif.objects import vif as osv_vifs
2627
from oslo_concurrency import processutils
2728
from oslo_log import log as logging
2829
from oslo_utils import strutils
@@ -120,9 +121,6 @@ def set_vf_interface_vlan(pci_addr, mac_addr, vlan=0):
120121
class LibvirtGenericVIFDriver(object):
121122
"""Generic VIF driver for libvirt networking."""
122123

123-
def _normalize_vif_type(self, vif_type):
124-
return vif_type.replace('2.1q', '2q')
125-
126124
def get_vif_devname(self, vif):
127125
if 'devname' in vif:
128126
return vif['devname']
@@ -432,6 +430,10 @@ def get_config_tap(self, instance, vif, image_meta,
432430

433431
return conf
434432

433+
def get_config_ib_hostdev(self, instance, vif, image_meta,
434+
inst_type, virt_type, host):
435+
return self.get_base_hostdev_pci_config(vif)
436+
435437
def _get_virtio_queue_sizes(self, host):
436438
"""Returns rx/tx queue sizes configured or (None, None)
437439
@@ -464,10 +466,6 @@ def _get_virtio_queue_sizes(self, host):
464466
tx = None
465467
return rx, tx
466468

467-
def get_config_ib_hostdev(self, instance, vif, image_meta,
468-
inst_type, virt_type, host):
469-
return self.get_base_hostdev_pci_config(vif)
470-
471469
def _set_config_VIFGeneric(self, instance, vif, conf, host):
472470
dev = vif.vif_name
473471
designer.set_vif_host_backend_ethernet_config(conf, dev, host)
@@ -522,14 +520,12 @@ def _set_config_VIFPortProfileOpenVSwitch(self, profile, conf):
522520

523521
def _set_config_VIFPortProfile(self, instance, vif, conf):
524522
# Set any port profile that may be required
525-
profilefunc = "_set_config_" + vif.port_profile.obj_name()
526-
func = getattr(self, profilefunc, None)
527-
if not func:
523+
profile_name = vif.port_profile.obj_name()
524+
if profile_name == 'VIFPortProfileOpenVSwitch':
525+
self._set_config_VIFPortProfileOpenVSwitch(vif.port_profile, conf)
526+
else:
528527
raise exception.InternalError(
529-
_("Unsupported VIF port profile type %(obj)s func %(func)s") %
530-
{'obj': vif.port_profile.obj_name(), 'func': profilefunc})
531-
532-
func(vif.port_profile, conf)
528+
_('Unsupported VIF port profile type %s') % profile_name)
533529

534530
def _get_config_os_vif(self, instance, vif, image_meta, inst_type,
535531
virt_type, host, vnic_type):
@@ -552,13 +548,19 @@ def _get_config_os_vif(self, instance, vif, image_meta, inst_type,
552548
host)
553549

554550
# Do the VIF type specific config
555-
viffunc = "_set_config_" + vif.obj_name()
556-
func = getattr(self, viffunc, None)
557-
if not func:
551+
if isinstance(vif, osv_vifs.VIFGeneric):
552+
self._set_config_VIFGeneric(instance, vif, conf, host)
553+
elif isinstance(vif, osv_vifs.VIFBridge):
554+
self._set_config_VIFBridge(instance, vif, conf, host)
555+
elif isinstance(vif, osv_vifs.VIFOpenVSwitch):
556+
self._set_config_VIFOpenVSwitch(instance, vif, conf, host)
557+
elif isinstance(vif, osv_vifs.VIFVHostUser):
558+
self._set_config_VIFVHostUser(instance, vif, conf, host)
559+
elif isinstance(vif, osv_vifs.VIFHostDevice):
560+
self._set_config_VIFHostDevice(instance, vif, conf, host)
561+
else:
558562
raise exception.InternalError(
559-
_("Unsupported VIF type %(obj)s func %(func)s") %
560-
{'obj': vif.obj_name(), 'func': viffunc})
561-
func(instance, vif, conf, host)
563+
_("Unsupported VIF type %s") % vif.obj_name())
562564

563565
# not all VIF types support bandwidth configuration
564566
# https://github.com/libvirt/libvirt/blob/568a41722/src/conf/netdev_bandwidth_conf.h#L38
@@ -596,13 +598,29 @@ def get_config(self, instance, vif, image_meta,
596598
vnic_type)
597599

598600
# Legacy non-os-vif codepath
599-
vif_slug = self._normalize_vif_type(vif_type)
600-
func = getattr(self, 'get_config_%s' % vif_slug, None)
601-
if not func:
602-
raise exception.InternalError(
603-
_("Unexpected vif_type=%s") % vif_type)
604-
return func(instance, vif, image_meta,
605-
inst_type, virt_type, host)
601+
args = (instance, vif, image_meta, inst_type, virt_type, host)
602+
if vif_type == network_model.VIF_TYPE_IOVISOR:
603+
return self.get_config_iovisor(*args)
604+
elif vif_type == network_model.VIF_TYPE_BRIDGE:
605+
return self.get_config_bridge(*args)
606+
elif vif_type == network_model.VIF_TYPE_802_QBG:
607+
return self.get_config_802qbg(*args)
608+
elif vif_type == network_model.VIF_TYPE_802_QBH:
609+
return self.get_config_802qbh(*args)
610+
elif vif_type == network_model.VIF_TYPE_HW_VEB:
611+
return self.get_config_hw_veb(*args)
612+
elif vif_type == network_model.VIF_TYPE_HOSTDEV:
613+
return self.get_config_hostdev_physical(*args)
614+
elif vif_type == network_model.VIF_TYPE_MACVTAP:
615+
return self.get_config_macvtap(*args)
616+
elif vif_type == network_model.VIF_TYPE_MIDONET:
617+
return self.get_config_midonet(*args)
618+
elif vif_type == network_model.VIF_TYPE_TAP:
619+
return self.get_config_tap(*args)
620+
elif vif_type == network_model.VIF_TYPE_IB_HOSTDEV:
621+
return self.get_config_ib_hostdev(*args)
622+
623+
raise exception.InternalError(_('Unexpected vif_type=%s') % vif_type)
606624

607625
def plug_ib_hostdev(self, instance, vif):
608626
fabric = vif.get_physical_network()
@@ -621,12 +639,6 @@ def plug_ib_hostdev(self, instance, vif):
621639
LOG.exception(_("Failed while plugging ib hostdev vif"),
622640
instance=instance)
623641

624-
def plug_802qbg(self, instance, vif):
625-
pass
626-
627-
def plug_802qbh(self, instance, vif):
628-
pass
629-
630642
def plug_hw_veb(self, instance, vif):
631643
# TODO(vladikr): This code can be removed once the minimum version of
632644
# Libvirt is incleased above 1.3.5, as vlan will be set by libvirt
@@ -642,9 +654,6 @@ def plug_hw_veb(self, instance, vif):
642654
if trusted:
643655
linux_net.set_vf_trusted(vif['profile']['pci_slot'], True)
644656

645-
def plug_hostdev_physical(self, instance, vif):
646-
pass
647-
648657
def plug_macvtap(self, instance, vif):
649658
vif_details = vif['details']
650659
vlan = vif_details.get(network_model.VIF_DETAILS_VLAN)
@@ -726,13 +735,27 @@ def plug(self, instance, vif):
726735
return
727736

728737
# Legacy non-os-vif codepath
729-
vif_slug = self._normalize_vif_type(vif_type)
730-
func = getattr(self, 'plug_%s' % vif_slug, None)
731-
if not func:
738+
if vif_type == network_model.VIF_TYPE_IB_HOSTDEV:
739+
self.plug_ib_hostdev(instance, vif)
740+
elif vif_type == network_model.VIF_TYPE_HW_VEB:
741+
self.plug_hw_veb(instance, vif)
742+
elif vif_type == network_model.VIF_TYPE_MACVTAP:
743+
self.plug_macvtap(instance, vif)
744+
elif vif_type == network_model.VIF_TYPE_MIDONET:
745+
self.plug_midonet(instance, vif)
746+
elif vif_type == network_model.VIF_TYPE_IOVISOR:
747+
self.plug_iovisor(instance, vif)
748+
elif vif_type == network_model.VIF_TYPE_TAP:
749+
self.plug_tap(instance, vif)
750+
elif vif_type in {network_model.VIF_TYPE_802_QBG,
751+
network_model.VIF_TYPE_802_QBH,
752+
network_model.VIF_TYPE_HOSTDEV}:
753+
# These are no-ops
754+
pass
755+
else:
732756
raise exception.VirtualInterfacePlugException(
733-
_("Plug vif failed because of unexpected "
757+
_("Plug VIF failed because of unexpected "
734758
"vif_type=%s") % vif_type)
735-
func(instance, vif)
736759

737760
def unplug_ib_hostdev(self, instance, vif):
738761
fabric = vif.get_physical_network()
@@ -746,12 +769,6 @@ def unplug_ib_hostdev(self, instance, vif):
746769
except Exception:
747770
LOG.exception(_("Failed while unplugging ib hostdev vif"))
748771

749-
def unplug_802qbg(self, instance, vif):
750-
pass
751-
752-
def unplug_802qbh(self, instance, vif):
753-
pass
754-
755772
def unplug_hw_veb(self, instance, vif):
756773
# TODO(sean-k-mooney): remove in Train after backporting 0 mac
757774
# change as this should no longer be needed with libvirt >= 3.2.0.
@@ -770,12 +787,6 @@ def unplug_hw_veb(self, instance, vif):
770787
if "trusted" in vif['profile']:
771788
linux_net.set_vf_trusted(vif['profile']['pci_slot'], False)
772789

773-
def unplug_hostdev_physical(self, instance, vif):
774-
pass
775-
776-
def unplug_macvtap(self, instance, vif):
777-
pass
778-
779790
def unplug_midonet(self, instance, vif):
780791
"""Unplug from MidoNet network port
781792
@@ -842,9 +853,25 @@ def unplug(self, instance, vif):
842853
return
843854

844855
# Legacy non-os-vif codepath
845-
vif_slug = self._normalize_vif_type(vif_type)
846-
func = getattr(self, 'unplug_%s' % vif_slug, None)
847-
if not func:
848-
msg = _("Unexpected vif_type=%s") % vif_type
849-
raise exception.InternalError(msg)
850-
func(instance, vif)
856+
if vif_type == network_model.VIF_TYPE_IB_HOSTDEV:
857+
self.unplug_ib_hostdev(instance, vif)
858+
elif vif_type == network_model.VIF_TYPE_HW_VEB:
859+
self.unplug_hw_veb(instance, vif)
860+
elif vif_type == network_model.VIF_TYPE_MIDONET:
861+
self.unplug_midonet(instance, vif)
862+
elif vif_type == network_model.VIF_TYPE_IOVISOR:
863+
self.unplug_iovisor(instance, vif)
864+
elif vif_type == network_model.VIF_TYPE_TAP:
865+
self.unplug_tap(instance, vif)
866+
elif vif_type in {network_model.VIF_TYPE_802_QBG,
867+
network_model.VIF_TYPE_802_QBH,
868+
network_model.VIF_TYPE_HOSTDEV,
869+
network_model.VIF_TYPE_MACVTAP}:
870+
# These are no-ops
871+
pass
872+
else:
873+
# TODO(stephenfin): This should probably raise
874+
# VirtualInterfaceUnplugException
875+
raise exception.InternalError(
876+
_("Unplug VIF failed because of unexpected "
877+
"vif_type=%s") % vif_type)

0 commit comments

Comments
 (0)