summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Tran <jtran@attinteractive.com>2011-06-07 01:30:59 +0000
committerTarmac <>2011-06-07 01:30:59 +0000
commita94992f199edd37ae3efd68c618b19c2ebab1a88 (patch)
treec7bd57ce7e4134cb8517cf1fa81b6c78e043fd68
parent90d6bf769dba648bb17cb2f6588fc1e65e325f37 (diff)
parent81099d63d6ff30b21116f7f0e5c782abadf0ab90 (diff)
downloadnova-a94992f199edd37ae3efd68c618b19c2ebab1a88.tar.gz
nova-a94992f199edd37ae3efd68c618b19c2ebab1a88.tar.xz
nova-a94992f199edd37ae3efd68c618b19c2ebab1a88.zip
run_instances will check image for 'available' status before attempting to create a new instance
-rw-r--r--nova/api/ec2/cloud.py11
-rw-r--r--nova/tests/test_cloud.py52
2 files changed, 58 insertions, 5 deletions
diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py
index b7a9a8633..ac73cd595 100644
--- a/nova/api/ec2/cloud.py
+++ b/nova/api/ec2/cloud.py
@@ -895,6 +895,17 @@ class CloudController(object):
if kwargs.get('ramdisk_id'):
ramdisk = self._get_image(context, kwargs['ramdisk_id'])
kwargs['ramdisk_id'] = ramdisk['id']
+ image = self._get_image(context, kwargs['image_id'])
+ if not image:
+ raise exception.ImageNotFound(image_id=kwargs['image_id'])
+ try:
+ available = (image['properties']['image_state'] == 'available')
+ except KeyError:
+ available = False
+
+ if not available:
+ raise exception.ApiError(_('Image must be available'))
+
instances = self.compute_api.create(context,
instance_type=instance_types.get_instance_type_by_name(
kwargs.get('instance_type', None)),
diff --git a/nova/tests/test_cloud.py b/nova/tests/test_cloud.py
index 1bf1271c4..a58e8bc39 100644
--- a/nova/tests/test_cloud.py
+++ b/nova/tests/test_cloud.py
@@ -26,17 +26,16 @@ from eventlet import greenthread
from nova import context
from nova import crypto
from nova import db
+from nova import exception
from nova import flags
from nova import log as logging
from nova import rpc
from nova import test
from nova import utils
-from nova import exception
from nova.auth import manager
from nova.api.ec2 import cloud
from nova.api.ec2 import ec2utils
from nova.image import local
-from nova.exception import NotFound
FLAGS = flags.FLAGS
@@ -68,7 +67,7 @@ class CloudTestCase(test.TestCase):
def fake_show(meh, context, id):
return {'id': 1, 'properties': {'kernel_id': 1, 'ramdisk_id': 1,
- 'type': 'machine'}}
+ 'type': 'machine', 'image_state': 'available'}}
self.stubs.Set(local.LocalImageService, 'show', fake_show)
self.stubs.Set(local.LocalImageService, 'show_by_name', fake_show)
@@ -290,7 +289,7 @@ class CloudTestCase(test.TestCase):
'type': 'machine'}}]
def fake_show_none(meh, context, id):
- raise NotFound
+ raise exception.ImageNotFound(image_id='bad_image_id')
self.stubs.Set(local.LocalImageService, 'detail', fake_detail)
# list all
@@ -308,7 +307,7 @@ class CloudTestCase(test.TestCase):
self.stubs.UnsetAll()
self.stubs.Set(local.LocalImageService, 'show', fake_show_none)
self.stubs.Set(local.LocalImageService, 'show_by_name', fake_show_none)
- self.assertRaises(NotFound, describe_images,
+ self.assertRaises(exception.ImageNotFound, describe_images,
self.context, ['ami-fake'])
def test_describe_image_attribute(self):
@@ -445,6 +444,49 @@ class CloudTestCase(test.TestCase):
self._create_key('test')
self.cloud.delete_key_pair(self.context, 'test')
+ def test_run_instances(self):
+ kwargs = {'image_id': FLAGS.default_image,
+ 'instance_type': FLAGS.default_instance_type,
+ 'max_count': 1}
+ run_instances = self.cloud.run_instances
+ result = run_instances(self.context, **kwargs)
+ instance = result['instancesSet'][0]
+ self.assertEqual(instance['imageId'], 'ami-00000001')
+ self.assertEqual(instance['displayName'], 'Server 1')
+ self.assertEqual(instance['instanceId'], 'i-00000001')
+ self.assertEqual(instance['instanceState']['name'], 'networking')
+ self.assertEqual(instance['instanceType'], 'm1.small')
+
+ def test_run_instances_image_state_none(self):
+ kwargs = {'image_id': FLAGS.default_image,
+ 'instance_type': FLAGS.default_instance_type,
+ 'max_count': 1}
+ run_instances = self.cloud.run_instances
+
+ def fake_show_no_state(self, context, id):
+ return {'id': 1, 'properties': {'kernel_id': 1, 'ramdisk_id': 1,
+ 'type': 'machine'}}
+
+ self.stubs.UnsetAll()
+ self.stubs.Set(local.LocalImageService, 'show', fake_show_no_state)
+ self.assertRaises(exception.ApiError, run_instances,
+ self.context, **kwargs)
+
+ def test_run_instances_image_state_invalid(self):
+ kwargs = {'image_id': FLAGS.default_image,
+ 'instance_type': FLAGS.default_instance_type,
+ 'max_count': 1}
+ run_instances = self.cloud.run_instances
+
+ def fake_show_decrypt(self, context, id):
+ return {'id': 1, 'properties': {'kernel_id': 1, 'ramdisk_id': 1,
+ 'type': 'machine', 'image_state': 'decrypting'}}
+
+ self.stubs.UnsetAll()
+ self.stubs.Set(local.LocalImageService, 'show', fake_show_decrypt)
+ self.assertRaises(exception.ApiError, run_instances,
+ self.context, **kwargs)
+
def test_terminate_instances(self):
inst1 = db.instance_create(self.context, {'reservation_id': 'a',
'image_ref': 1,