summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Yeoh <cyeoh@au1.ibm.com>2013-04-18 00:02:53 +0930
committerChris Yeoh <cyeoh@au1.ibm.com>2013-04-18 00:02:53 +0930
commita977294b86287ebefba6eecb48d70166b1daf0f2 (patch)
treec4574488d9594cd5cb9f96dfc80beb72ae8943a1
parent964df95013fe65d38b3675592ae02249e93d2bc5 (diff)
downloadnova-a977294b86287ebefba6eecb48d70166b1daf0f2.tar.gz
nova-a977294b86287ebefba6eecb48d70166b1daf0f2.tar.xz
nova-a977294b86287ebefba6eecb48d70166b1daf0f2.zip
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
-rw-r--r--nova/image/s3.py16
-rw-r--r--nova/tests/image/test_s3.py37
2 files changed, 52 insertions, 1 deletions
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)