volume = self._get(context, id)
except exception.VolumeNotFound as e:
raise exc.HTTPNotFound(explanation=e.msg)
- self.volume_api.terminate_connection(context, volume,
- {}, force=True)
+ try:
+ connector = body['os-force_detach'].get('connector', None)
+ except KeyError:
+ raise webob.exc.HTTPBadRequest(
+ explanation=_("Must specify '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)
attachment_id = body['os-force_detach'].get('attachment_id', None)
req.headers['content-type'] = 'application/json'
# request status of 'error'
req.body = jsonutils.dumps({'os-force_detach':
- {'attachment_id': attachment['id']}})
+ {'attachment_id': attachment['id'],
+ 'connector': connector}})
# attach admin context to request
req.environ['cinder.context'] = ctx
# make request
req.headers['content-type'] = 'application/json'
# request status of 'error'
req.body = jsonutils.dumps({'os-force_detach':
- {'attachment_id': attachment['id']}})
+ {'attachment_id': attachment['id'],
+ 'connector': connector}})
# attach admin context to request
req.environ['cinder.context'] = ctx
# make request
# make request
resp = req.get_response(app())
self.assertEqual(400, resp.status_int)
+
+ # test for KeyError when missing connector
+ volume_remote_error = (
+ messaging.RemoteError(exc_type='KeyError'))
+ with mock.patch.object(volume_api.API, 'detach',
+ side_effect=volume_remote_error):
+ req = webob.Request.blank('/v2/fake/volumes/%s/action' %
+ volume['id'])
+ req.method = 'POST'
+ req.headers['content-type'] = 'application/json'
+ req.body = jsonutils.dumps({'os-force_detach':
+ {'attachment_id': 'fake'}})
+ # attach admin context to request
+ req.environ['cinder.context'] = ctx
+ # make request
+ self.assertRaises(messaging.RemoteError,
+ req.get_response,
+ app())
+
+ # test for VolumeBackendAPIException
+ volume_remote_error = (
+ messaging.RemoteError(exc_type='VolumeBackendAPIException'))
+ with mock.patch.object(volume_api.API, 'detach',
+ side_effect=volume_remote_error):
+ req = webob.Request.blank('/v2/fake/volumes/%s/action' %
+ volume['id'])
+ req.method = 'POST'
+ req.headers['content-type'] = 'application/json'
+ req.body = jsonutils.dumps({'os-force_detach':
+ {'attachment_id': 'fake',
+ 'connector': connector}})
+
+ # attach admin context to request
+ req.environ['cinder.context'] = ctx
+ # make request
+ self.assertRaises(messaging.RemoteError,
+ req.get_response,
+ app())
# cleanup
svc.stop()
req.method = 'POST'
req.headers['content-type'] = 'application/json'
req.body = jsonutils.dumps({'os-force_detach':
- {'attachment_id': 'fake'}})
+ {'attachment_id': 'fake',
+ 'connector': connector}})
# attach admin context to request
req.environ['cinder.context'] = ctx
# make request