Skip to content

Commit

Permalink
Merge "Handle terminate_connection() exception in volume manager"
Browse files Browse the repository at this point in the history
  • Loading branch information
Jenkins authored and openstack-gerrit committed Dec 29, 2013
2 parents 5bc87a9 + 1e73e64 commit 2d6a903
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 25 deletions.
6 changes: 5 additions & 1 deletion cinder/api/contrib/volume_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,11 @@ def _terminate_connection(self, req, id, body):
connector = body['os-terminate_connection']['connector']
except KeyError:
raise webob.exc.HTTPBadRequest("Must specify 'connector'")
self.volume_api.terminate_connection(context, volume, connector)
try:
self.volume_api.terminate_connection(context, volume, connector)
except exception.VolumeBackendAPIException as error:
msg = _("Unable to terminate volume connection from backend.")
raise webob.exc.HTTPInternalServerError(explanation=msg)
return webob.Response(status_int=202)

@wsgi.response(202)
Expand Down
56 changes: 33 additions & 23 deletions cinder/tests/api/contrib/test_volume_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,34 +107,44 @@ def test_initialize_connection_exception(self):
self.assertEqual(res.status_int, 500)

def test_terminate_connection(self):
def fake_terminate_connection(*args, **kwargs):
return {}
self.stubs.Set(volume.API, 'terminate_connection',
fake_terminate_connection)

body = {'os-terminate_connection': {'connector': 'fake'}}
req = webob.Request.blank('/v2/fake/volumes/1/action')
req.method = "POST"
req.body = jsonutils.dumps(body)
req.headers["content-type"] = "application/json"
with mock.patch.object(volume_api.API,
'terminate_connection') as terminate_conn:
terminate_conn.return_value = {}
body = {'os-terminate_connection': {'connector': 'fake'}}
req = webob.Request.blank('/v2/fake/volumes/1/action')
req.method = "POST"
req.body = jsonutils.dumps(body)
req.headers["content-type"] = "application/json"

res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 202)
res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 202)

def test_terminate_connection_without_connector(self):
def fake_terminate_connection(*args, **kwargs):
return {}
self.stubs.Set(volume.API, 'terminate_connection',
fake_terminate_connection)
with mock.patch.object(volume_api.API,
'terminate_connection') as terminate_conn:
terminate_conn.return_value = {}
body = {'os-terminate_connection': {}}
req = webob.Request.blank('/v2/fake/volumes/1/action')
req.method = "POST"
req.body = jsonutils.dumps(body)
req.headers["content-type"] = "application/json"

body = {'os-terminate_connection': {}}
req = webob.Request.blank('/v2/fake/volumes/1/action')
req.method = "POST"
req.body = jsonutils.dumps(body)
req.headers["content-type"] = "application/json"
res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 400)

res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 400)
def test_terminate_connection_with_exception(self):
with mock.patch.object(volume_api.API,
'terminate_connection') as terminate_conn:
terminate_conn.side_effect = \
exception.VolumeBackendAPIException(data=None)
body = {'os-terminate_connection': {'connector': 'fake'}}
req = webob.Request.blank('/v2/fake/volumes/1/action')
req.method = "POST"
req.body = jsonutils.dumps(body)
req.headers["content-type"] = "application/json"

res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 500)

def test_attach_to_instance(self):
body = {'os-attach': {'instance_uuid': 'fake',
Expand Down
9 changes: 8 additions & 1 deletion cinder/volume/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -750,7 +750,14 @@ def terminate_connection(self, context, volume_id, connector, force=False):
The format of connector is the same as for initialize_connection.
"""
volume_ref = self.db.volume_get(context, volume_id)
self.driver.terminate_connection(volume_ref, connector, force=force)
try:
self.driver.terminate_connection(volume_ref,
connector, force=force)
except Exception as err:
err_msg = (_('Unable to terminate volume connection: %(err)s')
% {'err': str(err)})
LOG.error(err_msg)
raise exception.VolumeBackendAPIException(data=err_msg)

@utils.require_driver_initialized
def accept_transfer(self, context, volume_id, new_user, new_project):
Expand Down

0 comments on commit 2d6a903

Please sign in to comment.