"""Try to clone a volume from an image, and check the status
afterwards.
"""
- def fake_clone_image(volume, image_location):
+ def fake_clone_image(volume, image_location, image_id):
return {'provider_location': None}, True
- def fake_clone_error(volume, image_location):
+ def fake_clone_error(volume, image_location, image_id):
raise exception.CinderException()
self.stubs.Set(self.volume.driver, '_is_cloneable', lambda x: True)
expected = ({}, False)
self.stubs.Set(self.volume.driver, '_is_cloneable', lambda x: False)
- self.assertEquals(expected,
- self.volume.driver.clone_image(object(), object()))
+ actual = self.volume.driver.clone_image(object(), object(), object())
+ self.assertEquals(expected, actual)
self.stubs.Set(self.volume.driver, '_is_cloneable', lambda x: True)
self.assertEquals(expected,
- self.volume.driver.clone_image(object(), None))
+ self.volume.driver.clone_image(object(), None, None))
# Test Success Case(s)
expected = ({'provider_location': None}, True)
self.stubs.Set(self.volume.driver, '_clone', lambda *args: None)
self.stubs.Set(self.volume.driver, '_resize', lambda *args: None)
-
- self.assertEquals(expected,
- self.volume.driver.clone_image(object(), object()))
+ actual = self.volume.driver.clone_image(object(), object(), object())
+ self.assertEquals(expected, actual)
def test_clone_success(self):
self.stubs.Set(self.volume.driver, '_is_cloneable', lambda x: True)
- self.stubs.Set(self.volume.driver, 'clone_image', lambda a, b: True)
+ self.stubs.Set(self.volume.driver, 'clone_image', lambda a, b, c: True)
image_id = 'c905cedb-7281-47e4-8a62-f26bc5fc4c77'
- self.assertTrue(self.volume.driver.clone_image({}, image_id))
+ self.assertTrue(self.volume.driver.clone_image({}, image_id, image_id))
# Use Brick's code to do attach/detach
use_multipath = self.configuration.use_multipath_for_image_xfer
protocol = conn['driver_volume_type']
- connector = initiator.InitiatorConnector.factory(protocol,
- use_multipath=
- use_multipath)
+ connector = initiator.InitiatorConnector.factory(
+ protocol, use_multipath=use_multipath)
device = connector.connect_volume(conn['data'])
host_device = device['path']
connector.disconnect_volume(attach_info['conn']['data'],
attach_info['device'])
- def clone_image(self, volume, image_location):
+ def clone_image(self, volume, image_location, image_id):
"""Create a volume efficiently from an existing image.
image_location is a string whose format depends on the
image service backend in use. The driver should use it
to determine whether cloning is possible.
+ image_id is a string which represents id of the image.
+ It can be used by the driver to introspect internal
+ stores or registry to do an efficient image clone.
+
Returns a dict of volume properties eg. provider_location,
boolean indicating whether cloning occurred
"""
finally:
self.delete_snapshot(temp_snapshot)
- def clone_image(self, volume, image_location):
+ def clone_image(self, volume, image_location, image_id):
return None, False
def backup_volume(self, context, backup, backup_service):
dict(loc=image_location, err=e))
return False
- def clone_image(self, volume, image_location):
+ def clone_image(self, volume, image_location, image_id):
if image_location is None or not self._is_cloneable(image_location):
return ({}, False)
prefix, pool, image, snapshot = self._parse_location(image_location)
image_meta,
self.local_path(volume))
- def clone_image(self, volume, image_location):
+ def clone_image(self, volume, image_location, image_id):
"""Create a volume efficiently from an existing image.
image_location is a string whose format depends on the
image service backend in use. The driver should use it
to determine whether cloning is possible.
+ image_id is a string which represents id of the image.
+ It can be used by the driver to introspect internal
+ stores or registry to do an efficient image clone.
+
Returns a dict of volume properties eg. provider_location,
boolean indicating whether cloning occurred
"""
if srcvol_ref.bootable:
self._enable_bootable_flag(context, volume_ref['id'])
try:
- LOG.debug(_('Copying metadata from source volume %(source_volid)s'
- ' to cloned volume %(clone_vol_id)s') % {
- 'source_volid': source_volid,
- 'clone_vol_id': volume_ref['id'],
- })
+ msg = _('Copying metadata from source volume %(source_volid)s'
+ ' to cloned volume %(clone_vol_id)s')
+ LOG.debug(msg % {'source_volid': source_volid,
+ 'clone_vol_id': volume_ref['id'], })
self.db.volume_glance_metadata_copy_from_volume_to_volume(
context,
source_volid,
# NOTE (singn): two params need to be returned
# dict containing provider_location for cloned volume
# and clone status.
- model_update, cloned = self.driver.clone_image(volume_ref,
- image_location)
+ model_update, cloned = self.driver.clone_image(
+ volume_ref, image_location, image_id)
make_bootable = False
if not cloned:
# TODO(harlowja): what needs to be rolled back in the clone if this