def detach_volume(self, blockdevice_id):
        """
        Detach ``blockdevice_id`` from whatever host it is attached to.

        :param blockdevice_id: The unique identifier for the block
            device being detached.
        :return: `None``
        """
        logger.info('detaching Volume with blockdevice id {} .'.format(blockdevice_id))
        try:
            volumeinfo = self.find_volume_by_blockdevice_id(blockdevice_id)
            volume_name = volumeinfo[u'name']
            logger.debug('Found the volume, volume name is {} .'.format(volume_name))
        except Exception as e:
            logger.error('An error occurred finding the  volume {} .'.format(blockdevice_id))
            logger.error('Exception: ' + str(e))
            raise UnknownVolume(e)

        try:
            assignmentlist = self.get_assignments_of_volume(blockdevice_id, volume_name)
            paths = find_paths(blockdevice_id)
            for path in paths:
                remove_device(path)

            logger.info("Revoking all hosts assigned to volume {} .".format(volume_name))
            for assignment in assignmentlist:
                logger.debug("Revoking {} .".format(volume_name))
                self._rdxapi.unassign(vol_name=volume_name, host_name=assignment[u'host'])

            rescan_iscsi_session()
            logger.debug("Volume {} successfully detached.".format(blockdevice_id))
        except Exception as ex:
            logger.error('An error occurred while detaching volume {} .'.format(blockdevice_id))
            logger.error('Exception: ' + str(ex))
            raise Exception(ex)
    def detach_volume(self, blockdevice_id):
        """Detach ``blockdevice_id`` from whatever host it is attached to.

        :param unicode blockdevice_id: The unique identifier for the block
            device being detached.
        :raises UnknownVolume: If the supplied ``blockdevice_id`` does not
            exist.
        :raises UnattachedVolume: If the supplied ``blockdevice_id`` is
            not attached to anything.
        :returns: ``None``
        """
        LOG.info("Detaching %s", blockdevice_id)

        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)

            # First check if we are mapped
            mappings = api.find_mapping_profiles(scvolume)
            if not mappings:
                raise blockdevice.UnattachedVolume(blockdevice_id)

            device_id = scvolume["deviceId"]
            paths = iscsi_utils.find_paths(device_id)
            paths.reverse()
            for path in paths:
                iscsi_utils.remove_device(path)

            # 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(self.compute_instance_id(), iqn)
            LOG.info("Created server %s", host)

            # Make sure we were able to find something
            if not host:
                raise BlockDriverAPIException("Unable to locate server.")

            api.unmap_volume(scvolume, host)
        self._do_rescan("detach")
    def detach_volume(self, blockdevice_id):
        """Detach ``blockdevice_id`` from whatever host it is attached to.

        :param unicode blockdevice_id: The unique identifier for the block
            device being detached.
        :raises UnknownVolume: If the supplied ``blockdevice_id`` does not
            exist.
        :raises UnattachedVolume: If the supplied ``blockdevice_id`` is
            not attached to anything.
        :returns: ``None``
        """
        LOG.info('Detaching %s', blockdevice_id)

        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)

            # First check if we are mapped
            mappings = api.find_mapping_profiles(scvolume)
            if not mappings:
                raise blockdevice.UnattachedVolume(blockdevice_id)

            device_id = scvolume['deviceId']
            paths = iscsi_utils.find_paths(device_id)
            paths.reverse()
            for path in paths:
                iscsi_utils.remove_device(path)

            # 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(self.compute_instance_id(), iqn)
            LOG.info("Created server %s", host)

            # Make sure we were able to find something
            if not host:
                raise BlockDriverAPIException('Unable to locate server.')

            api.unmap_volume(scvolume, host)
        self._do_rescan('detach')
 def get_device_path(self, blockdevice_id):
     """
     Get the deivce path based for the blockdevice_id which is WWID fo the volume
     :param blockdevice_id: WWID of the Reduxio Volume
     :return: block device path like /dev/sdb ..
     """
     logger.debug('Getting device path of Volume with blockdevice id {} .'.format(blockdevice_id))
     retries = 0
     while retries < MAX_RESCAN_ATTEMPTS:
         paths = find_paths(blockdevice_id)
         if paths:
             # Just return the first path
             logger.debug("it has path: {}".format(filepath.FilePath(paths[0])))
             return filepath.FilePath(paths[0])
         retries += 1
         logger.debug('{} not found, attempt {}'.format(blockdevice_id, retries))
         time.sleep(SLEEP_BWN_RESCAN_IN_S)
     return None
    def get_device_path(self, blockdevice_id):
        """Return the device path.

        Returns the local device path that has been allocated to the block
        device on the host to which it is currently attached.
        :param unicode blockdevice_id: The unique identifier for the block
            device.
        :raises UnknownVolume: If the supplied ``blockdevice_id`` does not
            exist.
        :raises UnattachedVolume: If the supplied ``blockdevice_id`` is
            not attached to a host.
        :returns: A ``FilePath`` for the device.
        """
        device_id = None
        with self._client.open_connection() as api:
            # Check that we have that volume
            volume = api.find_volume(blockdevice_id)
            if not volume:
                raise blockdevice.UnknownVolume(blockdevice_id)

            scvolume = api.find_volume(blockdevice_id)
            device_id = scvolume["deviceId"]

            # First check if we are mapped
            # NOTE: The assumption right now is if we are mapped,
            # we are mapped to the local compute host.
            mappings = api.find_mapping_profiles(scvolume)
            if not mappings:
                raise blockdevice.UnattachedVolume(blockdevice_id)

        if not device_id:
            raise blockdevice.UnknownVolume(blockdevice_id)

        # Look for any new devices
        retries = 0
        while retries < 4:
            paths = iscsi_utils.find_paths(device_id)
            if paths:
                # Just return the first path
                return filepath.FilePath(paths[0]).realpath()
            retries += 1
            LOG.info("%s not found, attempt %d", device_id, retries)
            time.sleep(5)
        return None
    def get_device_path(self, blockdevice_id):
        """Return the device path.

        Returns the local device path that has been allocated to the block
        device on the host to which it is currently attached.
        :param unicode blockdevice_id: The unique identifier for the block
            device.
        :raises UnknownVolume: If the supplied ``blockdevice_id`` does not
            exist.
        :raises UnattachedVolume: If the supplied ``blockdevice_id`` is
            not attached to a host.
        :returns: A ``FilePath`` for the device.
        """
        device_id = None
        with self._client.open_connection() as api:
            # Check that we have that volume
            volume = api.find_volume(blockdevice_id)
            if not volume:
                raise blockdevice.UnknownVolume(blockdevice_id)

            scvolume = api.find_volume(blockdevice_id)
            device_id = scvolume['deviceId']

            # First check if we are mapped
            # NOTE: The assumption right now is if we are mapped,
            # we are mapped to the local compute host.
            mappings = api.find_mapping_profiles(scvolume)
            if not mappings:
                raise blockdevice.UnattachedVolume(blockdevice_id)

        if not device_id:
            raise blockdevice.UnknownVolume(blockdevice_id)

        # Look for any new devices
        retries = 0
        while retries < 4:
            paths = iscsi_utils.find_paths(device_id)
            if paths:
                # Just return the first path
                return filepath.FilePath(paths[0]).realpath()
            retries += 1
            LOG.info('%s not found, attempt %d', device_id, retries)
            time.sleep(5)
        return None