Example #1
0
    def plug(self, instance, vif):
        vif_type = vif['type']

        LOG.debug('vif_type=%(vif_type)s instance=%(instance)s '
                  'vif=%(vif)s', {
                      'vif_type': vif_type,
                      'instance': instance,
                      'vif': vif
                  })

        if vif_type is None:
            raise exception.VirtualInterfacePlugException(
                _("vif_type parameter must be present "
                  "for this vif_driver implementation"))

        # Try os-vif codepath first
        vif_obj = os_vif_util.nova_to_osvif_vif(vif)
        if vif_obj is not None:
            self._plug_os_vif(instance, vif_obj)
            return

        # Legacy non-os-vif codepath
        vif_slug = self._normalize_vif_type(vif_type)
        func = getattr(self, 'plug_%s' % vif_slug, None)
        if not func:
            raise exception.VirtualInterfacePlugException(
                _("Plug vif failed because of unexpected "
                  "vif_type=%s") % vif_type)
        func(instance, vif)
Example #2
0
def _build_vif_driver(adapter, host_uuid, instance, vif):
    """Returns the appropriate VIF Driver for the given VIF.

    :param adapter: The pypowervm adapter API interface.
    :param host_uuid: The host system UUID.
    :param instance: The nova instance.
    :param vif: The virtual interface to from Nova.
    :return: The appropriate PvmVifDriver for the VIF.
    """
    if vif.get('type') is None:
        raise exception.VirtualInterfacePlugException(
            _("vif_type parameter must be present for this vif_driver "
              "implementation"))

    # Check the type to the implementations
    if VIF_MAPPING.get(vif['type']):
        return importutils.import_object(VIF_MAPPING.get(vif['type']), adapter,
                                         host_uuid, instance)

    # No matching implementation, raise error.
    raise exception.VirtualInterfacePlugException(
        _("Unable to find appropriate PowerVM VIF Driver for VIF type "
          "%(vif_type)s on instance %(instance)s") % {
              'vif_type': vif['type'],
              'instance': instance.name
          })
Example #3
0
    def plug_vifs(self, instance, network_info):
        """Plug VIFs into networks."""
        self._log_operation('plug_vifs', instance)

        # Define the flow
        flow = tf_lf.Flow("plug_vifs")

        # Get the LPAR Wrapper
        flow.add(tf_vm.Get(self.adapter, instance))

        # Run the attach
        flow.add(
            tf_net.PlugVifs(self.virtapi, self.adapter, instance,
                            network_info))

        # Run the flow
        try:
            tf_base.run(flow, instance=instance)
        except exc.InstanceNotFound:
            raise exc.VirtualInterfacePlugException(
                _("Plug vif failed because instance %s was not found.") %
                instance.name)
        except Exception:
            LOG.exception("PowerVM error plugging vifs.", instance=instance)
            raise exc.VirtualInterfacePlugException(
                _("Plug vif failed because of an unexpected error."))
Example #4
0
    def post_start_actions(self, instance, vif_ref):
        """Do needed actions post vif start:
        plug the interim ovs bridge to the integration bridge;
        set external_ids to the int-br port which will service
        for this vif.
        """
        vif_rec = self._session.VIF.get_record(vif_ref)
        network_ref = vif_rec['network']
        bridge_name = self._session.network.get_bridge(network_ref)
        network_uuid = self._session.network.get_uuid(network_ref)
        iface_id = vif_rec['other_config']['nicira-iface-id']
        patch_port1, patch_port2 = self._get_patch_port_pair_names(iface_id)
        LOG.debug(
            'plug_ovs_bridge: port1=%(port1)s, port2=%(port2)s,'
            'network_uuid=%(uuid)s, bridge_name=%(bridge_name)s', {
                'port1': patch_port1,
                'port2': patch_port2,
                'uuid': network_uuid,
                'bridge_name': bridge_name
            })
        if bridge_name is None:
            raise exception.VirtualInterfacePlugException(
                _("Failed to find bridge for vif"))

        self._ovs_add_patch_port(bridge_name, patch_port1, patch_port2)
        self._ovs_add_patch_port(CONF.xenserver.ovs_integration_bridge,
                                 patch_port2, patch_port1)
        self._ovs_map_external_ids(patch_port2, vif_rec)
Example #5
0
    def _plug_vifs(self, node, instance, network_info):
        # NOTE(PhilDay): Accessing network_info will block if the thread
        # it wraps hasn't finished, so do this ahead of time so that we
        # don't block while holding the logging lock.
        network_info_str = str(network_info)
        LOG.debug("plug: instance_uuid=%(uuid)s vif=%(network_info)s", {
            'uuid': instance.uuid,
            'network_info': network_info_str
        })
        # start by ensuring the ports are clear
        self._unplug_vifs(node, instance, network_info)

        ports = self.ironicclient.call("node.list_ports", node.uuid)

        if len(network_info) > len(ports):
            raise exception.VirtualInterfacePlugException(
                _("Ironic node: %(id)s virtual to physical interface count"
                  "  missmatch"
                  " (Vif count: %(vif_count)d, Pif count: %(pif_count)d)") % {
                      'id': node.uuid,
                      'vif_count': len(network_info),
                      'pif_count': len(ports)
                  })

        if len(network_info) > 0:
            # not needed if no vif are defined
            for vif, pif in zip(network_info, ports):
                # attach what neutron needs directly to the port
                port_id = unicode(vif['id'])
                patch = [{
                    'op': 'add',
                    'path': '/extra/vif_port_id',
                    'value': port_id
                }]
                self.ironicclient.call("port.update", pif.uuid, patch)
Example #6
0
def plug(adapter, instance, vif, new_vif=True):
    """Plugs a virtual interface (network) into a VM.

    :param adapter: The pypowervm adapter.
    :param instance: The nova instance object.
    :param vif: The virtual interface to plug into the instance.
    :param new_vif: (Optional, Default: True) If set, indicates that it is
                    a brand new VIF.  If False, it indicates that the VIF
                    is already on the client but should be treated on the
                    bridge.
    :return: The wrapper (CNA) representing the plugged virtual network. None
             if the vnet was not created.
    """
    vif_drv = _build_vif_driver(adapter, instance, vif)

    try:
        vnet_w = vif_drv.plug(vif, new_vif=new_vif)
    except pvm_ex.HttpError:
        LOG.exception('VIF plug failed for instance.', instance=instance)
        raise exception.VirtualInterfacePlugException()
    # Other exceptions are (hopefully) custom VirtualInterfacePlugException
    # generated lower in the call stack.

    # Push a custom event if we really plugged the vif
    if vnet_w is not None:
        _push_vif_event(adapter, 'plug', vnet_w, instance, vif['type'])

    return vnet_w
Example #7
0
    def post_start_actions(self, instance, vif_ref):
        """Do needed actions post vif start:
        plug the interim ovs bridge to the integration bridge;
        set external_ids to the int-br port which will service
        for this vif.
        """
        vif_rec = self._session.VIF.get_record(vif_ref)
        network_ref = vif_rec['network']
        bridge_name = self._session.network.get_bridge(network_ref)
        network_uuid = self._session.network.get_uuid(network_ref)
        iface_id = vif_rec['other_config']['neutron-port-id']
        patch_port1, tap_name = self._get_patch_port_pair_names(iface_id)
        LOG.debug('plug_ovs_bridge: port1=%(port1)s, port2=%(port2)s,'
                  'network_uuid=%(uuid)s, bridge_name=%(bridge_name)s',
                  {'port1': patch_port1, 'port2': tap_name,
                   'uuid': network_uuid, 'bridge_name': bridge_name})
        if bridge_name is None:
            raise exception.VirtualInterfacePlugException(
                      _("Failed to find bridge for vif"))

        # Create Linux bridge qbrXXX
        linux_br_name = self._create_linux_bridge(vif_rec)
        if not self._device_exists(tap_name):
            LOG.debug("create veth pair for interim bridge %(interim_bridge)s "
                      "and linux bridge %(linux_bridge)s",
                      {'interim_bridge': bridge_name,
                       'linux_bridge': linux_br_name})
            self._create_veth_pair(tap_name, patch_port1)
            host_network.brctl_add_if(self._session, linux_br_name, tap_name)
            # Add port to interim bridge
            host_network.ovs_add_port(self._session, bridge_name, patch_port1)
Example #8
0
 def create_vif_interim_network(self, vif):
     net_name = self.get_vif_interim_net_name(vif['id'])
     # In a pooled environment, make the network shared in order to ensure
     # it can also be used in the target host while live migrating.
     # "assume_network_is_shared" flag does not affect environments where
     # storage pools are not used.
     network_rec = {
         'name_label': net_name,
         'name_description': "interim network for vif[%s]" % vif['id'],
         'other_config': {
             'assume_network_is_shared': 'true'
         }
     }
     network_ref = network_utils.find_network_with_name_label(
         self._session, net_name)
     if network_ref:
         # already exist, just return
         # in some scenarios: e..g resize/migrate, it won't create new
         # interim network.
         return network_ref
     try:
         network_ref = self._session.network.create(network_rec)
     except Exception as e:
         LOG.warning(
             "Failed to create interim network for vif %(if)s, "
             "exception:%(exception)s", {
                 'if': vif,
                 'exception': e
             })
         raise exception.VirtualInterfacePlugException(
             _("Failed to create the interim network for vif"))
     return network_ref
Example #9
0
 def create_vif_interim_network(self, vif):
     net_name = self.get_vif_interim_net_name(vif['id'])
     network_rec = {
         'name_label': net_name,
         'name_description': "interim network for vif",
         'other_config': {}
     }
     network_ref = network_utils.find_network_with_name_label(
         self._session, net_name)
     if network_ref:
         # already exist, just return
         # in some scenarios: e..g resize/migrate, it won't create new
         # interim network.
         return network_ref
     try:
         network_ref = self._session.network.create(network_rec)
     except Exception as e:
         LOG.warning(
             _LW("Failed to create interim network for vif %(if)s, "
                 "exception:%(exception)s"), {
                     'if': vif,
                     'exception': e
                 })
         raise exception.VirtualInterfacePlugException(
             _("Failed to create the interim network for vif"))
     return network_ref
Example #10
0
File: vif.py Project: YLTiny/nova
    def plug(self, instance, vif):
        vif_type = vif['type']

        # instance.display_name could be unicode
        instance_repr = utils.get_obj_repr_unicode(instance)
        LOG.debug('vif_type=%(vif_type)s instance=%(instance)s '
                  'vif=%(vif)s', {
                      'vif_type': vif_type,
                      'instance': instance_repr,
                      'vif': vif
                  })

        if vif_type is None:
            raise exception.VirtualInterfacePlugException(
                _("vif_type parameter must be present "
                  "for this vif_driver implementation"))

        # Try os-vif codepath first
        vif_obj = os_vif_util.nova_to_osvif_vif(vif)
        if vif_obj is not None:
            self._plug_os_vif(instance, vif_obj)
            return

        # Legacy non-os-vif codepath
        if vif_type == network_model.VIF_TYPE_IB_HOSTDEV:
            self.plug_ib_hostdev(instance, vif)
        elif vif_type == network_model.VIF_TYPE_HW_VEB:
            self.plug_hw_veb(instance, vif)
        elif vif_type == network_model.VIF_TYPE_MACVTAP:
            self.plug_macvtap(instance, vif)
        elif vif_type == network_model.VIF_TYPE_MIDONET:
            self.plug_midonet(instance, vif)
        elif vif_type == network_model.VIF_TYPE_IOVISOR:
            self.plug_iovisor(instance, vif)
        elif vif_type == network_model.VIF_TYPE_TAP:
            self.plug_tap(instance, vif)
        elif vif_type in {
                network_model.VIF_TYPE_802_QBG, network_model.VIF_TYPE_802_QBH,
                network_model.VIF_TYPE_HOSTDEV
        }:
            # These are no-ops
            pass
        else:
            raise exception.VirtualInterfacePlugException(
                _("Plug VIF failed because of unexpected "
                  "vif_type=%s") % vif_type)
Example #11
0
    def plug(self, instance, vif):
        vif_type = vif['type']

        LOG.debug('vif_type=%(vif_type)s instance=%(instance)s '
                  'vif=%(vif)s',
                  {'vif_type': vif_type, 'instance': instance,
                   'vif': vif})

        if vif_type is None:
            raise exception.VirtualInterfacePlugException(
                _("vif_type parameter must be present "
                  "for this vif_driver implementation"))
        vif_slug = self._normalize_vif_type(vif_type)
        func = getattr(self, 'plug_%s' % vif_slug, None)
        if not func:
            raise exception.VirtualInterfacePlugException(
                _("Plug vif failed because of unexpected "
                  "vif_type=%s") % vif_type)
        func(instance, vif)
Example #12
0
def _build_vif_driver(adapter, instance, vif):
    """Returns the appropriate VIF Driver for the given VIF.
    :param adapter: The pypowervm adapter API interface.
    :param instance: The nova instance.
    :param vif: The virtual interface.
    :return: The appropriate PvmVifDriver for the VIF.
    """
    if vif.get('type') is None:
        LOG.exception("Failed to build vif driver. Missing vif type.",
                      instance=instance)
        raise exception.VirtualInterfacePlugException()

    # Check the type to the implementations
    if VIF_MAPPING.get(vif['type']):
        return importutils.import_object(VIF_MAPPING.get(vif['type']), adapter,
                                         instance)

    # No matching implementation, raise error.
    LOG.exception("Failed to build vif driver. Invalid vif type provided.",
                  instance=instance)
    raise exception.VirtualInterfacePlugException()
Example #13
0
    def plug(self, instance, vif):
        vif_type = vif['type']
        if vif_type == model.VIF_TYPE_HYPERV:
            self._vif_plugin.plug(instance, vif)
        elif vif_type == model.VIF_TYPE_OVS:
            vif = os_vif_util.nova_to_osvif_vif(vif)
            instance = os_vif_util.nova_to_osvif_instance(instance)

            # NOTE(claudiub): the vNIC has to be connected to a vSwitch
            # before the ovs port is created.
            self._netutils.connect_vnic_to_vswitch(CONF.hyperv.vswitch_name,
                                                   vif.id)
            os_vif.plug(vif, instance)
        else:
            reason = _("Failed to plug virtual interface: "
                       "unexpected vif_type=%s") % vif_type
            raise exception.VirtualInterfacePlugException(reason)
Example #14
0
    def plug(self, instance, vif, vm_ref=None, device=None):
        """create an interim network for this vif; and build
        the vif_rec which will be used by xapi to create VM vif
        """
        if not vm_ref:
            vm_ref = vm_utils.lookup(self._session, instance['name'])
        if not vm_ref:
            raise exception.VirtualInterfacePlugException(
                "Cannot find instance %s, discard vif plug" % instance['name'])

        # if VIF already exists, return this vif_ref directly
        vif_ref = self._get_vif_ref(vif, vm_ref)
        if vif_ref:
            LOG.debug("VIF %s already exists when plug vif",
                      vif_ref,
                      instance=instance)
            return vif_ref

        if not device:
            device = 0

        # Create an interim network for each VIF, so dom0 has a single
        # bridge for each device (the emulated and PV ethernet devices
        # will both be on this bridge.
        network_ref = self.create_vif_interim_network(vif)
        vif_rec = {}
        vif_rec['device'] = str(device)
        vif_rec['network'] = network_ref
        vif_rec['VM'] = vm_ref
        vif_rec['MAC'] = vif['address']
        vif_rec['MTU'] = '1500'
        vif_rec['qos_algorithm_type'] = ''
        vif_rec['qos_algorithm_params'] = {}
        # Deprecated: 'niciria-iface-id', will remove it in the next release
        vif_rec['other_config'] = {
            'nicira-iface-id': vif['id'],
            'neutron-port-id': vif['id']
        }
        vif_ref = self._create_vif(vif, vif_rec, vm_ref)

        # call XenAPI to plug vif
        self.hot_plug(vif, instance, vm_ref, vif_ref)

        return vif_ref
Example #15
0
def plug(adapter, host_uuid, instance, vif, slot_mgr, new_vif=True):
    """Plugs a virtual interface (network) into a VM.

    :param adapter: The pypowervm adapter.
    :param host_uuid: The host UUID for the PowerVM API.
    :param instance: The nova instance object.
    :param vif: The virtual interface to plug into the instance.
    :param slot_mgr: A NovaSlotManager.  Used to store/retrieve the client
                     slots used when a VIF is attached to the VM.
    :param new_vif: (Optional, Default: True) If set, indicates that it is
                    a brand new VIF.  If False, it indicates that the VIF
                    is already on the client but should be treated on the
                    bridge.
    :return: The wrapper (CNA or VNIC) representing the plugged virtual
             network.  None if the vnet was not created.
    """
    vif_drv = _build_vif_driver(adapter, host_uuid, instance, vif)

    # Get the slot number to use for the VIF creation.  May be None
    # indicating usage of the next highest available.
    slot_num = slot_mgr.build_map.get_vnet_slot(vif['address'])

    # Invoke the plug
    try:
        vnet_w = vif_drv.plug(vif, slot_num, new_vif=new_vif)
    except pvm_ex.HttpError as he:
        # Log the message constructed by HttpError
        LOG.exception("HttpError during vif plug operation.",
                      instance=instance)
        raise exception.VirtualInterfacePlugException(reason=he.args[0])
    # Other exceptions are (hopefully) custom VirtualInterfacePlugException
    # generated lower in the call stack.

    # If the slot number hadn't been provided initially, save it for the
    # next rebuild
    if not slot_num and new_vif:
        slot_mgr.register_vnet(vnet_w)

    # Push a custom event if we really plugged the vif
    if vnet_w is not None:
        _push_vif_event(adapter, 'plug', vnet_w, instance, vif['type'])

    return vnet_w
Example #16
0
def plug(adapter, instance, vif, new_vif=True):
    """Plugs a virtual interface (network) into a VM.

    :param adapter: The pypowervm adapter.
    :param instance: The nova instance object.
    :param vif: The virtual interface to plug into the instance.
    :param new_vif: (Optional, Default: True) If set, indicates that it is
                    a brand new VIF.  If False, it indicates that the VIF
                    is already on the client but should be treated on the
                    bridge.
    :return: The wrapper (CNA) representing the plugged virtual network. None
             if the vnet was not created.
    """
    vif_drv = _build_vif_driver(adapter, instance, vif)

    try:
        return vif_drv.plug(vif, new_vif=new_vif)
    except pvm_ex.HttpError:
        LOG.exception('VIF plug failed for instance.', instance=instance)
        raise exception.VirtualInterfacePlugException()
Example #17
0
    def plug(self, instance, vif, vm_ref=None, device=None):
        if not vm_ref:
            vm_ref = vm_utils.lookup(self._session, instance['name'])
        if not vm_ref:
            raise exception.VirtualInterfacePlugException(
                "Cannot find instance %s, discard vif plug" % instance['name'])

        # if VIF already exists, return this vif_ref directly
        vif_ref = self._get_vif_ref(vif, vm_ref)
        if vif_ref:
            LOG.debug("VIF %s already exists when plug vif",
                      vif_ref,
                      instance=instance)
            return vif_ref

        if not device:
            device = 0

        if vif['network'].get_meta('should_create_vlan'):
            network_ref = self._ensure_vlan_bridge(vif['network'])
        else:
            network_ref = network_utils.find_network_with_bridge(
                self._session, vif['network']['bridge'])
        vif_rec = {}
        vif_rec['device'] = str(device)
        vif_rec['network'] = network_ref
        vif_rec['VM'] = vm_ref
        vif_rec['MAC'] = vif['address']
        vif_rec['MTU'] = '1500'
        vif_rec['other_config'] = {}
        if vif.get_meta('rxtx_cap'):
            vif_rec['qos_algorithm_type'] = 'ratelimit'
            vif_rec['qos_algorithm_params'] = {
                'kbps': str(int(vif.get_meta('rxtx_cap')) * 1024)
            }
        else:
            vif_rec['qos_algorithm_type'] = ''
            vif_rec['qos_algorithm_params'] = {}
        return self._create_vif(vif, vif_rec, vm_ref)
Example #18
0
    def plug(self, vif, slot_num, new_vif=True):
        if not new_vif:
            return None

        physnet = vif.get_physical_network()
        if not physnet:
            # Get physnet from neutron network if not present in vif
            # TODO(svenkat): This section of code will be eliminated in
            # pike release. Design will be in place to fix any vif
            # that has physical_network missing. The fix will be in
            # compute startup code.
            net_id = vif['network']['id']
            admin_context = ctx.get_admin_context()
            napi = net_api.API()
            network = napi.get(admin_context, net_id)
            physnet = network.physical_network

        LOG.debug("Plugging vNIC SR-IOV vif for physical network %(physnet)s.",
                  {'physnet': physnet},
                  instance=self.instance)

        # Get the msys
        msys = pvm_ms.System.get(self.adapter)[0]
        # Physical ports for the given port label
        pports_w = sriovtask.find_pports_for_portlabel(physnet, self.adapter,
                                                       msys)
        pports = [pport.loc_code for pport in pports_w]

        if not pports:
            raise exception.VirtualInterfacePlugException(
                _("Unable to find acceptable Ethernet ports on physical "
                  "network '%(physnet)s' for instance %(inst)s for SRIOV "
                  "based VIF with MAC address %(vif_mac)s.") % {
                      'physnet': physnet,
                      'inst': self.instance.name,
                      'vif_mac': vif['address']
                  })

        # MAC
        mac_address = pvm_util.sanitize_mac_for_api(vif['address'])

        # vlan id
        vlan_id = int(vif['details']['vlan'])

        # Redundancy: plugin sets from binding:profile, then conf, then default
        redundancy = int(vif['details']['redundancy'])

        # Capacity: plugin sets from binding:profile, then conf, then default
        capacity = vif['details']['capacity']

        vnic = pvm_card.VNIC.bld(self.adapter,
                                 vlan_id,
                                 slot_num=slot_num,
                                 mac_addr=mac_address,
                                 allowed_vlans=pvm_util.VLANList.NONE,
                                 allowed_macs=pvm_util.MACList.NONE)

        sriovtask.set_vnic_back_devs(vnic,
                                     pports,
                                     sys_w=msys,
                                     redundancy=redundancy,
                                     capacity=capacity,
                                     check_port_status=True)

        return vnic.create(parent_type=pvm_lpar.LPAR,
                           parent_uuid=vm.get_pvm_uuid(self.instance))