¡@

Home 

OpenStack Study: __init__.py

OpenStack Index

**** CubicPower OpenStack Study ****

def _image_handler_asso(handler, path, location, image_meta):

    _IMAGE_HANDLERS_ASSO[path] = (handler, location, image_meta)

**** CubicPower OpenStack Study ****

def _image_handler_disasso(handler, path):

    _IMAGE_HANDLERS_ASSO.pop(path, None)

**** CubicPower OpenStack Study ****

def _match_locations(locations, schemes):

    matched = []

    if locations and (schemes is not None):

        for loc in locations:

            # Note(zhiyan): location = {'url': 'string',

            #                           'metadata': {...}}

            if len(schemes) == 0:

                # Note(zhiyan): handler has not scheme limitation.

                matched.append(loc)

            elif urlparse.urlparse(loc['url']).scheme in schemes:

                matched.append(loc)

    return matched

**** CubicPower OpenStack Study ****

def load_image_handlers(driver):

    """Loading construct user configured image handlers.

    Handler objects will be cached to keep handler instance as singleton

    since this structure need support follow sub-class development,

    developer could implement particular sub-class in relevant hypervisor

    layer with more advanced functions.

    The handler's __init__() need do some re-preparing work if it needed,

    for example when nova-compute service restart or host reboot,

    CinderImageHandler will need to re-prepare iscsi/fc link for volumes

    those already be cached on compute host as template image previously.

    """

    global _IMAGE_HANDLERS, _IMAGE_HANDLERS_ASSO

    if _IMAGE_HANDLERS:

        _IMAGE_HANDLERS = []

        _IMAGE_HANDLERS_ASSO = {}

    # for de-duplicate. using ordereddict lib to support both py26 and py27?

    processed_handler_names = []

    ex = stevedore.extension.ExtensionManager('nova.virt.image.handlers')

    for name in CONF.image_handlers:

        if not name:

            continue

        name = name.strip()

        if name in processed_handler_names:

            LOG.warn(_("Duplicated handler extension name in 'image_handlers' "

                       "option: %s, skip."), name)

            continue

        elif name not in ex.names():

            LOG.warn(_("Invalid handler extension name in 'image_handlers' "

                       "option: %s, skip."), name)

            continue

        processed_handler_names.append(name)

        try:

            mgr = stevedore.driver.DriverManager(

                namespace='nova.virt.image.handlers',

                name=name,

                invoke_on_load=True,

                invoke_kwds={"driver": driver,

                             "associate_fn": _image_handler_asso,

                             "disassociate_fn": _image_handler_disasso})

            _IMAGE_HANDLERS.append(mgr.driver)

        except Exception as err:

            LOG.warn(_("Failed to import image handler extension "

                       "%(name)s: %(err)s"), {'name': name, 'err': err})

**** CubicPower OpenStack Study ****

def handle_image(context=None, image_id=None,

                 user_id=None, project_id=None,

                 target_path=None):

    """Handle image using available handles.

    This generator will return each available handler on each time.

    :param context: Request context

    :param image_id: The opaque image identifier

    :param user_id: Request user id

    :param project_id: Request project id

    :param target_path: Where the image data to write

    :raises NoImageHandlerAvailable: if no any image handler specified in

        the configuration is available for this request.

    """

    handled = False

    if target_path is not None:

        target_path = target_path.strip()

    # Check if target image has been handled before,

    # we can using previous handler process it again directly.

    if target_path and _IMAGE_HANDLERS_ASSO:

        ret = _IMAGE_HANDLERS_ASSO.get(target_path)

        if ret:

            (image_handler, location, image_meta) = ret

            yield image_handler, location, image_meta

            handled = image_handler.last_ops_handled()

    image_meta = None

    if not handled and _IMAGE_HANDLERS:

        if context and image_id:

            (image_service, _image_id) = glance.get_remote_image_service(

                                                            context, image_id)

            image_meta = image_service.show(context, image_id)

            # Note(zhiyan): Glance maybe can not receive image

            # location property since Glance disabled it by default.

            img_locs = image_service.get_locations(context, image_id)

            for image_handler in _IMAGE_HANDLERS:

                matched_locs = _match_locations(img_locs,

                                                image_handler.get_schemes())

                for loc in matched_locs:

                    yield image_handler, loc, image_meta

                    handled = image_handler.last_ops_handled()

                    if handled:

                        return

        if not handled:

            # Note(zhiyan): using location-independent handler do it.

            for image_handler in _IMAGE_HANDLERS:

                if len(image_handler.get_schemes()) == 0:

                    yield image_handler, None, image_meta

                    handled = image_handler.last_ops_handled()

                    if handled:

                        return

    if not handled:

        LOG.error(_("Can not handle image: %(image_id)s %(target_path)s"),

                  {'image_id': image_id, 'target_path': target_path})

        raise exception.NoImageHandlerAvailable(image_id=image_id)