Admin action to reset states.
Adds support for the new Nova Admin API action which resets the state of an instance. This will at least allow easy clean-up from bugs which corrupt the state of an instance and inhibit the owner of the instance from deleting it. Change-Id: I47d1d75e3bd2a07b3b75302b512122b27d5d79d9
This commit is contained in:
@@ -252,6 +252,12 @@ class Server(base.Resource):
|
|||||||
block_migration,
|
block_migration,
|
||||||
disk_over_commit)
|
disk_over_commit)
|
||||||
|
|
||||||
|
def reset_state(self, state='error'):
|
||||||
|
"""
|
||||||
|
Reset the state of an instance to active or error.
|
||||||
|
"""
|
||||||
|
self.manager.reset_state(self, state)
|
||||||
|
|
||||||
|
|
||||||
class ServerManager(local_base.BootingManagerWithFind):
|
class ServerManager(local_base.BootingManagerWithFind):
|
||||||
resource_class = Server
|
resource_class = Server
|
||||||
@@ -631,6 +637,16 @@ class ServerManager(local_base.BootingManagerWithFind):
|
|||||||
'block_migration': block_migration,
|
'block_migration': block_migration,
|
||||||
'disk_over_commit': disk_over_commit})
|
'disk_over_commit': disk_over_commit})
|
||||||
|
|
||||||
|
def reset_state(self, server, state='error'):
|
||||||
|
"""
|
||||||
|
Reset the state of an instance to active or error.
|
||||||
|
|
||||||
|
:param server: ID of the instance to reset the state of.
|
||||||
|
:param state: Desired state; either 'active' or 'error'.
|
||||||
|
Defaults to 'error'.
|
||||||
|
"""
|
||||||
|
self._action('os-resetState', server, dict(state=state))
|
||||||
|
|
||||||
def _action(self, action, server, info=None, **kwargs):
|
def _action(self, action, server, info=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
Perform a server "action" -- reboot/rebuild/resize/etc.
|
Perform a server "action" -- reboot/rebuild/resize/etc.
|
||||||
|
|||||||
@@ -1597,6 +1597,16 @@ def do_live_migration(cs, args):
|
|||||||
args.disk_over_commit)
|
args.disk_over_commit)
|
||||||
|
|
||||||
|
|
||||||
|
@utils.arg('server', metavar='<server>', help='Name or ID of server.')
|
||||||
|
@utils.arg('--active', action='store_const', dest='state',
|
||||||
|
default='error', const='active',
|
||||||
|
help='Request the instance be reset to "active" state instead '
|
||||||
|
'of "error" state (the default).')
|
||||||
|
def do_reset_state(cs, args):
|
||||||
|
"""Reset the state of an instance"""
|
||||||
|
_find_server(cs, args.server).reset_state(args.state)
|
||||||
|
|
||||||
|
|
||||||
@utils.arg('host', metavar='<hostname>', help='Name of host.')
|
@utils.arg('host', metavar='<hostname>', help='Name of host.')
|
||||||
def do_describe_resource(cs, args):
|
def do_describe_resource(cs, args):
|
||||||
"""Show details about a resource"""
|
"""Show details about a resource"""
|
||||||
|
|||||||
@@ -339,6 +339,8 @@ class FakeHTTPClient(base_client.HTTPClient):
|
|||||||
assert set(body[action].keys()) == set(['host',
|
assert set(body[action].keys()) == set(['host',
|
||||||
'block_migration',
|
'block_migration',
|
||||||
'disk_over_commit'])
|
'disk_over_commit'])
|
||||||
|
elif action == 'os-resetState':
|
||||||
|
assert body[action].keys() == ['state']
|
||||||
else:
|
else:
|
||||||
raise AssertionError("Unexpected server action: %s" % action)
|
raise AssertionError("Unexpected server action: %s" % action)
|
||||||
return (resp, _body)
|
return (resp, _body)
|
||||||
|
|||||||
@@ -303,3 +303,10 @@ class ServersTest(utils.TestCase):
|
|||||||
cs.servers.live_migrate(s, host='hostname', block_migration=False,
|
cs.servers.live_migrate(s, host='hostname', block_migration=False,
|
||||||
disk_over_commit=False)
|
disk_over_commit=False)
|
||||||
cs.assert_called('POST', '/servers/1234/action')
|
cs.assert_called('POST', '/servers/1234/action')
|
||||||
|
|
||||||
|
def test_reset_state(self):
|
||||||
|
s = cs.servers.get(1234)
|
||||||
|
s.reset_state('newstate')
|
||||||
|
cs.assert_called('POST', '/servers/1234/action')
|
||||||
|
cs.servers.reset_state(s, 'newstate')
|
||||||
|
cs.assert_called('POST', '/servers/1234/action')
|
||||||
|
|||||||
@@ -440,6 +440,14 @@ class ShellTest(utils.TestCase):
|
|||||||
'block_migration': True,
|
'block_migration': True,
|
||||||
'disk_over_commit': True}})
|
'disk_over_commit': True}})
|
||||||
|
|
||||||
|
def test_reset_state(self):
|
||||||
|
self.run_command('reset-state sample-server')
|
||||||
|
self.assert_called('POST', '/servers/1234/action',
|
||||||
|
{'os-resetState': {'state': 'error'}})
|
||||||
|
self.run_command('reset-state sample-server --active')
|
||||||
|
self.assert_called('POST', '/servers/1234/action',
|
||||||
|
{'os-resetState': {'state': 'active'}})
|
||||||
|
|
||||||
def test_host_update_status(self):
|
def test_host_update_status(self):
|
||||||
self.run_command('host-update sample-host_1 --status enabled')
|
self.run_command('host-update sample-host_1 --status enabled')
|
||||||
body = {'status': 'enabled'}
|
body = {'status': 'enabled'}
|
||||||
|
|||||||
Reference in New Issue
Block a user