From beef71d0f8edf5770f8fe95d85e5ea230ddd6f10 Mon Sep 17 00:00:00 2001 From: Tomoki Sekiyama Date: Tue, 28 Jul 2015 14:08:15 -0400 Subject: [PATCH] Fix exception on uploading a volume to image with glance v2 API This fixes an exception on uploading a volume to image when the glance v2 api is enabled. Also, this adds the unit tests for updating metadata and data both with glance API v1 and v2. Change-Id: Id70eff82837c0af1f033a2bb749ef367cd9e32fb Closes-bug: #1478737 --- cinder/image/glance.py | 4 ++-- cinder/tests/unit/glance/stubs.py | 30 ++++++++++++++++++++++---- cinder/tests/unit/image/test_glance.py | 18 ++++++++++++++++ 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/cinder/image/glance.py b/cinder/image/glance.py index c4a1afe2de5..b1fc25e69da 100644 --- a/cinder/image/glance.py +++ b/cinder/image/glance.py @@ -323,8 +323,8 @@ class GlanceImageService(object): try: # NOTE(dosaboy): the v2 api separates update from upload if data and CONF.glance_api_version > 1: - image_meta = self._client.call(context, 'upload', image_id, - image_meta['data']) + self._client.call(context, 'upload', image_id, data) + image_meta = self._client.call(context, 'get', image_id) else: image_meta = self._client.call(context, 'update', image_id, **image_meta) diff --git a/cinder/tests/unit/glance/stubs.py b/cinder/tests/unit/glance/stubs.py index 6094496c4d6..291687c3a64 100644 --- a/cinder/tests/unit/glance/stubs.py +++ b/cinder/tests/unit/glance/stubs.py @@ -34,9 +34,13 @@ class StubGlanceClient(object): # NOTE(bcwaldon): HACK to get client.images.* to work self.images = lambda: None - for fn in ('list', 'get', 'data', 'create', 'update', 'delete'): + for fn in ('list', 'get', 'data', 'create', 'update', 'upload', + 'delete'): setattr(self.images, fn, getattr(self, fn)) + self.schemas = lambda: None + setattr(self.schemas, 'get', getattr(self, 'schemas_get')) + # TODO(bcwaldon): implement filters def list(self, filters=None, marker=None, limit=30): if marker is None: @@ -58,8 +62,11 @@ class StubGlanceClient(object): raise glanceclient.exc.NotFound(image_id) def data(self, image_id): - self.get(image_id) - return [] + image = self.get(image_id) + if getattr(image, 'size', 0): + return ['*' * image.size] + else: + return [] def create(self, **metadata): metadata['created_at'] = NOW_GLANCE_FORMAT @@ -81,7 +88,10 @@ class StubGlanceClient(object): for i, image in enumerate(self._images): if image.id == str(image_id): for k, v in metadata.items(): - setattr(self._images[i], k, v) + if k == 'data': + setattr(self._images[i], 'size', len(v)) + else: + setattr(self._images[i], k, v) return self._images[i] raise glanceclient.exc.NotFound(image_id) @@ -92,6 +102,18 @@ class StubGlanceClient(object): return raise glanceclient.exc.NotFound(image_id) + def upload(self, image_id, data): + for i, image in enumerate(self._images): + if image.id == image_id: + setattr(self._images[i], 'size', len(data)) + return + raise glanceclient.exc.NotFound(image_id) + + def schemas_get(self, schema_name): + if schema_name != 'image': + raise glanceclient.exc.NotFound() + return FakeSchema() + class FakeImage(object): def __init__(self, metadata): diff --git a/cinder/tests/unit/image/test_glance.py b/cinder/tests/unit/image/test_glance.py index c53c3aae890..71fd0f3141c 100644 --- a/cinder/tests/unit/image/test_glance.py +++ b/cinder/tests/unit/image/test_glance.py @@ -334,6 +334,24 @@ class TestGlanceImageService(test.TestCase): new_image_data = self.service.show(self.context, image_id) self.assertEqual('new image name', new_image_data['name']) + def test_update_v2(self): + self.flags(glance_api_version=2) + self.test_update() + + def test_update_with_data(self): + fixture = self._make_fixture(name='test image') + image = self.service.create(self.context, fixture) + image_id = image['id'] + data = '*' * 256 + self.service.update(self.context, image_id, fixture, data=data) + + new_image_data = self.service.show(self.context, image_id) + self.assertEqual(256, new_image_data['size']) + + def test_update_with_data_v2(self): + self.flags(glance_api_version=2) + self.test_update_with_data() + def test_delete(self): fixture1 = self._make_fixture(name='test image 1') fixture2 = self._make_fixture(name='test image 2')