Merge "Implement reset-state for attach_status and migration_status"
This commit is contained in:
@@ -496,6 +496,25 @@ class ShellTest(utils.TestCase):
|
|||||||
expected = {'os-reset_status': {'status': 'error'}}
|
expected = {'os-reset_status': {'status': 'error'}}
|
||||||
self.assert_called('POST', '/volumes/1234/action', body=expected)
|
self.assert_called('POST', '/volumes/1234/action', body=expected)
|
||||||
|
|
||||||
|
def test_reset_state_with_attach_status(self):
|
||||||
|
self.run_command('reset-state --attach-status detached 1234')
|
||||||
|
expected = {'os-reset_status': {'status': 'available',
|
||||||
|
'attach_status': 'detached'}}
|
||||||
|
self.assert_called('POST', '/volumes/1234/action', body=expected)
|
||||||
|
|
||||||
|
def test_reset_state_with_attach_status_with_flag(self):
|
||||||
|
self.run_command('reset-state --state in-use '
|
||||||
|
'--attach-status attached 1234')
|
||||||
|
expected = {'os-reset_status': {'status': 'in-use',
|
||||||
|
'attach_status': 'attached'}}
|
||||||
|
self.assert_called('POST', '/volumes/1234/action', body=expected)
|
||||||
|
|
||||||
|
def test_reset_state_with_reset_migration_status(self):
|
||||||
|
self.run_command('reset-state --reset-migration-status 1234')
|
||||||
|
expected = {'os-reset_status': {'status': 'available',
|
||||||
|
'migration_status': 'none'}}
|
||||||
|
self.assert_called('POST', '/volumes/1234/action', body=expected)
|
||||||
|
|
||||||
def test_reset_state_multiple(self):
|
def test_reset_state_multiple(self):
|
||||||
self.run_command('reset-state 1234 5678 --state error')
|
self.run_command('reset-state 1234 5678 --state error')
|
||||||
expected = {'os-reset_status': {'status': 'error'}}
|
expected = {'os-reset_status': {'status': 'error'}}
|
||||||
|
@@ -160,6 +160,12 @@ class VolumesTest(utils.TestCase):
|
|||||||
cs.volumes.extend(v, 2)
|
cs.volumes.extend(v, 2)
|
||||||
cs.assert_called('POST', '/volumes/1234/action')
|
cs.assert_called('POST', '/volumes/1234/action')
|
||||||
|
|
||||||
|
def test_reset_state(self):
|
||||||
|
v = cs.volumes.get('1234')
|
||||||
|
cs.volumes.reset_state(v, 'in-use', attach_status='detached',
|
||||||
|
migration_status='none')
|
||||||
|
cs.assert_called('POST', '/volumes/1234/action')
|
||||||
|
|
||||||
def test_get_encryption_metadata(self):
|
def test_get_encryption_metadata(self):
|
||||||
cs.volumes.get_encryption_metadata('1234')
|
cs.volumes.get_encryption_metadata('1234')
|
||||||
cs.assert_called('GET', '/volumes/1234/encryption')
|
cs.assert_called('GET', '/volumes/1234/encryption')
|
||||||
|
@@ -464,6 +464,16 @@ def do_force_delete(cs, args):
|
|||||||
'NOTE: This command simply changes the state of the '
|
'NOTE: This command simply changes the state of the '
|
||||||
'Volume in the DataBase with no regard to actual status, '
|
'Volume in the DataBase with no regard to actual status, '
|
||||||
'exercise caution when using. Default=available.'))
|
'exercise caution when using. Default=available.'))
|
||||||
|
@utils.arg('--attach-status', metavar='<attach-status>', default=None,
|
||||||
|
help=('The attach status to assign to the volume in the DataBase, '
|
||||||
|
'with no regard to the actual status. Valid values are '
|
||||||
|
'"attached" and "detached". Default=None, that means the '
|
||||||
|
'status is unchanged.'))
|
||||||
|
@utils.arg('--reset-migration-status',
|
||||||
|
action='store_true',
|
||||||
|
help=('Clears the migration status of the volume in the DataBase '
|
||||||
|
'that indicates the volume is source or destination of '
|
||||||
|
'volume migration, with no regard to the actual status.'))
|
||||||
@utils.service_type('volumev2')
|
@utils.service_type('volumev2')
|
||||||
def do_reset_state(cs, args):
|
def do_reset_state(cs, args):
|
||||||
"""Explicitly updates the volume state in the Cinder database.
|
"""Explicitly updates the volume state in the Cinder database.
|
||||||
@@ -475,10 +485,13 @@ def do_reset_state(cs, args):
|
|||||||
unusable in the case of change to the 'available' state.
|
unusable in the case of change to the 'available' state.
|
||||||
"""
|
"""
|
||||||
failure_flag = False
|
failure_flag = False
|
||||||
|
migration_status = 'none' if args.reset_migration_status else None
|
||||||
|
|
||||||
for volume in args.volume:
|
for volume in args.volume:
|
||||||
try:
|
try:
|
||||||
utils.find_volume(cs, volume).reset_state(args.state)
|
utils.find_volume(cs, volume).reset_state(args.state,
|
||||||
|
args.attach_status,
|
||||||
|
migration_status)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
failure_flag = True
|
failure_flag = True
|
||||||
msg = "Reset state for volume %s failed: %s" % (volume, e)
|
msg = "Reset state for volume %s failed: %s" % (volume, e)
|
||||||
|
@@ -127,9 +127,16 @@ class Volume(base.Resource):
|
|||||||
"""
|
"""
|
||||||
self.manager.force_delete(self)
|
self.manager.force_delete(self)
|
||||||
|
|
||||||
def reset_state(self, state):
|
def reset_state(self, state, attach_status=None, migration_status=None):
|
||||||
"""Update the volume with the provided state."""
|
"""Update the volume with the provided state.
|
||||||
self.manager.reset_state(self, state)
|
|
||||||
|
:param state: The state of the volume to set.
|
||||||
|
:param attach_status: The attach_status of the volume to be set,
|
||||||
|
or None to keep the current status.
|
||||||
|
:param migration_status: The migration_status of the volume to be set,
|
||||||
|
or None to keep the current status.
|
||||||
|
"""
|
||||||
|
self.manager.reset_state(self, state, attach_status, migration_status)
|
||||||
|
|
||||||
def extend(self, volume, new_size):
|
def extend(self, volume, new_size):
|
||||||
"""Extend the size of the specified volume.
|
"""Extend the size of the specified volume.
|
||||||
@@ -531,9 +538,23 @@ class VolumeManager(base.ManagerWithFind):
|
|||||||
"""
|
"""
|
||||||
return self._action('os-force_delete', base.getid(volume))
|
return self._action('os-force_delete', base.getid(volume))
|
||||||
|
|
||||||
def reset_state(self, volume, state):
|
def reset_state(self, volume, state, attach_status=None,
|
||||||
"""Update the provided volume with the provided state."""
|
migration_status=None):
|
||||||
return self._action('os-reset_status', volume, {'status': state})
|
"""Update the provided volume with the provided state.
|
||||||
|
|
||||||
|
:param volume: The :class:`Volume` to set the state.
|
||||||
|
:param state: The state of the volume to be set.
|
||||||
|
:param attach_status: The attach_status of the volume to be set,
|
||||||
|
or None to keep the current status.
|
||||||
|
:param migration_status: The migration_status of the volume to be set,
|
||||||
|
or None to keep the current status.
|
||||||
|
"""
|
||||||
|
body = {'status': state}
|
||||||
|
if attach_status:
|
||||||
|
body.update({'attach_status': attach_status})
|
||||||
|
if migration_status:
|
||||||
|
body.update({'migration_status': migration_status})
|
||||||
|
return self._action('os-reset_status', volume, body)
|
||||||
|
|
||||||
def extend(self, volume, new_size):
|
def extend(self, volume, new_size):
|
||||||
"""Extend the size of the specified volume.
|
"""Extend the size of the specified volume.
|
||||||
|
Reference in New Issue
Block a user