From edbfe4c78cca6c4dd8b8a164de86b1fa4c210ab9 Mon Sep 17 00:00:00 2001 From: Mate Lakat Date: Thu, 21 Feb 2013 17:10:42 +0000 Subject: [PATCH] XenAPINFS: Fix Volume always uploaded as vhd/ovf Fixes bug 1131291 copy_volume_to_image was always using the glance plugin to do the upload, and was ignoring the users request. Thus the image was always uploaded as vhd/ovf. This patch is using the image utils to fix the generic case. Change-Id: If12c3d175b3d4437305ac4d2f954a2a42ee3a3c1 --- cinder/tests/test_xenapi_sm.py | 92 ++++++++++++++++++++++++++++-- cinder/volume/drivers/xenapi/sm.py | 24 ++++++++ 2 files changed, 112 insertions(+), 4 deletions(-) diff --git a/cinder/tests/test_xenapi_sm.py b/cinder/tests/test_xenapi_sm.py index 9a07aba0e..04f09bfc0 100644 --- a/cinder/tests/test_xenapi_sm.py +++ b/cinder/tests/test_xenapi_sm.py @@ -36,6 +36,11 @@ class MockContext(object): ctxt.auth_token = auth_token +@contextlib.contextmanager +def simple_context(value): + yield value + + def get_configured_driver(server='ignore_server', path='ignore_path'): configuration = mox.MockObject(conf.Configuration) configuration.xenapi_nfs_server = server @@ -264,6 +269,89 @@ class DriverTestCase(unittest.TestCase): drv.delete_snapshot(snapshot) mock.VerifyAll() + def test_copy_volume_to_image_xenserver_case(self): + mock, drv = self._setup_mock_driver( + 'server', 'serverpath', '/var/run/sr-mount') + + mock.StubOutWithMock(drv, '_use_glance_plugin_to_upload_volume') + mock.StubOutWithMock(driver, 'is_xenserver_format') + context = MockContext('token') + + driver.is_xenserver_format('image_meta').AndReturn(True) + + drv._use_glance_plugin_to_upload_volume( + context, 'volume', 'image_service', 'image_meta').AndReturn( + 'result') + mock.ReplayAll() + + result = drv.copy_volume_to_image( + context, "volume", "image_service", "image_meta") + self.assertEquals('result', result) + + mock.VerifyAll() + + def test_copy_volume_to_image_non_xenserver_case(self): + mock, drv = self._setup_mock_driver( + 'server', 'serverpath', '/var/run/sr-mount') + + mock.StubOutWithMock(drv, '_use_image_utils_to_upload_volume') + mock.StubOutWithMock(driver, 'is_xenserver_format') + context = MockContext('token') + + driver.is_xenserver_format('image_meta').AndReturn(False) + + drv._use_image_utils_to_upload_volume( + context, 'volume', 'image_service', 'image_meta').AndReturn( + 'result') + mock.ReplayAll() + + result = drv.copy_volume_to_image( + context, "volume", "image_service", "image_meta") + self.assertEquals('result', result) + + mock.VerifyAll() + + def test_use_image_utils_to_upload_volume(self): + mock, drv = self._setup_mock_driver( + 'server', 'serverpath', '/var/run/sr-mount') + + volume = dict(provider_location='sr-uuid/vdi-uuid') + context = MockContext('token') + + mock.StubOutWithMock(driver.image_utils, 'upload_volume') + + drv.nfs_ops.volume_attached_here( + 'server', 'serverpath', 'sr-uuid', 'vdi-uuid', True).AndReturn( + simple_context('device')) + + driver.image_utils.upload_volume( + context, 'image_service', 'image_meta', 'device') + + mock.ReplayAll() + drv._use_image_utils_to_upload_volume( + context, volume, "image_service", "image_meta") + mock.VerifyAll() + + def test_use_glance_plugin_to_upload_volume(self): + mock, drv = self._setup_mock_driver( + 'server', 'serverpath', '/var/run/sr-mount') + + volume = dict(provider_location='sr-uuid/vdi-uuid') + context = MockContext('token') + + mock.StubOutWithMock(driver.glance, 'get_api_servers') + + driver.glance.get_api_servers().AndReturn((x for x in ['glancesrv'])) + + drv.nfs_ops.use_glance_plugin_to_upload_volume( + 'server', 'serverpath', 'sr-uuid', 'vdi-uuid', 'glancesrv', + 'image-id', 'token', '/var/run/sr-mount') + + mock.ReplayAll() + drv._use_glance_plugin_to_upload_volume( + context, volume, "image_service", {"id": "image-id"}) + mock.VerifyAll() + def test_copy_image_to_volume_xenserver_case(self): mock, drv = self._setup_mock_driver( 'server', 'serverpath', '/var/run/sr-mount') @@ -308,10 +396,6 @@ class DriverTestCase(unittest.TestCase): mock.StubOutWithMock(driver.image_utils, 'fetch_to_raw') - @contextlib.contextmanager - def simple_context(value): - yield value - drv.nfs_ops.volume_attached_here( 'server', 'serverpath', 'sr-uuid', 'vdi-uuid', False).AndReturn( simple_context('device')) diff --git a/cinder/volume/drivers/xenapi/sm.py b/cinder/volume/drivers/xenapi/sm.py index e77495875..cc93af096 100644 --- a/cinder/volume/drivers/xenapi/sm.py +++ b/cinder/volume/drivers/xenapi/sm.py @@ -204,6 +204,27 @@ class XenAPINFSDriver(driver.VolumeDriver): volume['size']) def copy_volume_to_image(self, context, volume, image_service, image_meta): + if is_xenserver_format(image_meta): + return self._use_glance_plugin_to_upload_volume( + context, volume, image_service, image_meta) + + return self._use_image_utils_to_upload_volume( + context, volume, image_service, image_meta) + + def _use_image_utils_to_upload_volume(self, context, volume, image_service, + image_meta): + sr_uuid, vdi_uuid = volume['provider_location'].split('/') + with self.nfs_ops.volume_attached_here(FLAGS.xenapi_nfs_server, + FLAGS.xenapi_nfs_serverpath, + sr_uuid, vdi_uuid, + True) as device: + image_utils.upload_volume(context, + image_service, + image_meta, + device) + + def _use_glance_plugin_to_upload_volume(self, context, volume, + image_service, image_meta): image_id = image_meta['id'] sr_uuid, vdi_uuid = volume['provider_location'].split('/') @@ -238,7 +259,10 @@ class XenAPINFSDriver(driver.VolumeDriver): def is_xenserver_image(context, image_service, image_id): image_meta = image_service.show(context, image_id) + return is_xenserver_format(image_meta) + +def is_xenserver_format(image_meta): return ( image_meta['disk_format'] == 'vhd' and image_meta['container_format'] == 'ovf' -- 2.45.2