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:
parent
f7595283c1
commit
9ea493060f
@ -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('/')
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user