Skip to content

Commit

Permalink
WIP: using stevedore to load image handler automatically.
Browse files Browse the repository at this point in the history
  • Loading branch information
jianghua wang committed Aug 18, 2017
1 parent 95f8fc5 commit 4804631
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 16 deletions.
17 changes: 5 additions & 12 deletions nova/conf/xenserver.py
Expand Up @@ -471,6 +471,11 @@
* ``vlan_interface``
* ``ovs_integration_bridge``
"""),
cfg.StrOpt('image_glance_store',
default='',
help="""
"""),

# TODO(dharinic): Make this, a stevedore plugin
cfg.StrOpt('image_upload_handler',
default='nova.virt.xenapi.image.glance.GlanceStore',
Expand All @@ -484,18 +489,6 @@
store for use. image_upload_handler takes in a value for the Dom0
plugin driver. This driver is then called to uplaod images to the
GlanceStore.
"""),
cfg.StrOpt('image_download_handler',
default='nova.virt.xenapi.image.glance.GlanceStore',
help="""
The plugin driver used to handle image downloads.
Provide a string value representing a plugin driver required to
handle the image downloading from Glance.
Images from Glance need to be downloaded to XenServer and create
disk from the image. This driver is called to download images and
create disk.
"""),
]

Expand Down
33 changes: 33 additions & 0 deletions nova/virt/xenapi/image/glanceStore.py
@@ -0,0 +1,33 @@
# Copyright 2017 Citrix Systems
#
# 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.

import abc

import six


@six.add_metaclass(abc.ABCMeta)
class glanceStore(object):
"""Base class for glance store used to upload/download images.
"""

@abc.abstractmethod
def download_image(self, context, session, instance, image_id):
"""Download image from glance and create disk from image.
"""

@abc.abstractmethod
def upload_image(self, context, session, instance, image_id, vdi_uuids):
"""create image from disk and upload to glance.
"""
66 changes: 66 additions & 0 deletions nova/virt/xenapi/image/vdiStream.py
@@ -0,0 +1,66 @@
# Copyright 2016 Citrix Systems
# 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.

""" This class will handle image data in a streaming way.
"""


from os_xenapi.client import exception as xenapi_exception
from os_xenapi.client.image import vdi_handler
from oslo_log import log as logging

import nova.conf
from nova import exception
from nova import image
from nova.virt.xenapi.image.glanceStore import glanceStore
from nova.virt.xenapi.image import utils

CONF = nova.conf.CONF
LOG = logging.getLogger(__name__)

IMAGE_API = image.API()


class vdiStream(glanceStore):
def download_image(self, context, session, instance, image_id):
LOG.debug("in vdiStream.download_image")
try:
host_url = CONF.xenserver.connection_url
image_data = IMAGE_API.download(context, image_id)
image_stream = utils.IterableToFileAdapter(image_data)
vdis = vdi_handler.stream_to_vdis(context, session,
instance, host_url,
data=image_stream)
except xenapi_exception.OsXenApiException:
raise exception.CouldNotFetchImage(image_id=image_id)
return vdis

def upload_image(self, context, session, instance, image_id, vdi_uuids):
try:
host_url = CONF.xenserver.connection_url
metadata = IMAGE_API.get(context, image_id)
metadata['disk_format'] = 'vhd'
metadata['container_format'] = "ovf"
# set size as zero, so that it will update the size in end basing
# on the uploaded data.
metadata['size'] = 0
image_trunks = vdi_handler.vdis_to_stream(context, session,
instance, host_url,
vdi_uuids)
image_stream = utils.IterableToFileAdapter(image_trunks)
IMAGE_API.update(context, image_id, metadata,
data=image_stream)
except xenapi_exception.OsXenApiException:
raise exception.CouldNotUploadImage(image_id=image_id)
7 changes: 5 additions & 2 deletions nova/virt/xenapi/vm_utils.py
Expand Up @@ -22,6 +22,7 @@
import contextlib
import math
import os
import stevedore
import time
import urllib
from xml.dom import minidom
Expand Down Expand Up @@ -1357,8 +1358,10 @@ def _fetch_vhd_image(context, session, instance, image_id):
LOG.debug("Asking xapi to fetch vhd image %s", image_id,
instance=instance)

handler = importutils.import_object(
CONF.xenserver.image_download_handler)
handler = stevedore.driver.DriverManager(
"xenapi.image.glance_store",
CONF.xenserver.image_glance_store,
invoke_on_load=True).driver

try:
vdis = handler.download_image(context, session, instance, image_id)
Expand Down
18 changes: 16 additions & 2 deletions nova/virt/xenapi/vmops.py
Expand Up @@ -19,6 +19,7 @@

import base64
import functools
import stevedore
import time
import zlib

Expand All @@ -38,6 +39,7 @@
from oslo_utils import units
import six

from nova.i18n import _LW
from nova import block_device
from nova import compute
from nova.compute import power_state
Expand Down Expand Up @@ -152,8 +154,20 @@ def __init__(self, session, virtapi):

LOG.debug("Importing image upload handler: %s",
CONF.xenserver.image_upload_handler)
self.image_upload_handler = importutils.import_object(
CONF.xenserver.image_upload_handler)

handler = CONF.xenserver.image_upload_handler
try:
self.image_upload_handler = stevedore.driver.DriverManager(
"xenapi.image.glance_store", handler,
invoke_on_load=True).driver
except stevedore.exception.NoMatches:
self.image_upload_handler = importutils.import_object(
handler)
LOG.warning(_LW("DEPRECATED: image_upload_handler uses "
"importutils to load %(path)s. This "
"legacy loading style will be removed "
"in the next release."),
{'path': handler})

def agent_enabled(self, instance):
if CONF.xenserver.disable_agent:
Expand Down
3 changes: 3 additions & 0 deletions setup.cfg
Expand Up @@ -27,6 +27,9 @@ packages =
nova

[entry_points]
xenapi.image.glance_store =
vdi_stream = nova.virt.xenapi.image.vdiStream:vdiStream

oslo.config.opts =
nova.conf = nova.conf.opts:list_opts

Expand Down

0 comments on commit 4804631

Please sign in to comment.