summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Kearney <josh@jk0.org>2011-08-11 17:10:25 -0500
committerJosh Kearney <josh@jk0.org>2011-08-11 17:10:25 -0500
commitb29bc97d5a69abe71dea5b9ff9dcfc65fcd59cc9 (patch)
tree8f2255023974f23c79edaa272405dbe9cedb1035
parentfe0bde67193ce76376e72a7263b89240a63722a8 (diff)
downloadnova-b29bc97d5a69abe71dea5b9ff9dcfc65fcd59cc9.tar.gz
nova-b29bc97d5a69abe71dea5b9ff9dcfc65fcd59cc9.tar.xz
nova-b29bc97d5a69abe71dea5b9ff9dcfc65fcd59cc9.zip
Check compressed image size and PEP8 cleanup.
-rw-r--r--nova/compute/manager.py40
-rw-r--r--nova/exception.py4
-rw-r--r--nova/tests/api/openstack/contrib/test_keypairs.py17
3 files changed, 59 insertions, 2 deletions
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index d38213083..1c3485342 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -321,10 +321,50 @@ class ComputeManager(manager.SchedulerDependentManager):
def _run_instance(self, context, instance_id, **kwargs):
"""Launch a new instance with specified options."""
+ def _check_image_size():
+ """Ensure image is smaller than the maximum size allowed by the
+ instance_type.
+
+ The image stored in Glance is potentially compressed, so we use two
+ checks to ensure that the size isn't exceeded:
+
+ 1) This one - checks compressed size, this a quick check to
+ eliminate any images which are obviously too large
+
+ 2) Check uncompressed size in nova.virt.xenapi.vm_utils. This
+ is a slower check since it requires uncompressing the entire
+ image, but is accurate because it reflects the image's
+ actual size.
+ """
+ image_href = instance['image_ref']
+ image_service, image_id = nova.image.get_image_service(image_href)
+ image_meta = image_service.show(context, image_id)
+ size_bytes = image_meta['size']
+
+ instance_type_id = instance['instance_type_id']
+ instance_type = self.db.instance_type_get(context,
+ instance_type_id)
+ allowed_size_gb = instance_type['local_gb']
+ allowed_size_bytes = allowed_size_gb * 1024 * 1024 * 1024
+
+ LOG.debug(_("image_id=%(image_id)d, image_size_bytes="
+ "%(size_bytes)d, allowed_size_bytes="
+ "%(allowed_size_bytes)d") % locals())
+
+ if size_bytes > allowed_size_bytes:
+ LOG.info(_("Image '%(image_id)d' size %(size_bytes)d exceeded"
+ " instance_type allowed size "
+ "%(allowed_size_bytes)d")
+ % locals())
+ raise exception.ImageTooLarge()
+
context = context.elevated()
instance = self.db.instance_get(context, instance_id)
if instance['name'] in self.driver.list_instances():
raise exception.Error(_("Instance has already been created"))
+
+ _check_image_size()
+
LOG.audit(_("instance %s: starting..."), instance_id,
context=context)
updates = {}
diff --git a/nova/exception.py b/nova/exception.py
index 0d60cb0bf..77ebf3c88 100644
--- a/nova/exception.py
+++ b/nova/exception.py
@@ -717,3 +717,7 @@ class CannotResizeToSameSize(NovaException):
class CannotResizeToSmallerSize(NovaException):
message = _("Resizing to a smaller size is not supported.")
+
+
+class ImageTooLarge(NovaException):
+ message = _("Image is larger than instance type allows")
diff --git a/nova/tests/api/openstack/contrib/test_keypairs.py b/nova/tests/api/openstack/contrib/test_keypairs.py
index c9dc34d65..cbc815b1a 100644
--- a/nova/tests/api/openstack/contrib/test_keypairs.py
+++ b/nova/tests/api/openstack/contrib/test_keypairs.py
@@ -28,6 +28,7 @@ def fake_keypair(name):
'fingerprint': 'FAKE_FINGERPRINT',
'name': name}
+
def db_key_pair_get_all_by_user(self, user_id):
return [fake_keypair('FAKE')]
@@ -78,7 +79,20 @@ class KeypairsTest(test.TestCase):
def test_keypair_import(self):
body = {'keypair': {'name': 'create_test',
- 'public_key': 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDBYIznAx9D7118Q1VKGpXy2HDiKyUTM8XcUuhQpo0srqb9rboUp4a9NmCwpWpeElDLuva707GOUnfaBAvHBwsRXyxHJjRaI6YQj2oLJwqvaSaWUbyT1vtryRqy6J3TecN0WINY71f4uymiMZP0wby4bKBcYnac8KiCIlvkEl0ETjkOGUq8OyWRmn7ljj5SESEUdBP0JnuTFKddWTU/wD6wydeJaUhBTqOlHn0kX1GyqoNTE1UEhcM5ZRWgfUZfTjVyDF2kGj3vJLCJtJ8LoGcj7YaN4uPg1rBle+izwE/tLonRrds+cev8p6krSSrxWOwBbHkXa6OciiJDvkRzJXzf'}}
+ 'public_key': 'ssh-rsa '
+ 'AAAAB3NzaC1yc2EAAAADAQABAAABAQDBY'
+ 'IznAx9D7118Q1VKGpXy2HDiKyUTM8XcUu'
+ 'hQpo0srqb9rboUp4a9NmCwpWpeElDLuva'
+ '707GOUnfaBAvHBwsRXyxHJjRaI6YQj2oL'
+ 'JwqvaSaWUbyT1vtryRqy6J3TecN0WINY7'
+ '1f4uymiMZP0wby4bKBcYnac8KiCIlvkEl'
+ '0ETjkOGUq8OyWRmn7ljj5SESEUdBP0Jnu'
+ 'TFKddWTU/wD6wydeJaUhBTqOlHn0kX1Gy'
+ 'qoNTE1UEhcM5ZRWgfUZfTjVyDF2kGj3vJ'
+ 'LCJtJ8LoGcj7YaN4uPg1rBle+izwE/tLo'
+ 'nRrds+cev8p6krSSrxWOwBbHkXa6OciiJ'
+ 'DvkRzJXzf'}}
+
req = webob.Request.blank('/v1.1/os-keypairs')
req.method = 'POST'
req.body = json.dumps(body)
@@ -96,4 +110,3 @@ class KeypairsTest(test.TestCase):
req.headers['Content-Type'] = 'application/json'
res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 202)
-