msg = _("Invalid request to attach volume with an invalid mode. "
"Attaching mode should be 'rw' or 'ro'")
raise webob.exc.HTTPBadRequest(explanation=msg)
+ try:
+ self.volume_api.attach(context, volume,
+ instance_uuid, host_name, mountpoint, mode)
+ except messaging.RemoteError as error:
+ if error.exc_type in ['InvalidVolume', 'InvalidUUID',
+ 'InvalidVolumeAttachMode']:
+ msg = "Error attaching volume - %(err_type)s: %(err_msg)s" % {
+ 'err_type': error.exc_type, 'err_msg': error.value}
+ raise webob.exc.HTTPBadRequest(explanation=msg)
+ else:
+ # There are also few cases where attach call could fail due to
+ # db or volume driver errors. These errors shouldn't be exposed
+ # to the user and in such cases it should raise 500 error.
+ raise
- self.volume_api.attach(context, volume,
- instance_uuid, host_name, mountpoint, mode)
return webob.Response(status_int=202)
@wsgi.action('os-detach')
def setUp(self):
super(VolumeActionsTest, self).setUp()
self.UUID = uuid.uuid4()
+ self.controller = volume_actions.VolumeActionsController()
self.api_patchers = {}
for _meth in self._methods:
self.api_patchers[_meth] = mock.patch('cinder.volume.API.' + _meth)
res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 202)
+ def test_volume_attach_to_instance_raises_remote_error(self):
+ volume_remote_error = \
+ messaging.RemoteError(exc_type='InvalidUUID')
+ with mock.patch.object(volume_api.API, 'attach',
+ side_effect=volume_remote_error):
+ id = 1
+ vol = {"instance_uuid": self.UUID,
+ "mountpoint": "/dev/vdc",
+ "mode": "rw"}
+ body = {"os-attach": vol}
+ req = fakes.HTTPRequest.blank('/v2/tenant1/volumes/%s/action' % id)
+ self.assertRaises(webob.exc.HTTPBadRequest,
+ self.controller._attach,
+ req,
+ id,
+ body)
+
+ def test_volume_attach_to_instance_raises_db_error(self):
+ # In case of DB error 500 error code is returned to user
+ volume_remote_error = \
+ messaging.RemoteError(exc_type='DBError')
+ with mock.patch.object(volume_api.API, 'attach',
+ side_effect=volume_remote_error):
+ id = 1
+ vol = {"instance_uuid": self.UUID,
+ "mountpoint": "/dev/vdc",
+ "mode": "rw"}
+ body = {"os-attach": vol}
+ req = fakes.HTTPRequest.blank('/v2/tenant1/volumes/%s/action' % id)
+ self.assertRaises(messaging.RemoteError,
+ self.controller._attach,
+ req,
+ id,
+ body)
+
def test_detach(self):
body = {'os-detach': {'attachment_id': 'fakeuuid'}}
req = webob.Request.blank('/v2/fake/volumes/1/action')