From 2594e480b2d90490a92865afbeecda35b29320d6 Mon Sep 17 00:00:00 2001 From: Tomoe Sugihara Date: Tue, 24 Jan 2012 18:14:47 +0900 Subject: Add os-start/os-stop server actions to OSAPI Implements blueprint start-stop-methods-support-in-os-servers-xapi Change-Id: I7aa241ffdd2ec3a7c9800411268f4adc47960be8 --- Authors | 1 + .../openstack/compute/contrib/server_start_stop.py | 76 ++++++++++++++++++++++ .../compute/contrib/test_server_start_stop.py | 74 +++++++++++++++++++++ .../tests/api/openstack/compute/test_extensions.py | 1 + 4 files changed, 152 insertions(+) create mode 100644 nova/api/openstack/compute/contrib/server_start_stop.py create mode 100644 nova/tests/api/openstack/compute/contrib/test_server_start_stop.py diff --git a/Authors b/Authors index a0dec6f8b..cc66d6e36 100644 --- a/Authors +++ b/Authors @@ -143,6 +143,7 @@ Stephanie Reese Thierry Carrez Tim Simpson Todd Willey +Tomoe Sugihara Tomoya Masuko Trey Morris Troy Toman diff --git a/nova/api/openstack/compute/contrib/server_start_stop.py b/nova/api/openstack/compute/contrib/server_start_stop.py new file mode 100644 index 000000000..e5317f051 --- /dev/null +++ b/nova/api/openstack/compute/contrib/server_start_stop.py @@ -0,0 +1,76 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2012 Midokura Japan K.K. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License + +import webob + +from nova.api.openstack import extensions +from nova.api.openstack import wsgi +from nova import compute +from nova import exception +from nova import log as logging + + +LOG = logging.getLogger('nova.api.openstack.compute.contrib.server_start_stop') + + +class ServerStartStopActionController(wsgi.Controller): + def __init__(self, *args, **kwargs): + super(ServerStartStopActionController, self).__init__(*args, **kwargs) + self.compute_api = compute.API() + + @wsgi.action('os-start') + def _start_server(self, req, id, body): + """Start an instance. """ + context = req.environ['nova.context'] + + try: + LOG.debug(_("start instance %r"), id) + instance = self.compute_api.get(context, id) + self.compute_api.start(context, instance) + except exception.ApiError, e: + raise webob.exc.HTTPBadRequest(explanation=e.message) + except exception.NotAuthorized, e: + raise webob.exc.HTTPUnauthorized() + return webob.Response(status_int=202) + + @wsgi.action('os-stop') + def _stop_server(self, req, id, body): + """Stop an instance.""" + context = req.environ['nova.context'] + + try: + LOG.debug(_("stop instance %r"), id) + instance = self.compute_api.get(context, id) + self.compute_api.stop(context, instance) + except exception.ApiError, e: + raise webob.exc.HTTPBadRequest(explanation=e.message) + except exception.NotAuthorized, e: + raise webob.exc.HTTPUnauthorized() + + return webob.Response(status_int=202) + + +class Server_start_stop(extensions.ExtensionDescriptor): + """Start/Stop instance compute API support""" + + name = "ServerStartStop" + namespace = "http://docs.openstack.org/compute/ext/servers/api/v1.1" + updated = "2012-01-23:00:00+00:00" + + def get_controller_extensions(self): + controller = ServerStartStopActionController() + extension = extensions.ControllerExtension(self, 'servers', controller) + return [extension] diff --git a/nova/tests/api/openstack/compute/contrib/test_server_start_stop.py b/nova/tests/api/openstack/compute/contrib/test_server_start_stop.py new file mode 100644 index 000000000..31b2b7308 --- /dev/null +++ b/nova/tests/api/openstack/compute/contrib/test_server_start_stop.py @@ -0,0 +1,74 @@ +# Copyright (c) 2012 Midokura Japan K.K. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import unittest +import mox + +from nova.api.openstack.compute.contrib import server_start_stop +from nova import context +from nova import exception +from nova import compute +from nova import test +from nova.tests.api.openstack import fakes + + +def fake_compute_api_get(self, context, instance_id): + return {'id': 1, 'uuid': instance_id} + + +class ServerStartStopTest(test.TestCase): + + def setUp(self): + super(ServerStartStopTest, self).setUp() + self.context = context.get_admin_context() + self.controller = server_start_stop.ServerStartStopActionController() + + def tearDown(self): + super(ServerStartStopTest, self).tearDown() + + def test_start(self): + self.stubs.Set(compute.API, 'get', fake_compute_api_get) + self.mox.StubOutWithMock(compute.API, 'start') + compute.API.start(mox.IgnoreArg(), mox.IgnoreArg()) + self.mox.ReplayAll() + + req = fakes.HTTPRequest.blank('/v2/fake/servers/test_inst/action') + body = dict(start="") + self.controller._start_server(req, 'test_inst', body) + + def test_stop(self): + self.stubs.Set(compute.API, 'get', fake_compute_api_get) + self.mox.StubOutWithMock(compute.API, 'stop') + compute.API.stop(mox.IgnoreArg(), mox.IgnoreArg()) + self.mox.ReplayAll() + + req = fakes.HTTPRequest.blank('/v2/fake/servers/test_inst/action') + body = dict(stop="") + self.controller._stop_server(req, 'test_inst', body) + + def test_start_with_bogus_id(self): + req = fakes.HTTPRequest.blank('/v2/fake/servers/test_inst/action') + body = dict(start="") + self.assertRaises(exception.InstanceNotFound, + self.controller._start_server, req, 'test_inst', body) + + def test_stop_with_bogus_id(self): + req = fakes.HTTPRequest.blank('/v2/fake/servers/test_inst/action') + body = dict(start="") + self.assertRaises(exception.InstanceNotFound, + self.controller._stop_server, req, 'test_inst', body) + + +if __name__ == '__main__': + unittest.main() diff --git a/nova/tests/api/openstack/compute/test_extensions.py b/nova/tests/api/openstack/compute/test_extensions.py index 4a03cacf6..21b490410 100644 --- a/nova/tests/api/openstack/compute/test_extensions.py +++ b/nova/tests/api/openstack/compute/test_extensions.py @@ -176,6 +176,7 @@ class ExtensionControllerTest(ExtensionTestCase): "SecurityGroups", "ServerActionList", "ServerDiagnostics", + "ServerStartStop", "SimpleTenantUsage", "Users", "VSAs", -- cgit