From 6b85f929742348fc4ba9b17e2181982de7ef02a8 Mon Sep 17 00:00:00 2001 From: Navneet Singh Date: Mon, 15 Jul 2013 10:42:00 +0530 Subject: [PATCH] Clone_image method added image_id as parameter. Clone_image method contains volume and image_location as parameters. It needs to add additional image_id as a parameter for driver implementations to introspect internal image stores or registry for efficient image cloning. blueprint clone-image-imageid Change-Id: I20ae519492d73abecb1d0efc3b8e7204d2b2a4cb --- cinder/tests/test_rbd.py | 19 +++++++++---------- cinder/volume/driver.py | 11 +++++++---- cinder/volume/drivers/lvm.py | 2 +- cinder/volume/drivers/rbd.py | 2 +- cinder/volume/drivers/scality.py | 6 +++++- cinder/volume/flows/create_volume.py | 13 ++++++------- 6 files changed, 29 insertions(+), 24 deletions(-) diff --git a/cinder/tests/test_rbd.py b/cinder/tests/test_rbd.py index f9a6986b2..6d68b8198 100644 --- a/cinder/tests/test_rbd.py +++ b/cinder/tests/test_rbd.py @@ -474,10 +474,10 @@ class ManagedRBDTestCase(DriverTestCase): """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) @@ -528,12 +528,12 @@ class ManagedRBDTestCase(DriverTestCase): 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) @@ -543,12 +543,11 @@ class ManagedRBDTestCase(DriverTestCase): 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)) diff --git a/cinder/volume/driver.py b/cinder/volume/driver.py index ec7280879..e509fe405 100644 --- a/cinder/volume/driver.py +++ b/cinder/volume/driver.py @@ -326,9 +326,8 @@ class VolumeDriver(object): # 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'] @@ -348,13 +347,17 @@ class VolumeDriver(object): 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 """ diff --git a/cinder/volume/drivers/lvm.py b/cinder/volume/drivers/lvm.py index 6b5414297..552289f0e 100644 --- a/cinder/volume/drivers/lvm.py +++ b/cinder/volume/drivers/lvm.py @@ -263,7 +263,7 @@ class LVMVolumeDriver(driver.VolumeDriver): 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): diff --git a/cinder/volume/drivers/rbd.py b/cinder/volume/drivers/rbd.py index 91c132f1f..3cbde15aa 100644 --- a/cinder/volume/drivers/rbd.py +++ b/cinder/volume/drivers/rbd.py @@ -519,7 +519,7 @@ class RBDDriver(driver.VolumeDriver): 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) diff --git a/cinder/volume/drivers/scality.py b/cinder/volume/drivers/scality.py index abf2fcda5..0b62b41ca 100644 --- a/cinder/volume/drivers/scality.py +++ b/cinder/volume/drivers/scality.py @@ -246,13 +246,17 @@ class ScalityDriver(driver.VolumeDriver): 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 """ diff --git a/cinder/volume/flows/create_volume.py b/cinder/volume/flows/create_volume.py index 702254553..0d7f49703 100644 --- a/cinder/volume/flows/create_volume.py +++ b/cinder/volume/flows/create_volume.py @@ -1213,11 +1213,10 @@ class CreateVolumeFromSpecTask(CinderTask): 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, @@ -1317,8 +1316,8 @@ class CreateVolumeFromSpecTask(CinderTask): # 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 -- 2.45.2