Skip to content

Commit

Permalink
Bug #897091: "nova actions" fails with HTTP 400 / TypeError if a serv…
Browse files Browse the repository at this point in the history
…er action has been performed

Fix code in Controller.action that was overwriting the definition of the
actions method with a dictionary.  This meant that 'nova actions' would fail
if 'nova reboot' had previously been called.

Added two tests, one for the actions call in general, and one for this
failure mode specifically.

(cherry picked from commit 4a76167)

Change-Id: I695bb5c4dcfba96a5aba54125a8f3163e1a6a193
  • Loading branch information
Ewan Mellor authored and markmc committed Dec 8, 2011
1 parent 1e3b88b commit c733462
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 5 deletions.
8 changes: 4 additions & 4 deletions nova/api/openstack/servers.py
Expand Up @@ -207,7 +207,7 @@ def _update(self, context, req, id, inst_dict):
def action(self, req, id, body):
"""Multi-purpose method used to take actions on a server"""

self.actions = {
_actions = {
'changePassword': self._action_change_password,
'reboot': self._action_reboot,
'resize': self._action_resize,
Expand All @@ -221,11 +221,11 @@ def action(self, req, id, body):
admin_actions = {
'createBackup': self._action_create_backup,
}
self.actions.update(admin_actions)
_actions.update(admin_actions)

for key in body:
if key in self.actions:
return self.actions[key](body, req, id)
if key in _actions:
return _actions[key](body, req, id)
else:
msg = _("There is no such server action: %s") % (key,)
raise exc.HTTPBadRequest(explanation=msg)
Expand Down
35 changes: 34 additions & 1 deletion nova/tests/api/openstack/test_servers.py
Expand Up @@ -42,6 +42,7 @@
import nova.db.api
import nova.scheduler.api
from nova.db.sqlalchemy.models import Instance
from nova.db.sqlalchemy.models import InstanceActions
from nova.db.sqlalchemy.models import InstanceMetadata
import nova.image.fake
import nova.rpc
Expand Down Expand Up @@ -229,6 +230,19 @@ def fake_compute_api(cls, req, id):
return True


_fake_compute_actions = [
dict(
created_at=str(datetime.datetime(2010, 11, 11, 11, 0, 0)),
action='Fake Action',
error='Fake Error',
)
]


def fake_compute_actions(_1, _2, _3):
return [InstanceActions(**a) for a in _fake_compute_actions]


def find_host(self, context, instance_id):
return "nova"

Expand Down Expand Up @@ -272,7 +286,7 @@ def setUp(self):
self.stubs.Set(nova.compute.API, 'suspend', fake_compute_api)
self.stubs.Set(nova.compute.API, 'resume', fake_compute_api)
self.stubs.Set(nova.compute.API, "get_diagnostics", fake_compute_api)
self.stubs.Set(nova.compute.API, "get_actions", fake_compute_api)
self.stubs.Set(nova.compute.API, "get_actions", fake_compute_actions)

self.webreq = common.webob_factory('/v1.0/servers')
self.config_drive = None
Expand Down Expand Up @@ -2417,6 +2431,25 @@ def test_get_all_server_details_v1_1(self):
self.assertEqual(s['status'], 'BUILD')
self.assertEqual(s['metadata']['seq'], str(i))

def test_server_actions(self):
req = webob.Request.blank('/v1.1/fake/servers/%s/actions' % FAKE_UUID)
req.method = "GET"
res = req.get_response(fakes.wsgi_app())
res_dict = json.loads(res.body)
self.assertEqual(res_dict, {'actions': _fake_compute_actions})

def test_server_actions_after_reboot(self):
"""
Bug #897091 was this failure mode -- the /actions call failed if
/action had been called first.
"""
req = webob.Request.blank('/v1.1/fake/servers/%s/action' % FAKE_UUID)
req.method = 'POST'
req.body = json.dumps(dict(reboot=dict(type="HARD")))
req.headers["content-type"] = "application/json"
req.get_response(fakes.wsgi_app())
self.test_server_actions()

def test_get_all_server_details_with_host(self):
'''
We want to make sure that if two instances are on the same host, then
Expand Down

0 comments on commit c733462

Please sign in to comment.