def attach_volume(self, blockdevice_id, attach_to): """ Attach ``blockdevice_id`` to ``host``. :param unicode blockdevice_id: The unique identifier for the block device being attached. :param unicode 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. :raises AlreadyAttachedVolume: If the supplied ``blockdevice_id`` is already attached. :returns: A ``BlockDeviceVolume`` with a ``host`` attribute set to ``host``. """ vol = self._get_solidfire_volume(blockdevice_id) if not vol: raise UnknownVolume(blockdevice_id) tgt_iqn = vol['iqn'] if utils.path_exists('/dev/disk/by-path/ip-%s-iscsi-%s-lun-0' % (self.svip, tgt_iqn), 1): raise AlreadyAttachedVolume(blockdevice_id) # It's not attached here, make sure it's not attached somewhere else # In the future we can add multi-attach support maybe, but for now # avoid the trouble of file-systems etc current_sessions = self._current_iscsi_sessions(blockdevice_id) if current_sessions: raise AlreadyAttachedVolume(blockdevice_id) targets = utils.iscsi_discovery(self.svip) if len(targets) < 1 and tgt_iqn not in targets: raise Exception("No targes found during discovery.") if utils.iscsi_login(self.svip, tgt_iqn): return BlockDeviceVolume( blockdevice_id=unicode(blockdevice_id), size=vol['totalSize'], attached_to=attach_to, dataset_id=uuid.UUID(str(vol['name']))) raise Exception("Failed iSCSI login to device: %s" % blockdevice_id)
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`` """ vol = self._get_solidfire_volume(blockdevice_id) if not vol: raise UnknownVolume(blockdevice_id) tgt_iqn = vol['iqn'] if not utils.path_exists('/dev/disk/by-path/ip-%s-iscsi-%s-lun-0' % (self.svip, tgt_iqn), 1): raise UnattachedVolume(blockdevice_id) utils.iscsi_logout(self.svip, tgt_iqn)
def list_volumes(self): """ List all the block devices available via the back end API. :returns: A ``list`` of ``BlockDeviceVolume``s. """ volumes = [] sfvols = self.client.issue_request('ListVolumesForAccount', {'accountID': self.account_id}, version='7.0')['volumes'] for v in sfvols: attached_to = None tgt_iqn = v['iqn'] if utils.path_exists('/dev/disk/by-path/ip-%s-iscsi-%s-lun-0' % (self.svip, tgt_iqn), 1): attached_to = self.compute_instance_id() name = v['name'] if 'flock-' in v['name']: name = name.replace('flock-', '') volumes.append(BlockDeviceVolume( blockdevice_id=unicode(v['volumeID']), size=v['totalSize'], attached_to=attached_to, dataset_id=uuid.UUID(str(name)))) return volumes