summaryrefslogtreecommitdiff
path: root/nova
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2015-09-18 17:15:24 +0000
committerGerrit Code Review <review@openstack.org>2015-09-18 17:15:24 +0000
commit2a9c455b6b488e698e3fae2688b53fdd10707dd7 (patch)
treeb95658177e3b1d202dad0538a319f894c91f05fb /nova
parent1df8248b6ad7982174c417abf80070107eac8909 (diff)
parentaa899506366cd84d5170cb913f33c0c0ca7a8b27 (diff)
downloadnova-2a9c455b6b488e698e3fae2688b53fdd10707dd7.tar.gz
Merge "Detach and terminate conn if Cinder attach fails"
Diffstat (limited to 'nova')
-rw-r--r--nova/tests/unit/virt/test_block_device.py25
-rw-r--r--nova/virt/block_device.py27
2 files changed, 50 insertions, 2 deletions
diff --git a/nova/tests/unit/virt/test_block_device.py b/nova/tests/unit/virt/test_block_device.py
index 0b93839f68..0142a2df7a 100644
--- a/nova/tests/unit/virt/test_block_device.py
+++ b/nova/tests/unit/virt/test_block_device.py
@@ -436,6 +436,17 @@ class TestDriverBlockDevice(test.NoDBTestCase):
'fake_uuid', bdm_dict['device_name'],
mode=access_mode).AndRaise(
test.TestingException)
+ if driver_attach:
+ self.virt_driver.detach_volume(
+ expected_conn_info, instance,
+ bdm_dict['device_name'],
+ encryption=enc_data).AndReturn(None)
+ self.volume_api.terminate_connection(
+ elevated_context, fake_volume['id'],
+ connector).AndReturn(None)
+ self.volume_api.detach(elevated_context,
+ fake_volume['id']).AndReturn(None)
+
driver_bdm._bdm_obj.save().AndReturn(None)
return instance, expected_conn_info
@@ -564,6 +575,20 @@ class TestDriverBlockDevice(test.NoDBTestCase):
instance, self.volume_api, self.virt_driver,
do_driver_attach=True)
+ def test_volume_attach_no_driver_attach_volume_attach_fails(self):
+ test_bdm = self.driver_classes['volume'](
+ self.volume_bdm)
+ volume = {'id': 'fake-volume-id-1',
+ 'attach_status': 'detached'}
+
+ instance, _ = self._test_volume_attach(
+ test_bdm, self.volume_bdm, volume, fail_volume_attach=True)
+ self.mox.ReplayAll()
+
+ self.assertRaises(test.TestingException, test_bdm.attach, self.context,
+ instance, self.volume_api, self.virt_driver,
+ do_driver_attach=False)
+
def test_refresh_connection(self):
test_bdm = self.driver_classes['snapshot'](
self.snapshot_bdm)
diff --git a/nova/virt/block_device.py b/nova/virt/block_device.py
index 5e70aaf398..22f06f1e5d 100644
--- a/nova/virt/block_device.py
+++ b/nova/virt/block_device.py
@@ -276,8 +276,31 @@ class DriverVolumeBlockDevice(DriverBlockDevice):
# after that we can detach and connection_info is required for
# detach.
self.save()
- volume_api.attach(context, volume_id, instance.uuid,
- self['mount_device'], mode=mode)
+ try:
+ volume_api.attach(context, volume_id, instance.uuid,
+ self['mount_device'], mode=mode)
+ except Exception:
+ with excutils.save_and_reraise_exception():
+ if do_driver_attach:
+ try:
+ virt_driver.detach_volume(connection_info,
+ instance,
+ self['mount_device'],
+ encryption=encryption)
+ except Exception:
+ LOG.warn(_LW("Driver failed to detach volume "
+ "%(volume_id)s at %(mount_point)s."),
+ {'volume_id': volume_id,
+ 'mount_point': self['mount_device']},
+ exc_info=True, context=context,
+ instance=instance)
+ volume_api.terminate_connection(context, volume_id,
+ connector)
+
+ # Cinder-volume might have completed volume attach. So
+ # we should detach the volume. If the attach did not
+ # happen, the detach request will be ignored.
+ volume_api.detach(context, volume_id)
@update_db
def refresh_connection_info(self, context, instance,