Merge "Update volume-status waiter for new cinder attach"
This commit is contained in:
commit
8390829df2
@ -424,7 +424,7 @@ class BaseV2ComputeTest(api_version_utils.BaseMicroversionTest,
|
|||||||
LOG.exception('Waiting for deletion of volume %s failed',
|
LOG.exception('Waiting for deletion of volume %s failed',
|
||||||
volume['id'])
|
volume['id'])
|
||||||
|
|
||||||
def attach_volume(self, server, volume, device=None):
|
def attach_volume(self, server, volume, device=None, check_reserved=False):
|
||||||
"""Attaches volume to server and waits for 'in-use' volume status.
|
"""Attaches volume to server and waits for 'in-use' volume status.
|
||||||
|
|
||||||
The volume will be detached when the test tears down.
|
The volume will be detached when the test tears down.
|
||||||
@ -433,10 +433,15 @@ class BaseV2ComputeTest(api_version_utils.BaseMicroversionTest,
|
|||||||
:param volume: The volume to attach.
|
:param volume: The volume to attach.
|
||||||
:param device: Optional mountpoint for the attached volume. Note that
|
:param device: Optional mountpoint for the attached volume. Note that
|
||||||
this is not guaranteed for all hypervisors and is not recommended.
|
this is not guaranteed for all hypervisors and is not recommended.
|
||||||
|
:param check_reserved: Consider a status of reserved as valid for
|
||||||
|
completion. This is to handle new Cinder attach where we more
|
||||||
|
accurately use 'reserved' for things like attaching to a shelved
|
||||||
|
server.
|
||||||
"""
|
"""
|
||||||
attach_kwargs = dict(volumeId=volume['id'])
|
attach_kwargs = dict(volumeId=volume['id'])
|
||||||
if device:
|
if device:
|
||||||
attach_kwargs['device'] = device
|
attach_kwargs['device'] = device
|
||||||
|
|
||||||
attachment = self.servers_client.attach_volume(
|
attachment = self.servers_client.attach_volume(
|
||||||
server['id'], **attach_kwargs)['volumeAttachment']
|
server['id'], **attach_kwargs)['volumeAttachment']
|
||||||
# On teardown detach the volume and wait for it to be available. This
|
# On teardown detach the volume and wait for it to be available. This
|
||||||
@ -449,8 +454,11 @@ class BaseV2ComputeTest(api_version_utils.BaseMicroversionTest,
|
|||||||
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
|
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
|
||||||
self.servers_client.detach_volume,
|
self.servers_client.detach_volume,
|
||||||
server['id'], volume['id'])
|
server['id'], volume['id'])
|
||||||
|
statuses = ['in-use']
|
||||||
|
if check_reserved:
|
||||||
|
statuses.append('reserved')
|
||||||
waiters.wait_for_volume_resource_status(self.volumes_client,
|
waiters.wait_for_volume_resource_status(self.volumes_client,
|
||||||
volume['id'], 'in-use')
|
volume['id'], statuses)
|
||||||
return attachment
|
return attachment
|
||||||
|
|
||||||
|
|
||||||
|
@ -212,7 +212,8 @@ class AttachVolumeShelveTestJSON(AttachVolumeTestJSON):
|
|||||||
num_vol = self._count_volumes(server)
|
num_vol = self._count_volumes(server)
|
||||||
self._shelve_server(server)
|
self._shelve_server(server)
|
||||||
attachment = self.attach_volume(server, volume,
|
attachment = self.attach_volume(server, volume,
|
||||||
device=('/dev/%s' % self.device))
|
device=('/dev/%s' % self.device),
|
||||||
|
check_reserved=True)
|
||||||
|
|
||||||
# Unshelve the instance and check that attached volume exists
|
# Unshelve the instance and check that attached volume exists
|
||||||
self._unshelve_server_and_check_volumes(server, num_vol + 1)
|
self._unshelve_server_and_check_volumes(server, num_vol + 1)
|
||||||
@ -239,7 +240,8 @@ class AttachVolumeShelveTestJSON(AttachVolumeTestJSON):
|
|||||||
self._shelve_server(server)
|
self._shelve_server(server)
|
||||||
|
|
||||||
# Attach and then detach the volume
|
# Attach and then detach the volume
|
||||||
self.attach_volume(server, volume, device=('/dev/%s' % self.device))
|
self.attach_volume(server, volume, device=('/dev/%s' % self.device),
|
||||||
|
check_reserved=True)
|
||||||
self.servers_client.detach_volume(server['id'], volume['id'])
|
self.servers_client.detach_volume(server['id'], volume['id'])
|
||||||
waiters.wait_for_volume_resource_status(self.volumes_client,
|
waiters.wait_for_volume_resource_status(self.volumes_client,
|
||||||
volume['id'], 'available')
|
volume['id'], 'available')
|
||||||
|
@ -179,25 +179,26 @@ def wait_for_image_status(client, image_id, status):
|
|||||||
raise lib_exc.TimeoutException(message)
|
raise lib_exc.TimeoutException(message)
|
||||||
|
|
||||||
|
|
||||||
def wait_for_volume_resource_status(client, resource_id, status):
|
def wait_for_volume_resource_status(client, resource_id, statuses):
|
||||||
"""Waits for a volume resource to reach a given status.
|
"""Waits for a volume resource to reach any of the specified statuses.
|
||||||
|
|
||||||
This function is a common function for volume, snapshot and backup
|
This function is a common function for volume, snapshot and backup
|
||||||
resources. The function extracts the name of the desired resource from
|
resources. The function extracts the name of the desired resource from
|
||||||
the client class name of the resource.
|
the client class name of the resource.
|
||||||
"""
|
"""
|
||||||
resource_name = re.findall(
|
if not isinstance(statuses, list):
|
||||||
r'(Volume|Snapshot|Backup|Group)',
|
statuses = [statuses]
|
||||||
client.__class__.__name__)[0].lower()
|
resource_name = re.findall(r'(Volume|Snapshot|Backup|Group)',
|
||||||
|
client.__class__.__name__)[0].lower()
|
||||||
show_resource = getattr(client, 'show_' + resource_name)
|
show_resource = getattr(client, 'show_' + resource_name)
|
||||||
resource_status = show_resource(resource_id)[resource_name]['status']
|
resource_status = show_resource(resource_id)[resource_name]['status']
|
||||||
start = int(time.time())
|
start = int(time.time())
|
||||||
|
|
||||||
while resource_status != status:
|
while resource_status not in statuses:
|
||||||
time.sleep(client.build_interval)
|
time.sleep(client.build_interval)
|
||||||
resource_status = show_resource(resource_id)[
|
resource_status = show_resource(resource_id)[
|
||||||
'{}'.format(resource_name)]['status']
|
'{}'.format(resource_name)]['status']
|
||||||
if resource_status == 'error' and resource_status != status:
|
if resource_status == 'error' and resource_status not in statuses:
|
||||||
raise exceptions.VolumeResourceBuildErrorException(
|
raise exceptions.VolumeResourceBuildErrorException(
|
||||||
resource_name=resource_name, resource_id=resource_id)
|
resource_name=resource_name, resource_id=resource_id)
|
||||||
if resource_name == 'volume' and resource_status == 'error_restoring':
|
if resource_name == 'volume' and resource_status == 'error_restoring':
|
||||||
@ -206,7 +207,7 @@ def wait_for_volume_resource_status(client, resource_id, status):
|
|||||||
if int(time.time()) - start >= client.build_timeout:
|
if int(time.time()) - start >= client.build_timeout:
|
||||||
message = ('%s %s failed to reach %s status (current %s) '
|
message = ('%s %s failed to reach %s status (current %s) '
|
||||||
'within the required time (%s s).' %
|
'within the required time (%s s).' %
|
||||||
(resource_name, resource_id, status, resource_status,
|
(resource_name, resource_id, statuses, resource_status,
|
||||||
client.build_timeout))
|
client.build_timeout))
|
||||||
raise lib_exc.TimeoutException(message)
|
raise lib_exc.TimeoutException(message)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user