Pass availability zone through to volume creation.
New config option `enable_volume_az` (defaults to false) ensures that the instance and volume will be created in the same availability zone. Story: 2008313 Task: 41208 Change-Id: I62ea46991c7398fba4e5027d5170038624d5aec9
This commit is contained in:
parent
59a972b312
commit
e8287dfda9
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Added the ability to create the cinder volume in the same AZ as the nova
|
||||||
|
instance. Set ``enable_volume_az`` to True (defaults to False)
|
@ -507,7 +507,11 @@ common_opts = [
|
|||||||
'management.'),
|
'management.'),
|
||||||
cfg.BoolOpt(
|
cfg.BoolOpt(
|
||||||
'online_volume_resize', default=True,
|
'online_volume_resize', default=True,
|
||||||
help='If online volume resize is supported.')
|
help='If online volume resize is supported.'),
|
||||||
|
cfg.BoolOpt(
|
||||||
|
'enable_volume_az', default=False,
|
||||||
|
help='If true create the volume in the same availability-zone as the '
|
||||||
|
'instance'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -822,9 +822,11 @@ class FreshInstanceTasks(FreshInstance, NotifyMixin, ConfigurationMixin):
|
|||||||
volume_type, scheduler_hints):
|
volume_type, scheduler_hints):
|
||||||
LOG.debug("Begin _create_server_volume for id: %s", self.id)
|
LOG.debug("Begin _create_server_volume for id: %s", self.id)
|
||||||
server = None
|
server = None
|
||||||
volume_info = self._build_volume_info(datastore_manager,
|
volume_info = self._build_volume_info(
|
||||||
volume_size=volume_size,
|
datastore_manager,
|
||||||
volume_type=volume_type)
|
volume_size=volume_size,
|
||||||
|
volume_type=volume_type,
|
||||||
|
availability_zone=availability_zone)
|
||||||
block_device_mapping_v2 = volume_info['block_device']
|
block_device_mapping_v2 = volume_info['block_device']
|
||||||
try:
|
try:
|
||||||
server = self._create_server(
|
server = self._create_server(
|
||||||
@ -846,7 +848,7 @@ class FreshInstanceTasks(FreshInstance, NotifyMixin, ConfigurationMixin):
|
|||||||
return volume_info
|
return volume_info
|
||||||
|
|
||||||
def _build_volume_info(self, datastore_manager, volume_size=None,
|
def _build_volume_info(self, datastore_manager, volume_size=None,
|
||||||
volume_type=None):
|
volume_type=None, availability_zone=None):
|
||||||
volume_info = None
|
volume_info = None
|
||||||
volume_support = self.volume_support
|
volume_support = self.volume_support
|
||||||
device_path = self.device_path
|
device_path = self.device_path
|
||||||
@ -855,7 +857,8 @@ class FreshInstanceTasks(FreshInstance, NotifyMixin, ConfigurationMixin):
|
|||||||
if volume_support:
|
if volume_support:
|
||||||
try:
|
try:
|
||||||
volume_info = self._create_volume(
|
volume_info = self._create_volume(
|
||||||
volume_size, volume_type, datastore_manager)
|
volume_size, volume_type, datastore_manager,
|
||||||
|
availability_zone)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log_fmt = "Failed to create volume for instance %s"
|
log_fmt = "Failed to create volume for instance %s"
|
||||||
exc_fmt = _("Failed to create volume for instance %s")
|
exc_fmt = _("Failed to create volume for instance %s")
|
||||||
@ -890,14 +893,19 @@ class FreshInstanceTasks(FreshInstance, NotifyMixin, ConfigurationMixin):
|
|||||||
full_message = "%s%s" % (exc_fmt % fmt_content, exc_message)
|
full_message = "%s%s" % (exc_fmt % fmt_content, exc_message)
|
||||||
raise TroveError(message=full_message)
|
raise TroveError(message=full_message)
|
||||||
|
|
||||||
def _create_volume(self, volume_size, volume_type, datastore_manager):
|
def _create_volume(self, volume_size, volume_type, datastore_manager,
|
||||||
|
availability_zone):
|
||||||
LOG.debug("Begin _create_volume for id: %s", self.id)
|
LOG.debug("Begin _create_volume for id: %s", self.id)
|
||||||
volume_client = create_cinder_client(self.context, self.region_name)
|
volume_client = create_cinder_client(self.context, self.region_name)
|
||||||
volume_desc = ("datastore volume for %s" % self.id)
|
volume_desc = ("datastore volume for %s" % self.id)
|
||||||
volume_ref = volume_client.volumes.create(
|
volume_kwargs = {
|
||||||
volume_size, name="trove-%s" % self.id,
|
'size': volume_size,
|
||||||
description=volume_desc,
|
'name': "trove-%s" % self.id,
|
||||||
volume_type=volume_type)
|
'description': volume_desc,
|
||||||
|
'volume_type': volume_type}
|
||||||
|
if CONF.enable_volume_az:
|
||||||
|
volume_kwargs['availability_zone'] = availability_zone
|
||||||
|
volume_ref = volume_client.volumes.create(**volume_kwargs)
|
||||||
|
|
||||||
# Record the volume ID in case something goes wrong.
|
# Record the volume ID in case something goes wrong.
|
||||||
self.update_db(volume_id=volume_ref.id)
|
self.update_db(volume_id=volume_ref.id)
|
||||||
|
@ -358,7 +358,7 @@ class FakeRdServers(object):
|
|||||||
class FakeVolume(object):
|
class FakeVolume(object):
|
||||||
|
|
||||||
def __init__(self, parent, owner, id, size, name,
|
def __init__(self, parent, owner, id, size, name,
|
||||||
description, volume_type):
|
description, volume_type, availability_zone):
|
||||||
self.attachments = []
|
self.attachments = []
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.owner = owner # This is a context.
|
self.owner = owner # This is a context.
|
||||||
@ -371,6 +371,7 @@ class FakeVolume(object):
|
|||||||
# point.
|
# point.
|
||||||
self.device = "vdb"
|
self.device = "vdb"
|
||||||
self.volume_type = volume_type
|
self.volume_type = volume_type
|
||||||
|
self.availability_zone = availability_zone
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
msg = ("FakeVolume(id=%s, size=%s, name=%s, "
|
msg = ("FakeVolume(id=%s, size=%s, name=%s, "
|
||||||
@ -379,10 +380,6 @@ class FakeVolume(object):
|
|||||||
self.description, self._current_status)
|
self.description, self._current_status)
|
||||||
return (msg % params)
|
return (msg % params)
|
||||||
|
|
||||||
@property
|
|
||||||
def availability_zone(self):
|
|
||||||
return "fake-availability-zone"
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def created_at(self):
|
def created_at(self):
|
||||||
return "2001-01-01-12:30:30"
|
return "2001-01-01-12:30:30"
|
||||||
@ -445,10 +442,11 @@ class FakeVolumes(object):
|
|||||||
else:
|
else:
|
||||||
raise nova_exceptions.NotFound(404, "Bad permissions")
|
raise nova_exceptions.NotFound(404, "Bad permissions")
|
||||||
|
|
||||||
def create(self, size, name=None, description=None, volume_type=None):
|
def create(self, size, name=None, description=None, volume_type=None,
|
||||||
|
availability_zone=None):
|
||||||
id = "FAKE_VOL_%s" % uuid.uuid4()
|
id = "FAKE_VOL_%s" % uuid.uuid4()
|
||||||
volume = FakeVolume(self, self.context, id, size, name,
|
volume = FakeVolume(self, self.context, id, size, name,
|
||||||
description, volume_type)
|
description, volume_type, availability_zone)
|
||||||
self.db[id] = volume
|
self.db[id] = volume
|
||||||
if size == 9:
|
if size == 9:
|
||||||
volume.schedule_status("error", 2)
|
volume.schedule_status("error", 2)
|
||||||
|
@ -386,7 +386,7 @@ class FreshInstanceTasksTest(BaseFreshInstanceTasksTest):
|
|||||||
is_public=False
|
is_public=False
|
||||||
)
|
)
|
||||||
mock_build_volume_info.assert_called_with(
|
mock_build_volume_info.assert_called_with(
|
||||||
'mysql', volume_size=2,
|
'mysql', availability_zone=None, volume_size=2,
|
||||||
volume_type='volume_type'
|
volume_type='volume_type'
|
||||||
)
|
)
|
||||||
mock_guest_prepare.assert_called_with(
|
mock_guest_prepare.assert_called_with(
|
||||||
@ -457,7 +457,7 @@ class FreshInstanceTasksTest(BaseFreshInstanceTasksTest):
|
|||||||
)
|
)
|
||||||
|
|
||||||
mock_build_volume_info.assert_called_with(
|
mock_build_volume_info.assert_called_with(
|
||||||
'mysql', volume_size=2,
|
'mysql', availability_zone=None, volume_size=2,
|
||||||
volume_type='volume_type'
|
volume_type='volume_type'
|
||||||
)
|
)
|
||||||
mock_guest_prepare.assert_called_with(
|
mock_guest_prepare.assert_called_with(
|
||||||
|
Loading…
Reference in New Issue
Block a user