Translate Glance and internal image statuses to valid EC2 states

Glance image statuses are not compatible with AWS EC2. Now they will be
translated to appropriated EC2 states.

Also following to Nova EC2, ec2api uses internal states to indicate
progress of image registration. These states must be translated to valid
EC2 states, but this had been forgotten when image operations was ported
to ec2api.

Change-Id: I3e4bdaa84e654ffe6f7a8ed0b1e461f161829d90
This commit is contained in:
Feodor Tersin 2015-09-04 16:04:49 +03:00
parent f7595283c1
commit 9ea493060f
2 changed files with 61 additions and 5 deletions

View File

@ -91,6 +91,13 @@ CONTAINER_TO_KIND = {'aki': 'aki',
IMAGE_TYPES = {'aki': 'kernel',
'ari': 'ramdisk',
'ami': 'machine'}
GLANCE_STATUS_TO_EC2 = {'queued': 'pending',
'saving': 'pending',
'active': 'available',
'killed': 'deregistered',
'pending_delete': 'deregistered',
'deleted': 'deregistered',
'deactivated': 'invalid'}
EPHEMERAL_PREFIX_LEN = len('ephemeral')
@ -532,11 +539,11 @@ def _format_image(context, image, os_image, images_dict, ids_dict,
}
if 'description' in image:
ec2_image['description'] = image['description']
state = os_image.status
# NOTE(vish): fallback status if image_state isn't set
if state == 'active':
state = 'available'
ec2_image['imageState'] = os_image.properties.get('image_state', state)
state = GLANCE_STATUS_TO_EC2.get(os_image.status, 'error')
if state in ('available', 'pending'):
state = _s3_image_state_map.get(os_image.properties.get('image_state'),
state)
ec2_image['imageState'] = state
kernel_id = os_image.properties.get('kernel_id')
if kernel_id:
@ -692,6 +699,18 @@ ec2utils.register_auto_create_db_item_extension(
# NOTE(ft): following functions are copied from various parts of Nova
# translate our internal state to states valid by the EC2 API documentation
_s3_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 _s3_create(context, metadata):
"""Gets a manifest from s3 and makes an image."""
image_location = metadata['properties']['image_location'].lstrip('/')

View File

@ -482,6 +482,43 @@ class ImagePrivateTestCase(test_base.BaseTestCase):
self.assertEqual('instance-store', image['rootDeviceType'])
self.assertNotIn('blockDeviceMapping', image)
# check Glance status translation
os_image = fakes.OSImage({'id': fakes.ID_OS_IMAGE_1})
def check_status_translation(status, expected):
os_image.status = status
image = image_api._format_image(
'fake_context', fakes.DB_IMAGE_1, os_image, None, None)
self.assertEqual(expected, image['imageState'],
"Wrong '%s' Glance status translation" % status)
check_status_translation('queued', 'pending')
check_status_translation('saving', 'pending')
check_status_translation('active', 'available')
check_status_translation('killed', 'deregistered')
check_status_translation('pending_delete', 'deregistered')
check_status_translation('deleted', 'deregistered')
check_status_translation('deactivated', 'invalid')
check_status_translation('unknown-status', 'error')
# check internal state translation
os_image.status = 'queued'
def check_state_translation(state, expected):
os_image.properties['image_state'] = state
image = image_api._format_image(
'fake_context', fakes.DB_IMAGE_1, os_image, None, None)
self.assertEqual(expected, image['imageState'],
"Wrong '%s' internal state translation" % state)
for state in ('downloading', 'decrypting', 'untarring', 'uploading'):
check_state_translation(state, 'pending')
for state in ('failed_download', 'failed_decrypt', 'failed_untar',
'failed_upload'):
check_state_translation(state, 'failed')
os_image.status = 'active'
check_state_translation('available', 'available')
check_state_translation('unknown-state', 'available')
@mock.patch('ec2api.db.api.IMPL')
def test_format_mappings(self, db_api):
# check virtual mapping formatting