From c26be56d63a9d263ea8632514be03607713c754d Mon Sep 17 00:00:00 2001 From: Dan Prince Date: Fri, 27 May 2011 15:48:40 -0400 Subject: Glance client updates for xenapi and vmware API to work with image refs. --- nova/image/__init__.py | 42 +++++++++++++++++++++++++++--------- nova/tests/glance/stubs.py | 12 +++++++---- nova/tests/test_vmwareapi.py | 5 ++--- nova/tests/test_xenapi.py | 29 +++++++++++-------------- nova/tests/vmwareapi/db_fakes.py | 2 +- nova/virt/vmwareapi/vmops.py | 12 +++++------ nova/virt/vmwareapi/vmware_images.py | 16 ++++++-------- nova/virt/xenapi/vm_utils.py | 14 ++++++------ nova/virt/xenapi/vmops.py | 2 +- 9 files changed, 78 insertions(+), 56 deletions(-) (limited to 'nova') diff --git a/nova/image/__init__.py b/nova/image/__init__.py index 9b9108bd2..011d79d61 100644 --- a/nova/image/__init__.py +++ b/nova/image/__init__.py @@ -18,16 +18,16 @@ from urlparse import urlparse - from nova import exception -import nova.image.glance -from nova.utils import import_class +from nova import utils from nova import flags - FLAGS = flags.FLAGS +GlanceClient = utils.import_class('glance.client.Client') + + def _parse_image_ref(image_href): """Parse an image href into composite parts. @@ -43,10 +43,36 @@ def _parse_image_ref(image_href): def get_default_image_service(): - ImageService = import_class(FLAGS.image_service) + ImageService = utils.import_class(FLAGS.image_service) return ImageService() +def get_glance_client(image_href): + """Get the correct glance client and id for the given image_href. + + The image_href param can be an href of the form + http://myglanceserver:9292/images/42, or just an int such as 42. If the + image_href is an int, then flags are used to create the default + glance client. + + :param image_href: image ref/id for an image + :returns: a tuple of the form (glance_client, image_id) + + """ + image_href = image_href or 0 + if str(image_href).isdigit(): + glance_client = GlanceClient(FLAGS.glance_host, FLAGS.glance_port) + return (glance_client, int(image_href)) + + try: + (image_id, host, port) = _parse_image_ref(image_href) + except: + raise exception.InvalidImageRef(image_href=image_href) + glance_client = GlanceClient(host, port) + #glance_client = client.Client(host, port) + return (glance_client, image_id) + + def get_image_service(image_href): """Get the proper image_service and id for the given image_href. @@ -62,10 +88,6 @@ def get_image_service(image_href): if str(image_href).isdigit(): return (get_default_image_service(), int(image_href)) - try: - (image_id, host, port) = _parse_image_ref(image_href) - except: - raise exception.InvalidImageRef(image_href=image_href) - glance_client = nova.image.glance.GlanceClient(host, port) + (glance_client, image_id) = get_glance_client(image_href) image_service = nova.image.glance.GlanceImageService(glance_client) return (image_service, image_id) diff --git a/nova/tests/glance/stubs.py b/nova/tests/glance/stubs.py index 5872552ec..8611fef29 100644 --- a/nova/tests/glance/stubs.py +++ b/nova/tests/glance/stubs.py @@ -16,13 +16,17 @@ import StringIO -import glance.client +from nova import images -def stubout_glance_client(stubs, cls): + +def get_mock_glance_client(): + return FakeGlance() + + +def stubout_glance_client(stubs): """Stubs out glance.client.Client""" - stubs.Set(glance.client, 'Client', - lambda *args, **kwargs: cls(*args, **kwargs)) + stubs.Set(images, 'get_glance_client', get_mock_glance_client) class FakeGlance(object): diff --git a/nova/tests/test_vmwareapi.py b/nova/tests/test_vmwareapi.py index 22b66010a..e5ebd1600 100644 --- a/nova/tests/test_vmwareapi.py +++ b/nova/tests/test_vmwareapi.py @@ -55,8 +55,7 @@ class VMWareAPIVMTestCase(test.TestCase): vmwareapi_fake.reset() db_fakes.stub_out_db_instance_api(self.stubs) stubs.set_stubs(self.stubs) - glance_stubs.stubout_glance_client(self.stubs, - glance_stubs.FakeGlance) + glance_stubs.stubout_glance_client(self.stubs) self.conn = vmwareapi_conn.get_connection(False) def _create_instance_in_the_db(self): @@ -64,7 +63,7 @@ class VMWareAPIVMTestCase(test.TestCase): 'id': 1, 'project_id': self.project.id, 'user_id': self.user.id, - 'image_id': "1", + 'image_ref': "1", 'kernel_id': "1", 'ramdisk_id': "1", 'instance_type': 'm1.large', diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py index 18a267896..56e1e47af 100644 --- a/nova/tests/test_xenapi.py +++ b/nova/tests/test_xenapi.py @@ -79,7 +79,7 @@ class XenAPIVolumeTestCase(test.TestCase): self.values = {'id': 1, 'project_id': 'fake', 'user_id': 'fake', - 'image_id': 1, + 'image_ref': 1, 'kernel_id': 2, 'ramdisk_id': 3, 'instance_type_id': '3', # m1.large @@ -193,8 +193,7 @@ class XenAPIVMTestCase(test.TestCase): stubs.stubout_is_vdi_pv(self.stubs) self.stubs.Set(VMOps, 'reset_network', reset_network) stubs.stub_out_vm_methods(self.stubs) - glance_stubs.stubout_glance_client(self.stubs, - glance_stubs.FakeGlance) + glance_stubs.stubout_glance_client(self.stubs) fake_utils.stub_out_utils_execute(self.stubs) self.context = context.RequestContext('fake', 'fake', False) self.conn = xenapi_conn.get_connection(False) @@ -207,7 +206,7 @@ class XenAPIVMTestCase(test.TestCase): 'id': id, 'project_id': proj, 'user_id': user, - 'image_id': 1, + 'image_ref': 1, 'kernel_id': 2, 'ramdisk_id': 3, 'instance_type_id': '3', # m1.large @@ -351,14 +350,14 @@ class XenAPIVMTestCase(test.TestCase): self.assertEquals(self.vm['HVM_boot_params'], {}) self.assertEquals(self.vm['HVM_boot_policy'], '') - def _test_spawn(self, image_id, kernel_id, ramdisk_id, + def _test_spawn(self, image_ref, kernel_id, ramdisk_id, instance_type_id="3", os_type="linux", instance_id=1, check_injection=False): stubs.stubout_loopingcall_start(self.stubs) values = {'id': instance_id, 'project_id': self.project.id, 'user_id': self.user.id, - 'image_id': image_id, + 'image_ref': image_ref, 'kernel_id': kernel_id, 'ramdisk_id': ramdisk_id, 'instance_type_id': instance_type_id, @@ -567,7 +566,7 @@ class XenAPIVMTestCase(test.TestCase): 'id': 1, 'project_id': self.project.id, 'user_id': self.user.id, - 'image_id': 1, + 'image_ref': 1, 'kernel_id': 2, 'ramdisk_id': 3, 'instance_type_id': '3', # m1.large @@ -623,7 +622,7 @@ class XenAPIMigrateInstance(test.TestCase): self.values = {'id': 1, 'project_id': self.project.id, 'user_id': self.user.id, - 'image_id': 1, + 'image_ref': 1, 'kernel_id': None, 'ramdisk_id': None, 'local_gb': 5, @@ -634,8 +633,7 @@ class XenAPIMigrateInstance(test.TestCase): fake_utils.stub_out_utils_execute(self.stubs) stubs.stub_out_migration_methods(self.stubs) stubs.stubout_get_this_vm_uuid(self.stubs) - glance_stubs.stubout_glance_client(self.stubs, - glance_stubs.FakeGlance) + glance_stubs.stubout_glance_client(self.stubs) def tearDown(self): super(XenAPIMigrateInstance, self).tearDown() @@ -661,8 +659,7 @@ class XenAPIDetermineDiskImageTestCase(test.TestCase): """Unit tests for code that detects the ImageType.""" def setUp(self): super(XenAPIDetermineDiskImageTestCase, self).setUp() - glance_stubs.stubout_glance_client(self.stubs, - glance_stubs.FakeGlance) + glance_stubs.stubout_glance_client(self.stubs) class FakeInstance(object): pass @@ -679,7 +676,7 @@ class XenAPIDetermineDiskImageTestCase(test.TestCase): def test_instance_disk(self): """If a kernel is specified, the image type is DISK (aka machine).""" FLAGS.xenapi_image_service = 'objectstore' - self.fake_instance.image_id = glance_stubs.FakeGlance.IMAGE_MACHINE + self.fake_instance.image_ref = glance_stubs.FakeGlance.IMAGE_MACHINE self.fake_instance.kernel_id = glance_stubs.FakeGlance.IMAGE_KERNEL self.assert_disk_type(vm_utils.ImageType.DISK) @@ -689,7 +686,7 @@ class XenAPIDetermineDiskImageTestCase(test.TestCase): DISK_RAW is assumed. """ FLAGS.xenapi_image_service = 'objectstore' - self.fake_instance.image_id = glance_stubs.FakeGlance.IMAGE_RAW + self.fake_instance.image_ref = glance_stubs.FakeGlance.IMAGE_RAW self.fake_instance.kernel_id = None self.assert_disk_type(vm_utils.ImageType.DISK_RAW) @@ -699,7 +696,7 @@ class XenAPIDetermineDiskImageTestCase(test.TestCase): this case will be 'raw'. """ FLAGS.xenapi_image_service = 'glance' - self.fake_instance.image_id = glance_stubs.FakeGlance.IMAGE_RAW + self.fake_instance.image_ref = glance_stubs.FakeGlance.IMAGE_RAW self.fake_instance.kernel_id = None self.assert_disk_type(vm_utils.ImageType.DISK_RAW) @@ -709,7 +706,7 @@ class XenAPIDetermineDiskImageTestCase(test.TestCase): this case will be 'vhd'. """ FLAGS.xenapi_image_service = 'glance' - self.fake_instance.image_id = glance_stubs.FakeGlance.IMAGE_VHD + self.fake_instance.image_ref = glance_stubs.FakeGlance.IMAGE_VHD self.fake_instance.kernel_id = None self.assert_disk_type(vm_utils.ImageType.DISK_VHD) diff --git a/nova/tests/vmwareapi/db_fakes.py b/nova/tests/vmwareapi/db_fakes.py index 0addd5573..764de42d8 100644 --- a/nova/tests/vmwareapi/db_fakes.py +++ b/nova/tests/vmwareapi/db_fakes.py @@ -61,7 +61,7 @@ def stub_out_db_instance_api(stubs): 'name': values['name'], 'id': values['id'], 'reservation_id': utils.generate_uid('r'), - 'image_id': values['image_id'], + 'image_ref': values['image_ref'], 'kernel_id': values['kernel_id'], 'ramdisk_id': values['ramdisk_id'], 'state_description': 'scheduling', diff --git a/nova/virt/vmwareapi/vmops.py b/nova/virt/vmwareapi/vmops.py index c3e79a92f..d1bf2de2c 100644 --- a/nova/virt/vmwareapi/vmops.py +++ b/nova/virt/vmwareapi/vmops.py @@ -150,7 +150,7 @@ class VMWareVMOps(object): """ image_size, image_properties = \ vmware_images.get_vmdk_size_and_properties( - instance.image_id, instance) + instance.image_ref, instance) vmdk_file_size_in_kb = int(image_size) / 1024 os_type = image_properties.get("vmware_ostype", "otherGuest") adapter_type = image_properties.get("vmware_adaptertype", @@ -265,23 +265,23 @@ class VMWareVMOps(object): def _fetch_image_on_esx_datastore(): """Fetch image from Glance to ESX datastore.""" - LOG.debug(_("Downloading image file data %(image_id)s to the ESX " + LOG.debug(_("Downloading image file data %(image_ref)s to the ESX " "data store %(data_store_name)s") % - ({'image_id': instance.image_id, + ({'image_ref': instance.image_ref, 'data_store_name': data_store_name})) # Upload the -flat.vmdk file whose meta-data file we just created # above vmware_images.fetch_image( - instance.image_id, + instance.image_ref, instance, host=self._session._host_ip, data_center_name=self._get_datacenter_name_and_ref()[1], datastore_name=data_store_name, cookies=cookies, file_path=flat_uploaded_vmdk_name) - LOG.debug(_("Downloaded image file data %(image_id)s to the ESX " + LOG.debug(_("Downloaded image file data %(image_ref)s to the ESX " "data store %(data_store_name)s") % - ({'image_id': instance.image_id, + ({'image_ref': instance.image_ref, 'data_store_name': data_store_name})) _fetch_image_on_esx_datastore() diff --git a/nova/virt/vmwareapi/vmware_images.py b/nova/virt/vmwareapi/vmware_images.py index 50c6baedf..11f4fe06a 100644 --- a/nova/virt/vmwareapi/vmware_images.py +++ b/nova/virt/vmwareapi/vmware_images.py @@ -18,10 +18,9 @@ Utility functions for Image transfer. """ -from glance import client - from nova import exception from nova import flags +import nova.image from nova import log as logging from nova.virt.vmwareapi import io_util from nova.virt.vmwareapi import read_write_util @@ -117,8 +116,8 @@ def upload_image(image, instance, **kwargs): def _get_glance_image(image, instance, **kwargs): """Download image from the glance image server.""" LOG.debug(_("Downloading image %s from glance image server") % image) - glance_client = client.Client(FLAGS.glance_host, FLAGS.glance_port) - metadata, read_iter = glance_client.get_image(image) + glance_client, image_id = nova.image.get_glance_client(image) + metadata, read_iter = glance_client.get_image(image_id) read_file_handle = read_write_util.GlanceFileRead(read_iter) file_size = int(metadata['size']) write_file_handle = read_write_util.VMWareHTTPWriteFile( @@ -153,7 +152,7 @@ def _put_glance_image(image, instance, **kwargs): kwargs.get("cookies"), kwargs.get("file_path")) file_size = read_file_handle.get_size() - glance_client = client.Client(FLAGS.glance_host, FLAGS.glance_port) + glance_client, image_id = nova.image.get_glance_client(image) # The properties and other fields that we need to set for the image. image_metadata = {"is_public": True, "disk_format": "vmdk", @@ -165,7 +164,7 @@ def _put_glance_image(image, instance, **kwargs): "vmware_image_version": kwargs.get("image_version")}} start_transfer(read_file_handle, file_size, glance_client=glance_client, - image_id=image, image_meta=image_metadata) + image_id=image_id, image_meta=image_metadata) LOG.debug(_("Uploaded image %s to the Glance image server") % image) @@ -188,9 +187,8 @@ def get_vmdk_size_and_properties(image, instance): LOG.debug(_("Getting image size for the image %s") % image) if FLAGS.image_service == "nova.image.glance.GlanceImageService": - glance_client = client.Client(FLAGS.glance_host, - FLAGS.glance_port) - meta_data = glance_client.get_image_meta(image) + glance_client, image_id = nova.image.get_glance_client(image) + meta_data = glance_client.get_image_meta(image_id) size, properties = meta_data["size"], meta_data["properties"] elif FLAGS.image_service == "nova.image.s3.S3ImageService": raise NotImplementedError diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py index 06ee8ee9b..3b1209da8 100644 --- a/nova/virt/xenapi/vm_utils.py +++ b/nova/virt/xenapi/vm_utils.py @@ -32,6 +32,7 @@ from xml.dom import minidom import glance.client from nova import exception from nova import flags +import nova.image from nova import log as logging from nova import utils from nova.auth.manager import AuthManager @@ -455,8 +456,8 @@ class VMHelper(HelperBase): # DISK restores sr_ref = safe_find_sr(session) - client = glance.client.Client(FLAGS.glance_host, FLAGS.glance_port) - meta, image_file = client.get_image(image) + glance_client, image_id = nova.image.get_glance_client(image) + meta, image_file = glance_client.get_image(image_id) virtual_size = int(meta['size']) vdi_size = virtual_size LOG.debug(_("Size for image %(image)s:%(virtual_size)d") % locals()) @@ -515,10 +516,10 @@ class VMHelper(HelperBase): ImageType.DISK_RAW: 'DISK_RAW', ImageType.DISK_VHD: 'DISK_VHD'} disk_format = pretty_format[image_type] - image_id = instance.image_id + image_ref = instance.image_ref instance_id = instance.id LOG.debug(_("Detected %(disk_format)s format for image " - "%(image_id)s, instance %(instance_id)s") % locals()) + "%(image_ref)s, instance %(instance_id)s") % locals()) def determine_from_glance(): glance_disk_format2nova_type = { @@ -527,8 +528,9 @@ class VMHelper(HelperBase): 'ari': ImageType.KERNEL_RAMDISK, 'raw': ImageType.DISK_RAW, 'vhd': ImageType.DISK_VHD} - client = glance.client.Client(FLAGS.glance_host, FLAGS.glance_port) - meta = client.get_image_meta(instance.image_id) + image_ref = instance.image_ref + glance_client, image_id = nova.image.get_glance_client(image_ref) + meta = glance_client.get_image_meta(image_id) disk_format = meta['disk_format'] try: return glance_disk_format2nova_type[disk_format] diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index 6d516ddbc..183d29470 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -111,7 +111,7 @@ class VMOps(object): project = AuthManager().get_project(instance.project_id) disk_image_type = VMHelper.determine_disk_image_type(instance) vdis = VMHelper.fetch_image(self._session, - instance.id, instance.image_id, user, project, + instance.id, instance.image_ref, user, project, disk_image_type) return vdis -- cgit