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