def attach_volume(self, blockdevice_id, attach_to):
        """
        Attach ``blockdevice_id`` to the node indicated by ``attach_to``.
        :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 ``attached_to`` attribute set
            to ``attach_to``.
        """

        eliot.Message.new(Info="Attaching volume %s to %s" %
                          (blockdevice_id, attach_to)).write(_logger)
        # Connect the volume internally in Purity so it is exposed for the
        # initiator.
        target_info = self._connect_volume(blockdevice_id)

        # Do initiator connection steps to attach and discover the device.
        self._connector.connect_volume(target_info)

        volume = self._array.get_volume(blockdevice_id)
        eliot.Message.new(Info="Finished attaching volume" +
                          str(blockdevice_id)).write(_logger)

        return blockdevice.BlockDeviceVolume(
            blockdevice_id=volume['name'],
            size=volume['size'],
            attached_to=attach_to,
            dataset_id=self._dataset_id_from_vol_name(volume['name']))
 def _to_blockdevicevolume(self, scvolume, attached_to=None):
     """Converts our API volume to a ``BlockDeviceVolume``."""
     dataset_id = uuid.UUID('{00000000-0000-0000-0000-000000000000}')
     try:
         dataset_id = uuid.UUID("{%s}" % scvolume.get('name'))
     except ValueError:
         pass
     retval = blockdevice.BlockDeviceVolume(
         blockdevice_id=scvolume.get('name'),
         size=int(
             float(scvolume.get('configuredSize').replace(' Bytes', ''))),
         attached_to=attached_to,
         dataset_id=dataset_id)
     return retval
    def list_volumes(self):
        """
        Return ``BlockDeviceVolume`` instances for all managed volumes.
        """
        volumes = []
        pure_vols = self._array.list_volumes()
        for vol in pure_vols:
            name = vol['name']
            if name.startswith(self._vol_prefix):
                eliot.Message.new(
                    Info="Found Purity volume managed by flocker " +
                    str(vol)).write(_logger)
                attached_to = None
                try:
                    host_connections = self._array.list_volume_private_connections(
                        name)
                except purestorage.PureHTTPError as err:
                    if err.code == 400 and ERR_MSG_NOT_EXIST in err.text:
                        break  # Carry on... nothing to see here...
                    else:
                        raise
                for connection in host_connections:
                    # Look for one thats our host, if not we'll take anything
                    # else that is connected. It *should* only ever be one
                    # host, but just in case we loop through them all...
                    if connection['host'] == self._purity_hostname:
                        # Make sure there is a path on the system, meaning
                        # it is fully attached.
                        try:
                            self.get_device_path(name)
                        except blockdevice.UnattachedVolume:
                            pass
                        else:
                            attached_to = self._purity_hostname
                            break
                    else:
                        attached_to = connection['host']
                eliot.Message.new(Info="Volume %s attached_to = %s" %
                                  (vol['name'], attached_to)).write(_logger)

                volumes.append(
                    blockdevice.BlockDeviceVolume(
                        blockdevice_id=name,
                        size=vol['size'],
                        attached_to=attached_to,
                        dataset_id=self._dataset_id_from_vol_name(name),
                    ))
        return volumes
    def create_volume(self, dataset_id, size):
        """
        Create a volume of specified size on the Pure Storage FlashArray.
        The size shall be rounded off to 1MB, as Pure Storage creates
        volumes of these sizes.

        See ``IBlockDeviceAPI.create_volume`` for parameter and return type
        documentation.
        """

        vol_name = self._vol_name_from_dataset_id(dataset_id)
        volume = blockdevice.BlockDeviceVolume(
            blockdevice_id=unicode(vol_name),
            size=size,
            attached_to=None,
            dataset_id=dataset_id,
        )
        eliot.Message.new(Info="Creating Volume: " + vol_name).write(_logger)
        self._array.create_volume(vol_name, size)
        return volume
Example #5
0
    def _return_to_block_device_volume(self, volume, attached_to=None):
        """Converts K2 API volume to a `BlockDeviceVolume`.

        With the help of blockdevice_id OS can uniquely identify volume/device
        being referenced by Flocker.
        K2 API returns SCSI Serial number(Page 0x80)(scsi_sn) as
        unique identification of volume.
        """
        dataset_id = uuid.UUID('{00000000-0000-0000-0000-000000000000}')
        try:
            # volume name has a prefix and dataset_id
            # Assumption: dataset id is of 36 chars.
            dataset_id = uuid.UUID("{0}".format(
                volume.name)[-LEN_OF_DATASET_ID:])
        except ValueError:
            pass
        ret_val = blockdevice.BlockDeviceVolume(
            blockdevice_id=volume.scsi_sn,
            size=int(self.api_client.kib_to_bytes(volume.size)),
            attached_to=attached_to,
            dataset_id=dataset_id)
        return ret_val