Add methods that convert any volume BDM to driver format

There are places in the code where we need to get the DriverBlockDevice
instance based on the BDM object for a volume block device, however the
DriverBlockDevice class the object maps to (based on source of
the data) can be any of the following: volume, snapshot or image, all of
which are actually separate classes that extend VolumeDriverBlockDevice.

This patch adds a method to transform a volume BDM object to the correct
class instance, so that we can more easily avoid bugs such as 1411847.

Related-Bug: #1411847

Change-Id: I3496bab7aac448722240483b86c013e5f80d0cb5
This commit is contained in:
Nikola Dipanov 2015-01-26 16:50:45 +01:00 committed by Michael Still
parent 7287314278
commit 42ea00eece
4 changed files with 38 additions and 9 deletions

View File

@ -4611,7 +4611,7 @@ class ComputeManager(manager.Manager):
if not bdm:
bdm = objects.BlockDeviceMapping.get_by_volume_id(
context, volume_id)
driver_bdm = driver_block_device.DriverVolumeBlockDevice(bdm)
driver_bdm = driver_block_device.convert_volume(bdm)
@utils.synchronized(instance.uuid)
def do_attach_volume(context, instance, driver_bdm):

View File

@ -627,6 +627,22 @@ class TestDriverBlockDevice(test.NoDBTestCase):
[self.volume_bdm, self.ephemeral_bdm])
self.assertEqual(converted, [self.volume_driver_bdm])
def test_convert_all_volumes(self):
converted = driver_block_device.convert_all_volumes()
self.assertEqual([], converted)
converted = driver_block_device.convert_all_volumes(
self.volume_bdm, self.ephemeral_bdm, self.image_bdm)
self.assertEqual(converted, [self.volume_driver_bdm,
self.image_driver_bdm])
def test_convert_volume(self):
self.assertIsNone(driver_block_device.convert_volume(self.swap_bdm))
self.assertEqual(self.volume_driver_bdm,
driver_block_device.convert_volume(self.volume_bdm))
self.assertEqual(self.snapshot_driver_bdm,
driver_block_device.convert_volume(self.snapshot_bdm))
def test_legacy_block_devices(self):
test_snapshot = self.driver_classes['snapshot'](
self.snapshot_bdm)

View File

@ -13,6 +13,7 @@
# under the License.
import functools
import itertools
import operator
from oslo.serialization import jsonutils
@ -392,6 +393,22 @@ convert_blanks = functools.partial(_convert_block_devices,
DriverBlankBlockDevice)
def convert_all_volumes(*volume_bdms):
source_volume = convert_volumes(volume_bdms)
source_snapshot = convert_snapshots(volume_bdms)
source_image = convert_images(volume_bdms)
return [vol for vol in
itertools.chain(source_volume, source_snapshot, source_image)]
def convert_volume(volume_bdm):
try:
return convert_all_volumes(volume_bdm)[0]
except IndexError:
pass
def attach_block_devices(block_device_mapping, *attach_args, **attach_kwargs):
def _log_and_attach(bdm):
context = attach_args[0]

View File

@ -1648,14 +1648,10 @@ class LibvirtDriver(driver.ComputeDriver):
bdm = objects.BlockDeviceMapping.get_by_volume_id(context,
volume_id)
if bdm['source_type'] == 'image':
driver_bdm = driver_block_device.DriverImageBlockDevice(bdm)
else:
# source_type = 'volume'
driver_bdm = driver_block_device.DriverVolumeBlockDevice(bdm)
driver_bdm.refresh_connection_info(context, instance,
self._volume_api, self)
driver_bdm = driver_block_device.convert_volume(bdm)
if driver_bdm:
driver_bdm.refresh_connection_info(context, instance,
self._volume_api, self)
def volume_snapshot_create(self, context, instance, volume_id,
create_info):