summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2012-09-12 23:19:30 +0000
committerGerrit Code Review <review@openstack.org>2012-09-12 23:19:30 +0000
commit3390c70d2f4481527aaf2fbc3847664b3f45de0e (patch)
tree0a863500d5f06797f1aaa48e527cfd5d509b022c
parentde63434fec28987f4a7e6850e05cce0fa0082d44 (diff)
parentca9428037a33cf970d4d0c229121ee526614885a (diff)
Merge "Add 'detaching' to volume status"
-rw-r--r--nova/compute/api.py1
-rw-r--r--nova/compute/manager.py14
-rw-r--r--nova/tests/fake_volume.py10
-rw-r--r--nova/tests/policy.json2
-rw-r--r--nova/tests/test_volume.py11
-rw-r--r--nova/volume/api.py11
-rw-r--r--nova/volume/cinder.py6
7 files changed, 52 insertions, 3 deletions
diff --git a/nova/compute/api.py b/nova/compute/api.py
index a85e01d46..399ac6dd3 100644
--- a/nova/compute/api.py
+++ b/nova/compute/api.py
@@ -1839,6 +1839,7 @@ class API(base.Base):
volume = self.volume_api.get(context, volume_id)
self.volume_api.check_detach(context, volume)
+ self.volume_api.begin_detaching(context, volume)
self.compute_rpcapi.detach_volume(context, instance=instance,
volume_id=volume_id)
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index 1177d052d..6251027d7 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -1979,9 +1979,17 @@ class ComputeManager(manager.SchedulerDependentManager):
# but added for completeness in case we ever do.
if connection_info and 'serial' not in connection_info:
connection_info['serial'] = volume_id
- self.driver.detach_volume(connection_info,
- instance['name'],
- mp)
+ try:
+ self.driver.detach_volume(connection_info,
+ instance['name'],
+ mp)
+ except Exception: # pylint: disable=W0702
+ with excutils.save_and_reraise_exception():
+ msg = _("Faild to detach volume %(volume_id)s from %(mp)s")
+ LOG.exception(msg % locals(), context=context,
+ instance=instance)
+ volume = self.volume_api.get(context, volume_id)
+ self.volume_api.roll_detaching(context, volume)
@exception.wrap_exception(notifier=notifier, publisher_id=publisher_id())
@reverts_task_state
diff --git a/nova/tests/fake_volume.py b/nova/tests/fake_volume.py
index 040897582..8093ff06f 100644
--- a/nova/tests/fake_volume.py
+++ b/nova/tests/fake_volume.py
@@ -258,3 +258,13 @@ class API(object):
LOG.info('unreserving volume %s', volume['id'])
volume = self.get(context, volume['id'])
volume['status'] = 'available'
+
+ def begin_detaching(self, context, volume):
+ LOG.info('beging detaching volume %s', volume['id'])
+ volume = self.get(context, volume['id'])
+ volume['status'] = 'detaching'
+
+ def roll_detaching(self, context, volume):
+ LOG.info('roll detaching volume %s', volume['id'])
+ volume = self.get(context, volume['id'])
+ volume['status'] = 'in-use'
diff --git a/nova/tests/policy.json b/nova/tests/policy.json
index 073ba4142..d735f6b86 100644
--- a/nova/tests/policy.json
+++ b/nova/tests/policy.json
@@ -137,6 +137,8 @@
"volume:detach": [],
"volume:reserve_volume": [],
"volume:unreserve_volume": [],
+ "volume:begin_detaching": [],
+ "volume:roll_detaching": [],
"volume:check_attach": [],
"volume:check_detach": [],
"volume:initialize_connection": [],
diff --git a/nova/tests/test_volume.py b/nova/tests/test_volume.py
index 0752d2b9b..5bd510406 100644
--- a/nova/tests/test_volume.py
+++ b/nova/tests/test_volume.py
@@ -490,6 +490,17 @@ class VolumeTestCase(test.TestCase):
'name',
'description')
+ def test_begin_roll_detaching_volume(self):
+ """Test begin_detaching and roll_detaching functions."""
+ volume = self._create_volume()
+ volume_api = nova.volume.api.API()
+ volume_api.begin_detaching(self.context, volume)
+ volume = db.volume_get(self.context, volume['id'])
+ self.assertEqual(volume['status'], "detaching")
+ volume_api.roll_detaching(self.context, volume)
+ volume = db.volume_get(self.context, volume['id'])
+ self.assertEqual(volume['status'], "in-use")
+
class DriverTestCase(test.TestCase):
"""Base Test class for Drivers."""
diff --git a/nova/volume/api.py b/nova/volume/api.py
index 3b8c62e11..eb03b94c3 100644
--- a/nova/volume/api.py
+++ b/nova/volume/api.py
@@ -304,6 +304,17 @@ class API(base.Base):
{"status": "available"})
@wrap_check_policy
+ def begin_detaching(self, context, volume):
+ self.db.volume_update(context, volume['id'], {"status": "detaching"})
+
+ @wrap_check_policy
+ def roll_detaching(self, context, volume):
+ if volume['status'] == "detaching":
+ self.db.volume_update(context,
+ volume['id'],
+ {"status": "in-use"})
+
+ @wrap_check_policy
def attach(self, context, volume, instance_uuid, mountpoint):
host = volume['host']
queue = rpc.queue_get_for(context, FLAGS.volume_topic, host)
diff --git a/nova/volume/cinder.py b/nova/volume/cinder.py
index 9d5222c03..87b8036a1 100644
--- a/nova/volume/cinder.py
+++ b/nova/volume/cinder.py
@@ -165,6 +165,12 @@ class API(base.Base):
def unreserve_volume(self, context, volume):
cinderclient(context).volumes.unreserve(volume['id'])
+ def begin_detaching(self, context, volume):
+ cinderclient(context).volumes.begin_detaching(volume['id'])
+
+ def roll_detaching(self, context, volume):
+ cinderclient(context).volumes.roll_detaching(volume['id'])
+
def attach(self, context, volume, instance_uuid, mountpoint):
cinderclient(context).volumes.attach(volume['id'],
instance_uuid,