summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiam Kelleher <liam.kelleher@hp.com>2013-02-11 15:51:53 +0000
committerLiam Kelleher <liam.kelleher@hp.com>2013-02-14 17:29:18 +0000
commit1504cbc5d4a27695fa663f0b0f3f7b48745bdb45 (patch)
treef7c111b87437e99fe79ead9429bf265dda83eee9
parent4ffddcfa6385703ce9a02f624999f05b388778e6 (diff)
downloadnova-1504cbc5d4a27695fa663f0b0f3f7b48745bdb45.tar.gz
nova-1504cbc5d4a27695fa663f0b0f3f7b48745bdb45.tar.xz
nova-1504cbc5d4a27695fa663f0b0f3f7b48745bdb45.zip
Add option to allow cross AZ attach configurable
Make check_attach() optionally check if the volume and instance are in the same availability zone and if cross AZ attach is configured as not allowed report error. This does not change the current default behaviour. DocImpact: Adds a new Nova Config option Change-Id: Ib0e085888b1c6620869261d87cd964de302accb3
-rw-r--r--nova/compute/api.py2
-rw-r--r--nova/compute/cells_api.py2
-rwxr-xr-xnova/compute/manager.py3
-rw-r--r--nova/tests/fake_volume.py11
-rw-r--r--nova/volume/cinder.py10
5 files changed, 23 insertions, 5 deletions
diff --git a/nova/compute/api.py b/nova/compute/api.py
index 658673e50..3337fc82e 100644
--- a/nova/compute/api.py
+++ b/nova/compute/api.py
@@ -2244,7 +2244,7 @@ class API(base.Base):
context, device=device, instance=instance, volume_id=volume_id)
try:
volume = self.volume_api.get(context, volume_id)
- self.volume_api.check_attach(context, volume)
+ self.volume_api.check_attach(context, volume, instance=instance)
self.volume_api.reserve_volume(context, volume)
self.compute_rpcapi.attach_volume(context, instance=instance,
volume_id=volume_id, mountpoint=device)
diff --git a/nova/compute/cells_api.py b/nova/compute/cells_api.py
index 50449df04..1e30331bc 100644
--- a/nova/compute/cells_api.py
+++ b/nova/compute/cells_api.py
@@ -524,7 +524,7 @@ class ComputeCellsAPI(compute_api.API):
context, device=device, instance=instance, volume_id=volume_id)
try:
volume = self.volume_api.get(context, volume_id)
- self.volume_api.check_attach(context, volume)
+ self.volume_api.check_attach(context, volume, instance=instance)
except Exception:
with excutils.save_and_reraise_exception():
self.db.block_device_mapping_destroy_by_instance_and_device(
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index 8927e682a..18b0f3ae1 100755
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -645,7 +645,8 @@ class ComputeManager(manager.SchedulerDependentManager):
if bdm['volume_id'] is not None:
volume = self.volume_api.get(context, bdm['volume_id'])
- self.volume_api.check_attach(context, volume)
+ self.volume_api.check_attach(context, volume,
+ instance=instance)
cinfo = self._attach_volume_boot(context,
instance,
volume,
diff --git a/nova/tests/fake_volume.py b/nova/tests/fake_volume.py
index c7430ee6d..0d8a502a5 100644
--- a/nova/tests/fake_volume.py
+++ b/nova/tests/fake_volume.py
@@ -17,12 +17,17 @@
import uuid
from nova import exception
+from nova.openstack.common import cfg
from nova.openstack.common import log as logging
from nova.openstack.common import timeutils
LOG = logging.getLogger(__name__)
+CONF = cfg.CONF
+CONF.import_opt('cinder_cross_az_attach',
+ 'nova.volume.cinder')
+
class fake_volume():
user_uuid = '4a3cd440-b9c2-11e1-afa6-0800200c9a66'
@@ -175,7 +180,7 @@ class API(object):
LOG.info('deleting volume %s', volume['id'])
self.volume_list = [v for v in self.volume_list if v != volume]
- def check_attach(self, context, volume):
+ def check_attach(self, context, volume, instance=None):
if volume['status'] != 'available':
msg = _("status must be available")
msg = "%s" % volume
@@ -183,6 +188,10 @@ class API(object):
if volume['attach_status'] == 'attached':
msg = _("already attached")
raise exception.InvalidVolume(reason=msg)
+ if instance and not CONF.cinder_cross_az_attach:
+ if instance['availability_zone'] != volume['availability_zone']:
+ msg = _("Instance and volume not in same availability_zone")
+ raise exception.InvalidVolume(reason=msg)
def check_detach(self, context, volume):
if volume['status'] == "available":
diff --git a/nova/volume/cinder.py b/nova/volume/cinder.py
index 05918f83d..b58e63011 100644
--- a/nova/volume/cinder.py
+++ b/nova/volume/cinder.py
@@ -51,6 +51,10 @@ cinder_opts = [
cfg.BoolOpt('cinder_api_insecure',
default=False,
help='Allow to perform insecure SSL requests to cinder'),
+ cfg.BoolOpt('cinder_cross_az_attach',
+ default=True,
+ help='Allow attach between instance and volume in different '
+ 'availability zones.'),
]
CONF = cfg.CONF
@@ -195,7 +199,7 @@ class API(base.Base):
return rval
- def check_attach(self, context, volume):
+ def check_attach(self, context, volume, instance=None):
# TODO(vish): abstract status checking?
if volume['status'] != "available":
msg = _("status must be available")
@@ -203,6 +207,10 @@ class API(base.Base):
if volume['attach_status'] == "attached":
msg = _("already attached")
raise exception.InvalidVolume(reason=msg)
+ if instance and not CONF.cinder_cross_az_attach:
+ if instance['availability_zone'] != volume['availability_zone']:
+ msg = _("Instance and volume not in same availability_zone")
+ raise exception.InvalidVolume(reason=msg)
def check_detach(self, context, volume):
# TODO(vish): abstract status checking?