def attach_volume(self, server, volume, device=None, tag=None):
    "Attaches volume to server and waits for 'in-use' volume status.\n\n        The volume will be detached when the test tears down.\n\n        :param server: The server to which the volume will be attached.\n        :param volume: The volume to attach.\n        :param device: Optional mountpoint for the attached volume. Note that\n            this is not guaranteed for all hypervisors and is not recommended.\n        :param tag: Optional device role tag to apply to the volume.\n        "
    attach_kwargs = dict(volumeId=volume['id'])
    if device:
        attach_kwargs['device'] = device
    if tag:
        attach_kwargs['tag'] = tag
    attachment = self.servers_client.attach_volume(server['id'], **attach_kwargs)['volumeAttachment']
    if volume['multiattach']:
        att = waiters.wait_for_volume_attachment_create(self.volumes_client, volume['id'], server['id'])
        self.addCleanup(waiters.wait_for_volume_attachment_remove, self.volumes_client, volume['id'], att['attachment_id'])
    else:
        self.addCleanup(waiters.wait_for_volume_resource_status, self.volumes_client, volume['id'], 'available')
        waiters.wait_for_volume_resource_status(self.volumes_client, volume['id'], 'in-use')
    self.addCleanup(self._detach_volume, server, volume)
    return attachment
Attaches volume to server and waits for 'in-use' volume status.

The volume will be detached when the test tears down.

:param server: The server to which the volume will be attached.
:param volume: The volume to attach.
:param device: Optional mountpoint for the attached volume. Note that
    this is not guaranteed for all hypervisors and is not recommended.
:param tag: Optional device role tag to apply to the volume.
def attach_volume(self, server, volume, device=None, tag=None):
    "Attaches volume to server and waits for 'in-use' volume status.\n\n        The volume will be detached when the test tears down.\n\n        :param server: The server to which the volume will be attached.\n        :param volume: The volume to attach.\n        :param device: Optional mountpoint for the attached volume. Note that\n            this is not guaranteed for all hypervisors and is not recommended.\n        :param tag: Optional device role tag to apply to the volume.\n        "
    attach_kwargs = dict(volumeId=volume['id'])
    if device:
        attach_kwargs['device'] = device
    if tag:
        attach_kwargs['tag'] = tag
    attachment = self.servers_client.attach_volume(server['id'], **attach_kwargs)['volumeAttachment']
    if volume['multiattach']:
        att = waiters.wait_for_volume_attachment_create(self.volumes_client, volume['id'], server['id'])
        self.addCleanup(waiters.wait_for_volume_attachment_remove, self.volumes_client, volume['id'], att['attachment_id'])
    else:
        self.addCleanup(waiters.wait_for_volume_resource_status, self.volumes_client, volume['id'], 'available')
        waiters.wait_for_volume_resource_status(self.volumes_client, volume['id'], 'in-use')
    self.addCleanup(self._detach_volume, server, volume)
    return attachment