From a977294b86287ebefba6eecb48d70166b1daf0f2 Mon Sep 17 00:00:00 2001 From: Chris Yeoh Date: Thu, 18 Apr 2013 00:02:53 +0930 Subject: Map internal S3 image state to EC2 API values Fixes the EC2 API so it maps internal S3 image state values to ones defined by the EC2 API rather than returning the internally used values. Fixes bug #1074904 Change-Id: Iabbda0e5fcbe4d572c76367c6f98d4bece050e73 --- nova/image/s3.py | 16 ++++++++++++++++ nova/tests/image/test_s3.py | 37 ++++++++++++++++++++++++++++++++++++- 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/nova/image/s3.py b/nova/image/s3.py index 100d80030..563864b91 100644 --- a/nova/image/s3.py +++ b/nova/image/s3.py @@ -73,6 +73,16 @@ CONF.import_opt('my_ip', 'nova.netconf') class S3ImageService(object): """Wraps an existing image service to support s3 based register.""" + # translate our internal state to states valid by the EC2 API documentation + image_state_map = {'downloading': 'pending', + 'failed_download': 'failed', + 'decrypting': 'pending', + 'failed_decrypt': 'failed', + 'untarring': 'pending', + 'failed_untar': 'failed', + 'uploading': 'pending', + 'failed_upload': 'failed', + 'available': 'available'} def __init__(self, service=None, *args, **kwargs): self.cert_rpcapi = nova.cert.rpcapi.CertAPI() @@ -101,6 +111,12 @@ class S3ImageService(object): image_id = ec2utils.glance_id_to_id(context, image_uuid) image_copy['properties'][prop] = image_id + try: + image_copy['properties']['image_state'] = self.image_state_map[ + image['properties']['image_state']] + except (KeyError, ValueError): + pass + return image_copy def _translate_id_to_uuid(self, context, image): diff --git a/nova/tests/image/test_s3.py b/nova/tests/image/test_s3.py index 615a89b29..1775fe131 100644 --- a/nova/tests/image/test_s3.py +++ b/nova/tests/image/test_s3.py @@ -88,9 +88,13 @@ class TestS3ImageService(test.TestCase): self.context = context.RequestContext(None, None) self.useFixture(fixtures.FakeLogger('boto')) - # set up one fixture to test shows, should have id '1' + # set up 3 fixtures to test shows, should have id '1', '2', and '3' nova.db.api.s3_image_create(self.context, '155d900f-4e14-4e4c-a73d-069cbf4541e6') + nova.db.api.s3_image_create(self.context, + 'a2459075-d96c-40d5-893e-577ff92e721c') + nova.db.api.s3_image_create(self.context, + '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6') fake.stub_out_image_service(self.stubs) self.image_service = s3.S3ImageService() @@ -120,6 +124,37 @@ class TestS3ImageService(test.TestCase): def test_show_translates_correctly(self): self.image_service.show(self.context, '1') + def test_show_translates_image_state_correctly(self): + def my_fake_show(self, context, image_id): + fake_state_map = { + '155d900f-4e14-4e4c-a73d-069cbf4541e6': 'downloading', + 'a2459075-d96c-40d5-893e-577ff92e721c': 'failed_decrypt', + '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6': 'available'} + return {'id': image_id, + 'name': 'fakeimage123456', + 'deleted_at': None, + 'deleted': False, + 'status': 'active', + 'is_public': False, + 'container_format': 'raw', + 'disk_format': 'raw', + 'size': '25165824', + 'properties': {'image_state': fake_state_map[image_id]}} + + # Override part of the fake image service as well just for + # this test so we can set the image_state to various values + # and test that S3ImageService does the correct mapping for + # us. We can't put fake bad or pending states in the real fake + # image service as it causes other tests to fail + self.stubs.Set(nova.tests.image.fake._FakeImageService, 'show', + my_fake_show) + ret_image = self.image_service.show(self.context, '1') + self.assertEqual(ret_image['properties']['image_state'], 'pending') + ret_image = self.image_service.show(self.context, '2') + self.assertEqual(ret_image['properties']['image_state'], 'failed') + ret_image = self.image_service.show(self.context, '3') + self.assertEqual(ret_image['properties']['image_state'], 'available') + def test_detail(self): self.image_service.detail(self.context) -- cgit