def attach_volume(self, blockdevice_id, attach_to):
        LOG.debug('Entering EMCVNXBlockAPI.attach_volume: '
                  'blockdevice_id=%s, attach_to=%s',
                  blockdevice_id, attach_to)

        volume_name = self._build_volume_name_from_blockdevice_id(
            blockdevice_id)
        lun = self.client.get_lun(name=volume_name)
        if self.client.is_lun_destroyed(lun):
            raise blockdevice.UnknownVolume(blockdevice_id)

        if self._lun_already_in_sg(lun):
            raise blockdevice.AlreadyAttachedVolume(blockdevice_id)

        host_info = self._build_host_info(self.host_ip, attach_to)
        storage_group = self._assure_storage_group(host_info)

        try:
            hlu = self._assure_host_access(storage_group, lun)
        except exception.VNXAluAlreadyAttachedError:
            raise blockdevice.AlreadyAttachedVolume(blockdevice_id)

        connection_properties = self.connector.build_connection_properties(
            hlu, storage_group=storage_group)

        self.connector.connect_volume(connection_properties['data'])

        volume_size = self._gib_to_bytes(lun.total_capacity_gb)
        volume = loopback._blockdevicevolume_from_blockdevice_id(
            blockdevice_id=blockdevice_id,
            size=volume_size,
            attached_to=unicode(attach_to))

        LOG.debug('Exiting EMCVNXBlockAPI.attach_volume: '
                  'storage_group=%s, volume_name=%s, volume_size=%s, hlu=%s, '
                  'target_prop=%s',
                  attach_to,
                  volume_name,
                  volume_size,
                  hlu,
                  connection_properties)

        return volume
Beispiel #2
0
    def attach_volume(self, blockdevice_id, attach_to):
        LOG.debug('Entering EMCUnityBlockAPI.attach_volume: '
                  'blockdevice_id=%s, attach_to=%s',
                  blockdevice_id, attach_to)

        volume_name = self._build_volume_name_from_blockdevice_id(
            blockdevice_id)
        lun = self.client.get_lun(name=volume_name)
        if self.client.is_lun_destroyed(lun):
            raise blockdevice.UnknownVolume(blockdevice_id)

        if self._lun_already_in_host(lun):
            raise blockdevice.AlreadyAttachedVolume(blockdevice_id)

        host_info = self._build_host_info(attach_to)
        host = self._assure_host(host_info)

        try:
            hlu = self._assure_host_access(host, lun)
        except exception.UnityAluAlreadyAttachedError:
            raise blockdevice.AlreadyAttachedVolume(blockdevice_id)

        connection_properties = self.connector.build_connection_properties(
            hlu, host=host)

        self.connector.connect_volume(connection_properties['data'])

        volume = loopback._blockdevicevolume_from_blockdevice_id(
            blockdevice_id=blockdevice_id,
            size=lun.size_total,
            attached_to=unicode(attach_to))

        LOG.debug('Exiting EMCUnityBlockAPI.attach_volume: '
                  'host=%s, volume_name=%s, volume_size=%s, hlu=%s, '
                  'target_prop=%s',
                  attach_to,
                  volume_name,
                  lun.size_total,
                  hlu,
                  connection_properties)

        return volume
    def _connect_volume(self, vol_name):
        """Connect the volume object to our Purity host.

        We need to return a dictionary with target information that will be
        consumed by os-brick.
        """
        try:
            connection = self._array.connect_host(self._purity_hostname,
                                                  vol_name)
        except purestorage.PureHTTPError as err:
            if err.code == 400 and ERR_MSG_ALREADY_EXISTS in err.text:
                raise blockdevice.AlreadyAttachedVolume(vol_name)
            elif err.code == 400 and ERR_MSG_NOT_EXIST in err.text:
                raise blockdevice.UnknownVolume(vol_name)
            else:
                raise
        return self._format_connection_info(connection)
Beispiel #4
0
    def attach_volume(self, blockdevice_id, attach_to):
        """Attach an existing volume to an initiator (host).

        :param blockdevice_id: The unique identifier(scsi_sn of k2)
            for the volume.
        :param attach_to: It is a hostname of node which is returned
            by "compute_instance_id" method.
        :raises UnknownVolume: If the supplied "blockdevice_id" does not
            exist.
        :returns: A  "BlockDeviceVolume" with a "attached_to" attribute set
            to "attach_to".
        """
        LOG.info('attaching to blockdevice_id %s and host is %s',
                 blockdevice_id, attach_to)
        # Searching for volume by scsi_sn via krest
        volume = self.krest.search("volumes", scsi_sn=blockdevice_id)
        if volume.total == 0:
            raise blockdevice.UnknownVolume(blockdevice_id)

        # Check for host which is associate with iqn(iSCSI Qualified Name)
        iqn = self.api_client.get_initiator_name()
        host_iqns = self.krest.search("host_iqns", iqn=iqn)
        host = self.api_client.rgetattr(host_iqns.hits[0], "host", None) \
            if host_iqns.total > 0 else None

        # if iqn is not associate with any host
        if not host:
            # searching instance or node host which is return
            # by compute_instance_id method.
            host = self.krest.search("hosts", name=attach_to)
            if host.total > 0:
                raise InvalidDataException(
                    'Present host is not mapped with iqn')
            else:
                host = self._create_new_host(attach_to)
                self._map_host_with_iqn(host_iqns.hits[0], host)

        # Make sure the server is logged in to the array
        ips = self.krest.search("system/net_ips")
        for ip in ips.hits:
            self.api_client.iscsi_login(
                self.api_client.rgetattr(ip, 'ip_address', None), 3260)

        # Make sure we were able to find host
        if not host:
            raise InvalidDataException('Host does not exits')

        volume = volume.hits[0]
        # First check if we are already mapped
        mapped = self.krest.search('mappings', volume=volume)

        if mapped.total > 0:
            # Get the mapped host
            mapped_host = self.api_client.rgetattr(mapped.hits[0], "host",
                                                   None)
            if mapped_host != host:
                LOG.info("Mapped server %s", mapped_host)
                # raise exception for attached volume
                raise blockdevice.AlreadyAttachedVolume(blockdevice_id)

        # Make sure host should not be associate with host group
        # Note: Currently host groups not supported.
        try:
            mapping = self.krest.new("mappings", volume=volume, host=host)
            mapping.save()
            LOG.info("Mapping is done- %s", mapping)
        except Exception:
            raise StorageDriverAPIException('Unable to map volume to server.')

        # start iscsi rescan
        self._iscsi_rescan('attach')

        return self._return_to_block_device_volume(volume, attach_to)
    def attach_volume(self, blockdevice_id, attach_to):
        """Attach an existing volume to an initiator.

        :param blockdevice_id: The unique identifier for the volume.
        :param attach_to: An identifier like the one returned by the
            ``compute_instance_id`` method indicating the node to which to
            attach the volume.

        :raises UnknownVolume: If the supplied ``blockdevice_id`` does not
            exist.
        :returns: A ``BlockDeviceVolume`` with a ``attached_to`` attribute set
            to ``attach_to``.
        """
        LOG.info('Attaching %s to %s', blockdevice_id, attach_to)

        # Functional tests expect a failure if it's already
        # attached, even if we're being asked to attach to
        # the same host.
        # not_local = attach_to != self.compute_instance_id()
        not_local = True

        with self._client.open_connection() as api:
            # Check that we have that volume
            scvolume = api.find_volume(blockdevice_id)
            if not scvolume:
                raise blockdevice.UnknownVolume(blockdevice_id)

            # Make sure we have a server defined for this host
            iqn = iscsi_utils.get_initiator_name()
            host = api.find_server(iqn)
            LOG.info("Search for server returned: %s", host)
            if not host:
                # Try to create a new host
                host = api.create_server(attach_to, iqn)
                LOG.info("Created server %s", host)
            # Make sure the server is logged in to the array
            ports = api.get_iscsi_ports()
            for port in ports:
                iscsi_utils.iscsi_login(port[0], port[1])

            # Make sure we were able to find something
            if not host:
                raise BlockDriverAPIException()

            # First check if we are already mapped
            mappings = api.find_mapping_profiles(scvolume)
            if mappings:
                # See if it is to this server
                if not_local:
                    raise blockdevice.AlreadyAttachedVolume(blockdevice_id)
                for mapping in mappings:
                    if (mapping['server']['instanceName'] !=
                            host['instanceName']):
                        raise blockdevice.AlreadyAttachedVolume(blockdevice_id)

            mapping = api.map_volume(scvolume, host)
            if not mapping:
                raise BlockDriverAPIException(
                    'Unable to map volume to server.')

            self._do_rescan('attach')

            return self._to_blockdevicevolume(scvolume, attach_to)