diff options
| author | Rick Harris <rick.harris@rackspace.com> | 2011-03-25 04:41:47 +0000 |
|---|---|---|
| committer | Rick Harris <rick.harris@rackspace.com> | 2011-03-25 04:41:47 +0000 |
| commit | ccf4727ca16d7a67c6a35950ab378ab4615dbdad (patch) | |
| tree | 0431f395f4410c59adb3800ca2c6625447d9bf3b | |
| parent | e26e360106c2aeb468be90de609caaf03e1dab43 (diff) | |
| download | nova-ccf4727ca16d7a67c6a35950ab378ab4615dbdad.tar.gz nova-ccf4727ca16d7a67c6a35950ab378ab4615dbdad.tar.xz nova-ccf4727ca16d7a67c6a35950ab378ab4615dbdad.zip | |
disk_format is now an ImageService property
| -rw-r--r-- | nova/api/openstack/servers.py | 34 | ||||
| -rw-r--r-- | nova/tests/api/openstack/test_servers.py | 57 |
2 files changed, 78 insertions, 13 deletions
diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index 144d14536..ac9e29f07 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -502,33 +502,41 @@ class Controller(wsgi.Controller): return dict(actions=actions) def _get_kernel_ramdisk_from_image(self, req, image_id): - """Retrevies kernel and ramdisk IDs from Glance - - Only 'machine' (ami) type use kernel and ramdisk outside of the - image. + """Fetch an image from the ImageService, then if present, return the + associated kernel and ramdisk image IDs. """ - # FIXME(sirp): Since we're retrieving the kernel_id from an - # image_property, this means only Glance is supported. - # The BaseImageService needs to expose a consistent way of accessing - # kernel_id and ramdisk_id - image = self._image_service.show(req.environ['nova.context'], image_id) + context = req.environ['nova.context'] + image_meta = self._image_service.show(context, image_id) + # NOTE(sirp): extracted to a separate method to aid unit-testing, the + # new method doesn't need a request obj or an ImageService stub + kernel_id, ramdisk_id = self._do_get_kernel_ramdisk_from_image( + image_meta) + return kernel_id, ramdisk_id - if image['status'] != 'active': + @staticmethod + def _do_get_kernel_ramdisk_from_image(image_meta): + """Given an ImageService image_meta, return kernel and ramdisk image + ids if present. + + This is only valid for `ami` style images. + """ + image_id = image_meta['id'] + if image_meta['status'] != 'active': raise exception.Invalid( _("Cannot build from image %(image_id)s, status not active") % locals()) - if image['disk_format'] != 'ami': + if image_meta['properties']['disk_format'] != 'ami': return None, None try: - kernel_id = image['properties']['kernel_id'] + kernel_id = image_meta['properties']['kernel_id'] except KeyError: raise exception.NotFound( _("Kernel not found for image %(image_id)s") % locals()) try: - ramdisk_id = image['properties']['ramdisk_id'] + ramdisk_id = image_meta['properties']['ramdisk_id'] except KeyError: raise exception.NotFound( _("Ramdisk not found for image %(image_id)s") % locals()) diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py index c48cc5179..3c117f10c 100644 --- a/nova/tests/api/openstack/test_servers.py +++ b/nova/tests/api/openstack/test_servers.py @@ -26,6 +26,7 @@ import webob from nova import context from nova import db +from nova import exception from nova import flags from nova import test import nova.api.openstack @@ -1260,3 +1261,59 @@ class TestServerInstanceCreation(test.TestCase): server = dom.childNodes[0] self.assertEquals(server.nodeName, 'server') self.assertTrue(server.getAttribute('adminPass').startswith('fake')) + + +class TestGetKernelRamdiskFromImage(test.TestCase): + """ + If we're building from an AMI-style image, we need to be able to fetch the + kernel and ramdisk associated with the machine image. This information is + stored with the image metadata and return via the ImageService. + + These tests ensure that we parse the metadata return the ImageService + correctly and that we handle failure modes appropriately. + """ + + def test_status_not_active(self): + """We should only allow fetching of kernel and ramdisk information if + we have a 'fully-formed' image, aka 'active' + """ + image_meta = {'id': 1, 'status': 'queued'} + self.assertRaises(exception.Invalid, self._get_k_r, image_meta) + + def test_not_ami(self): + """Anything other than ami should return no kernel and no ramdisk""" + image_meta = {'id': 1, 'status': 'active', + 'properties': {'disk_format': 'vhd'}} + kernel_id, ramdisk_id = self._get_k_r(image_meta) + self.assertEqual(kernel_id, None) + self.assertEqual(ramdisk_id, None) + + def test_ami_no_kernel(self): + """If an ami is missing a kernel it should raise NotFound""" + image_meta = {'id': 1, 'status': 'active', + 'properties': {'disk_format': 'ami', 'ramdisk_id': 1}} + self.assertRaises(exception.NotFound, self._get_k_r, image_meta) + + def test_ami_no_ramdisk(self): + """If an ami is missing a ramdisk it should raise NotFound""" + image_meta = {'id': 1, 'status': 'active', + 'properties': {'disk_format': 'ami', 'kernel_id': 1}} + self.assertRaises(exception.NotFound, self._get_k_r, image_meta) + + def test_ami_kernel_ramdisk_present(self): + """Return IDs if both kernel and ramdisk are present""" + image_meta = {'id': 1, 'status': 'active', + 'properties': {'disk_format': 'ami', 'kernel_id': 1, + 'ramdisk_id': 2}} + kernel_id, ramdisk_id = self._get_k_r(image_meta) + self.assertEqual(kernel_id, 1) + self.assertEqual(ramdisk_id, 2) + + @staticmethod + def _get_k_r(image_meta): + """Rebinding function to a shorter name for convenience""" + kernel_id, ramdisk_id = \ + servers.Controller._do_get_kernel_ramdisk_from_image(image_meta) + return kernel_id, ramdisk_id + + |
