summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2012-02-23 18:32:53 +0000
committerGerrit Code Review <review@openstack.org>2012-02-23 18:32:53 +0000
commitdd851ff62b04da2c2d922dea6b9c175dc44ae234 (patch)
treee615d2ac5f461a5122bedec111137d92dfd4c72b
parent2736b2d493e5129257061739d339d4cd4d8a5f25 (diff)
parentd0cc37f8095bef38605930683af43af7ddb7e4a8 (diff)
downloadnova-dd851ff62b04da2c2d922dea6b9c175dc44ae234.tar.gz
Merge "Add attaching state for Volumes"
-rw-r--r--Authors1
-rw-r--r--nova/compute/api.py1
-rw-r--r--nova/compute/manager.py17
-rw-r--r--nova/tests/policy.json2
-rw-r--r--nova/tests/test_compute.py6
-rw-r--r--nova/utils.py6
-rw-r--r--nova/volume/api.py10
7 files changed, 38 insertions, 5 deletions
diff --git a/Authors b/Authors
index 1668cfa8fe..ec0e28b06a 100644
--- a/Authors
+++ b/Authors
@@ -106,6 +106,7 @@ Kevin L. Mitchell <kevin.mitchell@rackspace.com>
Kiall Mac Innes <kiall@managedit.ie>
Kirill Shileev <kshileev@gmail.com>
Koji Iida <iida.koji@lab.ntt.co.jp>
+Liam Kelleher <liam.kelleher@hp.com>
Likitha Shetty <likitha.shetty@citrix.com>
Loganathan Parthipan <parthipan@hp.com>
Lorin Hochstein <lorin@isi.edu>
diff --git a/nova/compute/api.py b/nova/compute/api.py
index 80abd37e1e..0aee6dc2fe 100644
--- a/nova/compute/api.py
+++ b/nova/compute/api.py
@@ -1515,6 +1515,7 @@ class API(base.Base):
raise exception.InvalidDevicePath(path=device)
volume = self.volume_api.get(context, volume_id)
self.volume_api.check_attach(context, volume)
+ self.volume_api.reserve_volume(context, volume)
params = {"volume_id": volume_id,
"mountpoint": device}
_cast_compute_message(self.db, 'attach_volume', context, instance,
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index b640861153..7eb8d45d6f 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -1659,12 +1659,21 @@ class ComputeManager(manager.SchedulerDependentManager):
context = context.elevated()
instance_ref = self.db.instance_get_by_uuid(context, instance_uuid)
instance_id = instance_ref['id']
+ msg = _("instance %(instance_uuid)s: attaching volume %(volume_id)s"
+ " to %(mountpoint)s")
LOG.audit(_('Attaching volume %(volume_id)s to %(mountpoint)s'),
locals(), context=context, instance=instance_ref)
- connector = self.driver.get_volume_connector(instance_ref)
- connection_info = self.volume_api.initialize_connection(context,
- volume,
- connector)
+ try:
+ connector = self.driver.get_volume_connector(instance_ref)
+ connection_info = self.volume_api.initialize_connection(context,
+ volume,
+ connector)
+ except Exception: # pylint: disable=W0702
+ with utils.save_and_reraise_exception():
+ msg = _("instance %(instance_uuid)s: attach failed"
+ " %(mountpoint)s, removing")
+ LOG.exception(msg % locals(), context=context)
+ self.volume_api.unreserve_volume(context, volume)
try:
self.driver.attach_volume(connection_info,
instance_ref['name'],
diff --git a/nova/tests/policy.json b/nova/tests/policy.json
index c231bff60a..d2e647f9f1 100644
--- a/nova/tests/policy.json
+++ b/nova/tests/policy.json
@@ -127,6 +127,8 @@
"volume:attach": [],
"volume:detach": [],
+ "volume:reserve_volume": [],
+ "volume:unreserve_volume": [],
"volume:check_attach": [],
"volume:check_detach": [],
"volume:initialize_connection": [],
diff --git a/nova/tests/test_compute.py b/nova/tests/test_compute.py
index 5e15b95e70..7fc3d8bed1 100644
--- a/nova/tests/test_compute.py
+++ b/nova/tests/test_compute.py
@@ -3149,12 +3149,16 @@ class ComputeAPITestCase(BaseTestCase):
def fake_check_attach(*args, **kwargs):
pass
+ def fake_reserve_volume(*args, **kwargs):
+ pass
+
def fake_volume_get(self, context, volume_id):
return {'id': volume_id}
self.stubs.Set(nova.volume.api.API, 'get', fake_volume_get)
self.stubs.Set(nova.volume.api.API, 'check_attach', fake_check_attach)
-
+ self.stubs.Set(nova.volume.api.API, 'reserve_volume',
+ fake_reserve_volume)
instance = self._create_fake_instance()
self.compute_api.attach_volume(self.context, instance, 1, '/dev/vdb')
diff --git a/nova/utils.py b/nova/utils.py
index dc8a660a62..ec62f87fc4 100644
--- a/nova/utils.py
+++ b/nova/utils.py
@@ -24,6 +24,7 @@ import datetime
import functools
import hashlib
import inspect
+import itertools
import json
import lockfile
import os
@@ -709,6 +710,11 @@ def to_primitive(value, convert_instances=False, level=0):
if test(value):
return unicode(value)
+ # value of itertools.count doesn't get caught by inspects
+ # above and results in infinite loop when list(value) is called.
+ if type(value) == itertools.count:
+ return unicode(value)
+
# FIXME(vish): Workaround for LP bug 852095. Without this workaround,
# tests that raise an exception in a mocked method that
# has a @wrap_exception with a notifier will fail. If
diff --git a/nova/volume/api.py b/nova/volume/api.py
index 8646f65e99..4719f4f1e4 100644
--- a/nova/volume/api.py
+++ b/nova/volume/api.py
@@ -229,6 +229,15 @@ class API(base.Base):
'volume_id': volume['id']}})
@wrap_check_policy
+ def reserve_volume(self, context, volume):
+ self.update(context, volume, {"status": "attaching"})
+
+ @wrap_check_policy
+ def unreserve_volume(self, context, volume):
+ if volume['status'] == "attaching":
+ self.update(context, volume, {"status": "available"})
+
+ @wrap_check_policy
def attach(self, context, volume, instance_id, mountpoint):
host = volume['host']
queue = self.db.queue_get_for(context, FLAGS.volume_topic, host)
@@ -257,6 +266,7 @@ class API(base.Base):
@wrap_check_policy
def terminate_connection(self, context, volume, connector):
+ self.unreserve_volume(context, volume)
host = volume['host']
queue = self.db.queue_get_for(context, FLAGS.volume_topic, host)
return rpc.call(context, queue,