summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYAMADA Hideki <yamada.hideki@lab.ntt.co.jp>2015-03-04 18:11:23 +0000
committerYAMADA Hideki <yamada.hideki@lab.ntt.co.jp>2015-04-07 04:56:20 +0000
commitde864b55cb495d74fa13c4a70ed42e623bbe3f71 (patch)
treec6a5cb0ec99af37f01d9ebdf13194e17757d9b61
parentaf79f87b9ee97f8ae56d97b6423c884889aec415 (diff)
downloadcinder-de864b55cb495d74fa13c4a70ed42e623bbe3f71.tar.gz
Add missing copy_volume_to_image method to Sheepdog driver
Copy Volume to Image feature is required since Havana release. The Sheepdog driver has not implemented it. Change-Id: I940095be7ed3721cc8f1bafde821fbb420d305d0 Closes-Bug: #1426431
-rw-r--r--cinder/tests/test_sheepdog.py43
-rw-r--r--cinder/volume/drivers/sheepdog.py20
2 files changed, 63 insertions, 0 deletions
diff --git a/cinder/tests/test_sheepdog.py b/cinder/tests/test_sheepdog.py
index 3d0e5365a..b0e138911 100644
--- a/cinder/tests/test_sheepdog.py
+++ b/cinder/tests/test_sheepdog.py
@@ -137,6 +137,49 @@ class SheepdogTestCase(test.TestCase):
'size': 1},
FakeImageService(), None)
+ def test_copy_volume_to_image(self):
+ fake_context = {}
+ fake_volume = {'name': 'volume-00000001'}
+ fake_image_service = mock.Mock()
+ fake_image_service_update = mock.Mock()
+ fake_image_meta = {'id': '10958016-e196-42e3-9e7f-5d8927ae3099'}
+
+ patch = mock.patch.object
+ with patch(self.driver, '_try_execute') as fake_try_execute:
+ with patch(fake_image_service,
+ 'update') as fake_image_service_update:
+ self.driver.copy_volume_to_image(fake_context,
+ fake_volume,
+ fake_image_service,
+ fake_image_meta)
+
+ expected_cmd = ('qemu-img',
+ 'convert',
+ '-f', 'raw',
+ '-t', 'none',
+ '-O', 'raw',
+ 'sheepdog:%s' % fake_volume['name'],
+ mock.ANY)
+ fake_try_execute.assert_called_once_with(*expected_cmd)
+ fake_image_service_update.assert_called_once_with(
+ fake_context, fake_image_meta['id'], mock.ANY, mock.ANY)
+
+ def test_copy_volume_to_image_nonexistent_volume(self):
+ fake_context = {}
+ fake_volume = {
+ 'name': 'nonexistent-volume-82c4539e-c2a5-11e4-a293-0aa186c60fe0'}
+ fake_image_service = mock.Mock()
+ fake_image_meta = {'id': '10958016-e196-42e3-9e7f-5d8927ae3099'}
+
+ # The command is expected to fail, so we don't want to retry it.
+ self.driver._try_execute = self.driver._execute
+
+ args = (fake_context, fake_volume, fake_image_service, fake_image_meta)
+ expected_errors = (processutils.ProcessExecutionError, OSError)
+ self.assertRaises(expected_errors,
+ self.driver.copy_volume_to_image,
+ *args)
+
def test_create_cloned_volume(self):
src_vol = {
'project_id': 'testprjid',
diff --git a/cinder/volume/drivers/sheepdog.py b/cinder/volume/drivers/sheepdog.py
index 479b0659a..43ec85d9d 100644
--- a/cinder/volume/drivers/sheepdog.py
+++ b/cinder/volume/drivers/sheepdog.py
@@ -28,6 +28,7 @@ from oslo_utils import units
from cinder import exception
from cinder.i18n import _, _LE
from cinder.image import image_utils
+from cinder.openstack.common import fileutils
from cinder.volume import driver
@@ -181,6 +182,25 @@ class SheepdogDriver(driver.VolumeDriver):
'raw')
self._resize(volume)
+ def copy_volume_to_image(self, context, volume, image_service, image_meta):
+ """Copy the volume to the specified image."""
+ image_id = image_meta['id']
+ with image_utils.temporary_file() as tmp:
+ # image_utils.convert_image doesn't support "sheepdog:" source,
+ # so we use the qemu-img directly.
+ # Sheepdog volume is always raw-formatted.
+ cmd = ('qemu-img',
+ 'convert',
+ '-f', 'raw',
+ '-t', 'none',
+ '-O', 'raw',
+ 'sheepdog:%s' % volume['name'],
+ tmp)
+ self._try_execute(*cmd)
+
+ with fileutils.file_open(tmp, 'rb') as image_file:
+ image_service.update(context, image_id, {}, image_file)
+
def create_snapshot(self, snapshot):
"""Create a sheepdog snapshot."""
self._try_execute('qemu-img', 'snapshot', '-c', snapshot['name'],