コード例 #1
0
    def unplug(self, vif, cna_w_list=None):
        """Unplugs a virtual interface (network) from a VM.

        :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.
        """
        # This is a default implementation that most implementations will
        # require.

        # 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)

        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.  The VIF was '
                'not found on the instance.', {'mac': vif['address']},
                instance=self.instance)
            return None

        LOG.info('Deleting VIF with mac %(mac)s.', {'mac': vif['address']},
                 instance=self.instance)
        try:
            cna_w.delete()
        except Exception as e:
            LOG.exception('Unable to unplug VIF with mac %(mac)s.',
                          {'mac': vif['address']},
                          instance=self.instance)
            raise exception.VirtualInterfaceUnplugException(reason=str(e))
        return cna_w
コード例 #2
0
ファイル: vif.py プロジェクト: arbrandes/nova
    def unplug(self, vif, cna_w_list=None):
        """Unplugs a virtual interface (network) from a VM.

        :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.
        """
        # This is a default implementation that most implementations will
        # require.

        # 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)

        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.  The VIF was '
                        'not found on the instance.',
                        {'mac': vif['address']}, instance=self.instance)
            return None

        LOG.info('Deleting VIF with mac %(mac)s.',
                 {'mac': vif['address']}, instance=self.instance)
        try:
            cna_w.delete()
        except Exception as e:
            LOG.exception('Unable to unplug VIF with mac %(mac)s.',
                          {'mac': vif['address']}, instance=self.instance)
            raise exception.VirtualInterfaceUnplugException(
                reason=six.text_type(e))
        return cna_w
コード例 #3
0
ファイル: vif.py プロジェクト: arbrandes/nova
    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)
コード例 #4
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)
コード例 #5
0
ファイル: network.py プロジェクト: arbrandes/nova
    def execute(self, vm_cnas):
        LOG.info('Plugging the Management Network Interface to instance.',
                 instance=self.instance)
        # Determine if we need to create the secure RMC VIF.  This should only
        # be needed if there is not a VIF on the secure RMC vSwitch
        vswitch = None
        vswitches = pvm_net.VSwitch.search(
            self.adapter, parent_type=pvm_ms.System.schema_type,
            parent_uuid=self.adapter.sys_uuid, name=SECURE_RMC_VSWITCH)
        if len(vswitches) == 1:
            vswitch = vswitches[0]

        if vswitch is None:
            LOG.warning('No management VIF created for instance due to lack '
                        'of Management Virtual Switch', instance=self.instance)
            return None

        # This next check verifies that there are no existing NICs on the
        # vSwitch, so that the VM does not end up with multiple RMC VIFs.
        if vm_cnas is None:
            has_mgmt_vif = vm.get_cnas(self.adapter, self.instance,
                                       vswitch_uri=vswitch.href)
        else:
            has_mgmt_vif = vswitch.href in [cna.vswitch_uri for cna in vm_cnas]

        if has_mgmt_vif:
            LOG.debug('Management VIF already created for instance',
                instance=self.instance)
            return None

        lpar_uuid = vm.get_pvm_uuid(self.instance)
        return pvm_cna.crt_cna(self.adapter, None, lpar_uuid, SECURE_RMC_VLAN,
                               vswitch=SECURE_RMC_VSWITCH, crt_vswitch=True)
コード例 #6
0
ファイル: test_vm.py プロジェクト: arbrandes/nova
 def test_get_cnas(self, mock_get, mock_search, mock_uuid):
     # No kwargs: get
     self.assertEqual(mock_get.return_value, vm.get_cnas(self.apt, 'inst'))
     mock_uuid.assert_called_once_with('inst')
     mock_get.assert_called_once_with(self.apt, parent_type=pvm_lpar.LPAR,
                                      parent_uuid=mock_uuid.return_value)
     mock_search.assert_not_called()
     # With kwargs: search
     mock_get.reset_mock()
     mock_uuid.reset_mock()
     self.assertEqual(mock_search.return_value, vm.get_cnas(
         self.apt, 'inst', one=2, three=4))
     mock_uuid.assert_called_once_with('inst')
     mock_search.assert_called_once_with(
         self.apt, parent_type=pvm_lpar.LPAR,
         parent_uuid=mock_uuid.return_value, one=2, three=4)
     mock_get.assert_not_called()
コード例 #7
0
 def test_get_cnas(self, mock_get, mock_search, mock_uuid):
     # No kwargs: get
     self.assertEqual(mock_get.return_value, vm.get_cnas(self.apt, 'inst'))
     mock_uuid.assert_called_once_with('inst')
     mock_get.assert_called_once_with(self.apt,
                                      parent_type=pvm_lpar.LPAR,
                                      parent_uuid=mock_uuid.return_value)
     mock_search.assert_not_called()
     # With kwargs: search
     mock_get.reset_mock()
     mock_uuid.reset_mock()
     self.assertEqual(mock_search.return_value,
                      vm.get_cnas(self.apt, 'inst', one=2, three=4))
     mock_uuid.assert_called_once_with('inst')
     mock_search.assert_called_once_with(self.apt,
                                         parent_type=pvm_lpar.LPAR,
                                         parent_uuid=mock_uuid.return_value,
                                         one=2,
                                         three=4)
     mock_get.assert_not_called()
コード例 #8
0
    def _vif_exists(self, network_info):
        """Does the instance have a CNA for a given net?

        :param network_info: A network information dict.  This method expects
                             it to contain key 'address' (MAC address).
        :return: True if a CNA with the network_info's MAC address exists on
                 the instance.  False otherwise.
        """
        if self.cnas is None:
            self.cnas = vm.get_cnas(self.adapter, self.instance)
        vifs = self.cnas

        return network_info['address'] in [vm.norm_mac(v.mac) for v in vifs]
コード例 #9
0
ファイル: network.py プロジェクト: arbrandes/nova
    def _vif_exists(self, network_info):
        """Does the instance have a CNA for a given net?

        :param network_info: A network information dict.  This method expects
                             it to contain key 'address' (MAC address).
        :return: True if a CNA with the network_info's MAC address exists on
                 the instance.  False otherwise.
        """
        if self.cnas is None:
            self.cnas = vm.get_cnas(self.adapter, self.instance)
        vifs = self.cnas

        return network_info['address'] in [vm.norm_mac(v.mac) for v in vifs]
コード例 #10
0
ファイル: vif.py プロジェクト: september1020/nova
    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
コード例 #11
0
ファイル: network.py プロジェクト: arbrandes/nova
    def revert(self, lpar_wrap, result, flow_failures):
        if not self.network_infos:
            return

        LOG.warning('VIF creation being rolled back for instance.',
                    instance=self.instance)

        # Get the current adapters on the system
        cna_w_list = vm.get_cnas(self.adapter, self.instance)
        for network_info in self.crt_network_infos:
            try:
                vif.unplug(self.adapter, self.instance, network_info,
                           cna_w_list=cna_w_list)
            except Exception:
                LOG.exception("An exception occurred during an unplug in the "
                              "vif rollback.  Ignoring.",
                              instance=self.instance)
コード例 #12
0
ファイル: network.py プロジェクト: arbrandes/nova
    def execute(self):
        # If the LPAR is not in an OK state for deleting, then throw an
        # error up front.
        lpar_wrap = vm.get_instance_wrapper(self.adapter, self.instance)
        modifiable, reason = lpar_wrap.can_modify_io()
        if not modifiable:
            LOG.error("Unable to remove VIFs from instance in the system's "
                      "current state. The reason reported by the system is: "
                      "%s", reason, instance=self.instance)
            raise exception.VirtualInterfaceUnplugException(reason=reason)

        # Get all the current Client Network Adapters (CNA) on the VM itself.
        cna_w_list = vm.get_cnas(self.adapter, self.instance)

        # Walk through the VIFs and delete the corresponding CNA on the VM.
        for network_info in self.network_infos:
            vif.unplug(self.adapter, self.instance, network_info,
                       cna_w_list=cna_w_list)
コード例 #13
0
    def execute(self, vm_cnas):
        LOG.info('Plugging the Management Network Interface to instance.',
                 instance=self.instance)
        # Determine if we need to create the secure RMC VIF.  This should only
        # be needed if there is not a VIF on the secure RMC vSwitch
        vswitch = None
        vswitches = pvm_net.VSwitch.search(
            self.adapter,
            parent_type=pvm_ms.System.schema_type,
            parent_uuid=self.adapter.sys_uuid,
            name=SECURE_RMC_VSWITCH)
        if len(vswitches) == 1:
            vswitch = vswitches[0]

        if vswitch is None:
            LOG.warning(
                'No management VIF created for instance due to lack '
                'of Management Virtual Switch',
                instance=self.instance)
            return None

        # This next check verifies that there are no existing NICs on the
        # vSwitch, so that the VM does not end up with multiple RMC VIFs.
        if vm_cnas is None:
            has_mgmt_vif = vm.get_cnas(self.adapter,
                                       self.instance,
                                       vswitch_uri=vswitch.href)
        else:
            has_mgmt_vif = vswitch.href in [cna.vswitch_uri for cna in vm_cnas]

        if has_mgmt_vif:
            LOG.debug('Management VIF already created for instance',
                      instance=self.instance)
            return None

        lpar_uuid = vm.get_pvm_uuid(self.instance)
        return pvm_cna.crt_cna(self.adapter,
                               None,
                               lpar_uuid,
                               SECURE_RMC_VLAN,
                               vswitch=SECURE_RMC_VSWITCH,
                               crt_vswitch=True)
コード例 #14
0
    def revert(self, lpar_wrap, result, flow_failures):
        if not self.network_infos:
            return

        LOG.warning('VIF creation being rolled back for instance.',
                    instance=self.instance)

        # Get the current adapters on the system
        cna_w_list = vm.get_cnas(self.adapter, self.instance)
        for network_info in self.crt_network_infos:
            try:
                vif.unplug(self.adapter,
                           self.instance,
                           network_info,
                           cna_w_list=cna_w_list)
            except Exception:
                LOG.exception(
                    "An exception occurred during an unplug in the "
                    "vif rollback.  Ignoring.",
                    instance=self.instance)
コード例 #15
0
    def execute(self):
        # If the LPAR is not in an OK state for deleting, then throw an
        # error up front.
        lpar_wrap = vm.get_instance_wrapper(self.adapter, self.instance)
        modifiable, reason = lpar_wrap.can_modify_io()
        if not modifiable:
            LOG.error(
                "Unable to remove VIFs from instance in the system's "
                "current state. The reason reported by the system is: "
                "%s",
                reason,
                instance=self.instance)
            raise exception.VirtualInterfaceUnplugException(reason=reason)

        # Get all the current Client Network Adapters (CNA) on the VM itself.
        cna_w_list = vm.get_cnas(self.adapter, self.instance)

        # Walk through the VIFs and delete the corresponding CNA on the VM.
        for network_info in self.network_infos:
            vif.unplug(self.adapter,
                       self.instance,
                       network_info,
                       cna_w_list=cna_w_list)
コード例 #16
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()
コード例 #17
0
ファイル: vif.py プロジェクト: arbrandes/nova
    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()