From c9af27c2302dda74e702c1cdc50a521fe0b32431 Mon Sep 17 00:00:00 2001 From: Alex Meade Date: Mon, 10 Dec 2012 15:17:58 -0500 Subject: xenapi: Add support for different image upload drivers This change refactors image upload code for xenapi and adds the xenapi_image_upload_handler config option. Preparation for bp nova-direct-image-upload DocImpact Change-Id: Icd4e7ef135beddca9ddcc4a880c09e5a1702a93c --- nova/virt/xenapi/imageupload/__init__.py | 0 nova/virt/xenapi/imageupload/glance.py | 54 ++++++++++++++++++++++++++++++++ nova/virt/xenapi/vm_utils.py | 29 ----------------- nova/virt/xenapi/vmops.py | 25 +++++++++++---- 4 files changed, 73 insertions(+), 35 deletions(-) create mode 100644 nova/virt/xenapi/imageupload/__init__.py create mode 100644 nova/virt/xenapi/imageupload/glance.py (limited to 'nova/virt') diff --git a/nova/virt/xenapi/imageupload/__init__.py b/nova/virt/xenapi/imageupload/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/nova/virt/xenapi/imageupload/glance.py b/nova/virt/xenapi/imageupload/glance.py new file mode 100644 index 000000000..adc06f65b --- /dev/null +++ b/nova/virt/xenapi/imageupload/glance.py @@ -0,0 +1,54 @@ +# Copyright 2013 OpenStack, LLC +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from nova.image import glance +from nova.openstack.common import cfg +import nova.openstack.common.log as logging +from nova.virt.xenapi import vm_utils + +LOG = logging.getLogger(__name__) + +CONF = cfg.CONF + + +class GlanceStore(object): + + def upload_image(self, context, session, instance, vdi_uuids, image_id): + """Requests that the Glance plugin bundle the specified VDIs and + push them into Glance using the specified human-friendly name. + """ + # NOTE(sirp): Currently we only support uploading images as VHD, there + # is no RAW equivalent (yet) + LOG.debug(_("Asking xapi to upload to glance %(vdi_uuids)s as" + " ID %(image_id)s"), locals(), instance=instance) + + glance_api_servers = glance.get_api_servers() + glance_host, glance_port, glance_use_ssl = glance_api_servers.next() + + properties = { + 'auto_disk_config': instance['auto_disk_config'], + 'os_type': instance['os_type'] or CONF.default_os_type, + } + + params = {'vdi_uuids': vdi_uuids, + 'image_id': image_id, + 'glance_host': glance_host, + 'glance_port': glance_port, + 'glance_use_ssl': glance_use_ssl, + 'sr_path': vm_utils.get_sr_path(session), + 'auth_token': getattr(context, 'auth_token', None), + 'properties': properties} + + session.call_plugin_serialized('glance', 'upload_vhd', **params) diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py index 52a5f37b2..c041171bd 100644 --- a/nova/virt/xenapi/vm_utils.py +++ b/nova/virt/xenapi/vm_utils.py @@ -722,35 +722,6 @@ def _find_cached_image(session, image_id, sr_ref): return cached_images.get(image_id) -def upload_image(context, session, instance, vdi_uuids, image_id): - """Requests that the Glance plugin bundle the specified VDIs and - push them into Glance using the specified human-friendly name. - """ - # NOTE(sirp): Currently we only support uploading images as VHD, there - # is no RAW equivalent (yet) - LOG.debug(_("Asking xapi to upload %(vdi_uuids)s as" - " ID %(image_id)s"), locals(), instance=instance) - - glance_api_servers = glance.get_api_servers() - glance_host, glance_port, glance_use_ssl = glance_api_servers.next() - - properties = { - 'auto_disk_config': instance['auto_disk_config'], - 'os_type': instance['os_type'] or CONF.default_os_type, - } - - params = {'vdi_uuids': vdi_uuids, - 'image_id': image_id, - 'glance_host': glance_host, - 'glance_port': glance_port, - 'glance_use_ssl': glance_use_ssl, - 'sr_path': get_sr_path(session), - 'auth_token': getattr(context, 'auth_token', None), - 'properties': properties} - - session.call_plugin_serialized('glance', 'upload_vhd', **params) - - def resize_disk(session, instance, vdi_ref, instance_type): # Copy VDI over to something we can resize # NOTE(jerdfelt): Would be nice to just set vdi_ref to read/write diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index 4a8372cda..8d3a3bed2 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -59,7 +59,10 @@ xenapi_vmops_opts = [ 'to go to running state'), cfg.StrOpt('xenapi_vif_driver', default='nova.virt.xenapi.vif.XenAPIBridgeDriver', - help='The XenAPI VIF driver using XenServer Network APIs.') + help='The XenAPI VIF driver using XenServer Network APIs.'), + cfg.StrOpt('xenapi_image_upload_handler', + default='nova.virt.xenapi.imageupload.glance.GlanceStore', + help='Object Store Driver used to handle image uploads.'), ] CONF = cfg.CONF @@ -161,6 +164,11 @@ class VMOps(object): self.vif_driver = vif_impl(xenapi_session=self._session) self.default_root_dev = '/dev/sda' + msg = _("Importing image upload handler: %s") + LOG.debug(msg % CONF.xenapi_image_upload_handler) + self.image_upload_handler = importutils.import_object( + CONF.xenapi_image_upload_handler) + @property def agent_enabled(self): return not CONF.xenapi_disable_agent @@ -661,9 +669,11 @@ class VMOps(object): coalesce together, so, we must wait for this coalescing to occur to get a stable representation of the data on disk. - 3. Push-to-glance: Once coalesced, we call a plugin on the XenServer - that will bundle the VHDs together and then push the bundle into - Glance. + 3. Push-to-data-store: Once coalesced, we call a plugin on the + XenServer that will bundle the VHDs together and then push the + bundle. Depending on the configured value of + 'xenapi_image_upload_handler', image data may be pushed to + Glance or the specified data store. """ vm_ref = self._get_vm_opaque_ref(instance) @@ -674,8 +684,11 @@ class VMOps(object): update_task_state) as vdi_uuids: update_task_state(task_state=task_states.IMAGE_UPLOADING, expected_state=task_states.IMAGE_PENDING_UPLOAD) - vm_utils.upload_image( - context, self._session, instance, vdi_uuids, image_id) + self.image_upload_handler.upload_image(context, + self._session, + instance, + vdi_uuids, + image_id) LOG.debug(_("Finished snapshot and upload for VM"), instance=instance) -- cgit