Ejemplo n.º 1
0
    def unplug(self, vif, cna_w_list=None):
        """Unplugs a virtual interface (network) from a VM.

        Extends the base implementation, but before calling it will remove
        the adapter from the Open vSwitch and delete the trunk.

        :param vif: The virtual interface to plug into the instance.
        :param cna_w_list: (Optional, Default: None) The list of Client Network
                           Adapters from pypowervm.  Providing this input
                           allows for an improvement in operation speed.
        :return cna_w: The deleted Client Network Adapter.
        """
        # Need to find the adapters if they were not provided
        if not cna_w_list:
            cna_w_list = vm.get_cnas(self.adapter, self.instance)

        # Find the CNA for this vif.
        cna_w = self._find_cna_for_vif(cna_w_list, vif)
        if not cna_w:
            LOG.warning(
                'Unable to unplug VIF with mac %(mac)s for. The VIF '
                'was not found on the instance.', {'mac': vif['address']},
                instance=self.instance)
            return None

        # Find and delete the trunk adapters
        trunks = pvm_cna.find_trunks(self.adapter, cna_w)
        dev = self.get_trunk_dev_name(vif)
        linux_net.delete_ovs_vif_port(vif['network']['bridge'], dev)
        for trunk in trunks:
            trunk.delete()

        # Now delete the client CNA
        return super(PvmOvsVifDriver, self).unplug(vif, cna_w_list=cna_w_list)
Ejemplo n.º 2
0
    def unplug(self, vif, cna_w_list=None):
        """Unplugs a virtual interface (network) from a VM.

        Extends the base implementation, but before calling it will remove
        the adapter from the Open vSwitch and delete the trunk.

        :param vif: The virtual interface to plug into the instance.
        :param cna_w_list: (Optional, Default: None) The list of Client Network
                           Adapters from pypowervm.  Providing this input
                           allows for an improvement in operation speed.
        :return cna_w: The deleted Client Network Adapter.
        """
        # Need to find the adapters if they were not provided
        if not cna_w_list:
            cna_w_list = vm.get_cnas(self.adapter, self.instance)

        # Find the CNA for this vif.
        cna_w = self._find_cna_for_vif(cna_w_list, vif)
        if not cna_w:
            LOG.warning(_LW('Unable to unplug VIF with mac %(mac)s for '
                            'instance %(inst)s.  The VIF was not found on '
                            'the instance.'),
                        {'mac': vif['address'], 'inst': self.instance.name})
            return None

        # Find and delete the trunk adapters
        trunks = pvm_cna.find_trunks(self.adapter, cna_w)
        dev = self.get_trunk_dev_name(vif)
        linux_net.delete_ovs_vif_port(vif['network']['bridge'], dev)
        for trunk in trunks:
            trunk.delete()

        # Now delete the client CNA
        return super(PvmOvsVifDriver, self).unplug(vif, cna_w_list=cna_w_list)
Ejemplo n.º 3
0
    def unplug(self, vif, cna_w_list=None):
        """Unplugs a virtual interface (network) from a VM.

        Extends the base implementation, but before calling it will remove
        the adapter from the Open vSwitch and delete the trunk.

        :param vif: The virtual interface to plug into the instance.
        :param cna_w_list: (Optional, Default: None) The list of Client Network
                           Adapters from pypowervm.  Providing this input
                           allows for an improvement in operation speed.
        :return cna_w: The deleted Client Network Adapter or None if the CNA
                       is not found.
        """
        # Need to find the adapters if they were not provided
        if not cna_w_list:
            cna_w_list = vm.get_cnas(self.adapter, self.instance)

        # Find the CNA for this vif.
        cna_w = self._find_cna_for_vif(cna_w_list, vif)

        if not cna_w:
            LOG.warning('Unable to unplug VIF with mac %s for instance. The '
                        'VIF was not found on the instance.', vif['address'],
                        instance=self.instance)
            return None

        # Find and delete the trunk adapters
        trunks = pvm_cna.find_trunks(self.adapter, cna_w)
        for trunk in trunks:
            trunk.delete()

        # Delete the client CNA
        return super(PvmOvsVifDriver, self).unplug(vif, cna_w_list=cna_w_list)
Ejemplo n.º 4
0
    def unplug(self, vif, cna_w_list=None):
        """Unplugs a virtual interface (network) from a VM.

        Extends the base implementation, but before invoking it will remove
        itself from the bridge it is connected to and delete the corresponding
        trunk device on the mgmt partition.

        :param vif: The virtual interface to plug into the instance.
        :param cna_w_list: (Optional, Default: None) The list of Client Network
                           Adapters from pypowervm.  Providing this input
                           allows for an improvement in operation speed.
        :return cna_w: The deleted Client Network Adapter.
        """
        # Need to find the adapters if they were not provided
        if not cna_w_list:
            cna_w_list = vm.get_cnas(self.adapter, self.instance)

        # Find the CNA for this vif.
        cna_w = self._find_cna_for_vif(cna_w_list, vif)
        if not cna_w:
            LOG.warning(_LW('Unable to unplug VIF with mac %(mac)s for '
                            'instance %(inst)s.  The VIF was not found on '
                            'the instance.'), {
                                'mac': vif['address'],
                                'inst': self.instance.name
                            },
                        instance=self.instance)
            return None

        # Find and delete the trunk adapters
        trunks = pvm_cna.find_trunks(self.adapter, cna_w)

        dev_name = self.get_trunk_dev_name(vif)
        utils.execute('ip', 'link', 'set', dev_name, 'down', run_as_root=True)
        try:
            utils.execute('brctl',
                          'delif',
                          vif['network']['bridge'],
                          dev_name,
                          run_as_root=True)
        except Exception as e:
            LOG.warning(_LW('Unable to delete device %(dev_name)s from bridge '
                            '%(bridge)s. Error: %(error)s'), {
                                'dev_name': dev_name,
                                'bridge': vif['network']['bridge'],
                                'error': e.message
                            },
                        instance=self.instance)
        for trunk in trunks:
            trunk.delete()

        # Now delete the client CNA
        return super(PvmLBVifDriver, self).unplug(vif, cna_w_list=cna_w_list)
Ejemplo n.º 5
0
    def unplug(self, vif, cna_w_list=None):
        """Unplugs a virtual interface (network) from a VM.

        This will remove the adapter from the Open vSwitch and delete the
        trunk adapters.

        :param vif: The virtual interface to plug into the instance.
        :param cna_w_list: (Optional, Default: None) The list of Client Network
                           Adapters from pypowervm.  Providing this input
                           allows for an improvement in operation speed.
        :return cna_w: The deleted Client Network Adapter or None if the CNA
                       is not found.
        """
        # Need to find the adapters if they were not provided
        if not cna_w_list:
            cna_w_list = vm.get_cnas(self.adapter, self.instance)

        # Find the CNA for this vif.
        cna_w = self._find_cna_for_vif(cna_w_list, vif)

        if not cna_w:
            LOG.warning(
                'Unable to unplug VIF with mac %s for instance. The '
                'VIF was not found on the instance.',
                vif['address'],
                instance=self.instance)
            return None

        # Find and delete the trunk adapters
        trunks = pvm_cna.find_trunks(self.adapter, cna_w)
        for trunk in trunks:
            trunk.delete()

        # Now delete the client CNA
        LOG.info('Deleting VIF with mac %s for instance.',
                 vif['address'],
                 instance=self.instance)
        try:
            cna_w.delete()
        except Exception as e:
            LOG.error('Unable to unplug VIF with mac %s for instance.',
                      vif['address'],
                      instance=self.instance)
            raise exception.VirtualInterfaceUnplugException(
                reason=six.text_type(e))
        return cna_w
Ejemplo n.º 6
0
    def test_find_trunks(self, mock_vios_get, mock_get_mgmt, mock_find_trunk):
        # Mocked responses can be simple, since they are just fed into the
        # _find_trunk_on_lpar
        mock_vios_get.return_value = [mock.MagicMock(), mock.MagicMock()]
        mock_get_mgmt.return_value = mock.MagicMock()

        # The responses back from the find trunk.  Make it an odd trunk
        # priority ordering to make sure we sort properly
        v1 = mock.Mock(trunk_pri=3)
        c1, c2 = mock.Mock(trunk_pri=1), mock.Mock(trunk_pri=2)
        mock_find_trunk.side_effect = [v1, c1, c2]

        # Invoke the method.
        resp = cna.find_trunks(self.adpt, mock.Mock(pvid=2))

        # Make sure four calls to the find trunk
        self.assertEqual(3, mock_find_trunk.call_count)

        # Order of the response is important.  Should be based off of trunk
        # priority
        self.assertEqual([c1, c2, v1], resp)
Ejemplo n.º 7
0
    def pre_live_migrate_at_source(self, vif):
        """Performs the pre live migrate on the source host.

        This is executed directly before the migration is started on the source
        host.

        :param vif: The virtual interface that will be migrated.  This may be
                    called network_info in other portions of the code.
        :return: The list of TrunkAdapter's on the source that are hosting the
                 VM's vif.  Should only return data if those trunks should be
                 deleted after the migration.
        """
        # Right before the migration, we need to find the trunk on the source
        # host.
        mac = pvm_util.sanitize_mac_for_api(vif['address'])
        cna_w = pvm_net.CNA.search(self.adapter,
                                   parent_type=pvm_lpar.LPAR.schema_type,
                                   parent_uuid=vm.get_pvm_uuid(self.instance),
                                   one_result=True,
                                   mac=mac)

        return pvm_cna.find_trunks(self.adapter, cna_w)
Ejemplo n.º 8
0
    def unplug(self, vif, cna_w_list=None):
        """Unplugs a virtual interface (network) from a VM.

        Extends the base implementation, but before invoking it will remove
        itself from the bridge it is connected to and delete the corresponding
        trunk device on the mgmt partition.

        :param vif: The virtual interface to plug into the instance.
        :param cna_w_list: (Optional, Default: None) The list of Client Network
                           Adapters from pypowervm.  Providing this input
                           allows for an improvement in operation speed.
        :return cna_w: The deleted Client Network Adapter.
        """
        # Need to find the adapters if they were not provided
        if not cna_w_list:
            cna_w_list = vm.get_cnas(self.adapter, self.instance)

        # Find the CNA for this vif.
        cna_w = self._find_cna_for_vif(cna_w_list, vif)
        if not cna_w:
            LOG.warning(_LW('Unable to unplug VIF with mac %(mac)s for '
                            'instance %(inst)s.  The VIF was not found on '
                            'the instance.'),
                        {'mac': vif['address'], 'inst': self.instance.name})
            return None

        # Find and delete the trunk adapters
        trunks = pvm_cna.find_trunks(self.adapter, cna_w)

        dev_name = self.get_trunk_dev_name(vif)
        utils.execute('ip', 'link', 'set', dev_name, 'down', run_as_root=True)
        utils.execute('brctl', 'delif', vif['network']['bridge'],
                      dev_name, run_as_root=True)
        for trunk in trunks:
            trunk.delete()

        # Now delete the client CNA
        return super(PvmLBVifDriver, self).unplug(vif, cna_w_list=cna_w_list)
Ejemplo n.º 9
0
    def plug(self, vif, new_vif=True):
        """Plugs a virtual interface (network) into a VM.

        Creates a 'peer to peer' connection between the Management partition
        hosting the Linux I/O and the client VM.  There will be one trunk
        adapter for a given client adapter.

        The device will be 'up' on the mgmt partition.

        Will make sure that the trunk device has the appropriate metadata (e.g.
        port id) set on it so that the Open vSwitch agent picks it up properly.

        :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 new vif that was created.  Only returned if new_vif is
                 set to True.  Otherwise None is expected.
        """

        # Create the trunk and client adapter.
        lpar_uuid = vm.get_pvm_uuid(self.instance)
        mgmt_uuid = pvm_par.get_this_partition(self.adapter).uuid

        mtu = vif['network'].get_meta('mtu')
        if 'devname' in vif:
            dev_name = vif['devname']
        else:
            dev_name = ("nic" + vif['id'])[:network_model.NIC_NAME_LEN]

        meta_attrs = ','.join([
            'iface-id=%s' % (vif.get('ovs_interfaceid') or vif['id']),
            'iface-status=active',
            'attached-mac=%s' % vif['address'],
            'vm-uuid=%s' % self.instance.uuid
        ])

        if new_vif:
            return pvm_cna.crt_p2p_cna(self.adapter,
                                       None,
                                       lpar_uuid, [mgmt_uuid],
                                       NOVALINK_VSWITCH,
                                       crt_vswitch=True,
                                       mac_addr=vif['address'],
                                       dev_name=dev_name,
                                       ovs_bridge=vif['network']['bridge'],
                                       ovs_ext_ids=meta_attrs,
                                       configured_mtu=mtu)[0]
        else:
            # Bug : https://bugs.launchpad.net/nova-powervm/+bug/1731548
            # When a host is rebooted, something is discarding tap devices for
            # VMs deployed with OVS vif. To prevent VMs losing network
            # connectivity, this is fixed by recreating the tap devices during
            # init of the nova compute service, which will call vif plug with
            # new_vif==False.

            # Find the CNA for this vif.
            # TODO(esberglu) improve performance by caching VIOS wrapper(s) and
            # CNA lists (in case >1 vif per VM).
            cna_w_list = vm.get_cnas(self.adapter, self.instance)
            cna_w = self._find_cna_for_vif(cna_w_list, vif)
            if not cna_w:
                LOG.warning(
                    'Unable to plug VIF with mac %s for instance. The '
                    'VIF was not found on the instance.',
                    vif['address'],
                    instance=self.instance)
                return None

            # Find the corresponding trunk adapter
            trunks = pvm_cna.find_trunks(self.adapter, cna_w)
            for trunk in trunks:
                # Set MTU, OVS external ids, and OVS bridge metadata
                trunk.configured_mtu = mtu
                trunk.ovs_ext_ids = meta_attrs
                trunk.ovs_bridge = vif['network']['bridge']
                # Updating the trunk adapter will cause NovaLink to reassociate
                # the tap device.
                trunk.update()
Ejemplo n.º 10
0
    def plug(self, vif, new_vif=True):
        """Plugs a virtual interface (network) into a VM.

        Creates a 'peer to peer' connection between the Management partition
        hosting the Linux I/O and the client VM.  There will be one trunk
        adapter for a given client adapter.

        The device will be 'up' on the mgmt partition.

        Will make sure that the trunk device has the appropriate metadata (e.g.
        port id) set on it so that the Open vSwitch agent picks it up properly.

        :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 new vif that was created.  Only returned if new_vif is
                 set to True.  Otherwise None is expected.
        """

        # Create the trunk and client adapter.
        lpar_uuid = vm.get_pvm_uuid(self.instance)
        mgmt_uuid = pvm_par.get_this_partition(self.adapter).uuid

        mtu = vif['network'].get_meta('mtu')
        if 'devname' in vif:
            dev_name = vif['devname']
        else:
            dev_name = ("nic" + vif['id'])[:network_model.NIC_NAME_LEN]

        meta_attrs = ','.join([
                     'iface-id=%s' % (vif.get('ovs_interfaceid') or vif['id']),
                     'iface-status=active',
                     'attached-mac=%s' % vif['address'],
                     'vm-uuid=%s' % self.instance.uuid])

        if new_vif:
            return pvm_cna.crt_p2p_cna(
                self.adapter, None, lpar_uuid, [mgmt_uuid], NOVALINK_VSWITCH,
                crt_vswitch=True, mac_addr=vif['address'], dev_name=dev_name,
                ovs_bridge=vif['network']['bridge'],
                ovs_ext_ids=meta_attrs, configured_mtu=mtu)[0]
        else:
            # Bug : https://bugs.launchpad.net/nova-powervm/+bug/1731548
            # When a host is rebooted, something is discarding tap devices for
            # VMs deployed with OVS vif. To prevent VMs losing network
            # connectivity, this is fixed by recreating the tap devices during
            # init of the nova compute service, which will call vif plug with
            # new_vif==False.

            # Find the CNA for this vif.
            # TODO(esberglu) improve performance by caching VIOS wrapper(s) and
            # CNA lists (in case >1 vif per VM).
            cna_w_list = vm.get_cnas(self.adapter, self.instance)
            cna_w = self._find_cna_for_vif(cna_w_list, vif)
            if not cna_w:
                LOG.warning('Unable to plug VIF with mac %s for instance. The '
                            'VIF was not found on the instance.',
                            vif['address'], instance=self.instance)
                return None

            # Find the corresponding trunk adapter
            trunks = pvm_cna.find_trunks(self.adapter, cna_w)
            for trunk in trunks:
                # Set MTU, OVS external ids, and OVS bridge metadata
                trunk.configured_mtu = mtu
                trunk.ovs_ext_ids = meta_attrs
                trunk.ovs_bridge = vif['network']['bridge']
                # Updating the trunk adapter will cause NovaLink to reassociate
                # the tap device.
                trunk.update()
Ejemplo n.º 11
0
    def plug(self, vif, slot_num, new_vif=True):
        """Plugs a virtual interface (network) into a VM.

        Extends the Lio implementation.  Will make sure that the trunk device
        has the appropriate metadata (ex. port id) set on it so that the
        Open vSwitch agent picks it up properly.

        :param vif: The virtual interface to plug into the instance.
        :param slot_num: Which slot number to plug the VIF into.  May be None.
        :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 new vif that was created.  Only returned if new_vif is
                 set to True.  Otherwise None is expected.
        """
        lpar_uuid = vm.get_pvm_uuid(self.instance)
        mgmt_uuid = pvm_par.get_mgmt_partition(self.adapter).uuid

        # There will only be one trunk wrap, as we have created with just
        # the mgmt lpar.  Next step is to connect to the OVS.
        mtu = vif['network'].get_meta('mtu')
        dev_name = _get_trunk_dev_name(vif)

        meta_attrs = PvmMetaAttrs(vif, self.instance)

        if new_vif:
            # Create the trunk and client adapter.
            return pvm_cna.crt_p2p_cna(
                self.adapter,
                self.host_uuid,
                lpar_uuid, [mgmt_uuid],
                CONF.powervm.pvm_vswitch_for_novalink_io,
                crt_vswitch=True,
                mac_addr=vif['address'],
                dev_name=dev_name,
                slot_num=slot_num,
                ovs_bridge=vif['network']['bridge'],
                ovs_ext_ids=str(meta_attrs),
                configured_mtu=mtu)[0]
        else:
            # Bug : https://bugs.launchpad.net/nova-powervm/+bug/1731548
            # When a host is rebooted, something is discarding tap devices for
            # VMs deployed with OVS vif. To prevent VMs losing network
            # connectivity, this is fixed by recreating the tap devices during
            # init of the nova compute service, which will call vif plug with
            # new_vif==False.

            # Find the CNA for this vif.
            # TODO(svenkat) improve performance by caching VIOS wrapper(s) and
            # CNA lists (in case >1 vif per VM).
            cna_w_list = vm.get_cnas(self.adapter, self.instance)
            cna_w = self._find_cna_for_vif(cna_w_list, vif)
            # Find the corresponding trunk adapter
            trunks = pvm_cna.find_trunks(self.adapter, cna_w)
            for trunk in trunks:
                # Set MTU, OVS external ids, and OVS bridge metadata
                # TODO(svenkat) set_parm_value calls should be replaced once
                # pypowervm supports setting these values directly.
                trunk.set_parm_value('ConfiguredMTU',
                                     mtu,
                                     attrib=pvm_c.ATTR_KSV160)
                trunk.set_parm_value('OvsPortExternalIds',
                                     meta_attrs,
                                     attrib=pvm_c.ATTR_KSV160)
                trunk.set_parm_value('OvsBridge',
                                     vif['network']['bridge'],
                                     attrib=pvm_c.ATTR_KSV160)
                # Updating the trunk adapter will cause NovaLink to reassociate
                # the tap device.
                trunk.update()