# glance.common.location_strategy

# Source code for glance.common.location_strategy

    # Copyright 2014 IBM Corp.
    # 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.

    import copy

    from oslo_config import cfg
    from oslo_log import log as logging
    import stevedore

    from glance.i18n import _, _LE

    location_strategy_opts = [
        cfg.StrOpt('location_strategy',
                   default='location_order',
                   choices=('location_order', 'store_type'),
                   help=_("""
    Strategy to determine the preference order of image locations.

    This configuration option indicates the strategy to determine
    the order in which an image's locations must be accessed to
    serve the image's data. Glance then retrieves the image data
    from the first responsive active location it finds in this list.

    This option takes one of two possible values ``location_order``
    and ``store_type``. The default value is ``location_order``,
    which suggests that image data be served by using locations in
    the order they are stored in Glance. The ``store_type`` value
    sets the image location preference based on the order in which
    the storage backends are listed as a comma separated list for
    the configuration option ``store_type_preference``.

    Possible values:
        * location_order
        * store_type

    Related options:
        * store_type_preference

    """)),
    ]

    CONF = cfg.CONF
    CONF.register_opts(location_strategy_opts)

    LOG = logging.getLogger(__name__)

    def _load_strategies():
        """Load all strategy modules."""
        modules = {}
        namespace = "glance.common.image_location_strategy.modules"
        ex = stevedore.extension.ExtensionManager(namespace)
        for module_name in ex.names():
            try:
                mgr = stevedore.driver.DriverManager(
                    namespace=namespace,
                    name=module_name,
                    invoke_on_load=False)

                # Obtain module name
                strategy_name = str(mgr.driver.get_strategy_name())
                if strategy_name in modules:
                    msg = (_('%(strategy)s is registered as a module twice. '
                             '%(module)s is not being used.') %
                           {'strategy': strategy_name, 'module': module_name})
                    LOG.warning(msg)
                else:
                    # Initialize strategy module
                    mgr.driver.init()
                    modules[strategy_name] = mgr.driver
            except Exception as e:
                LOG.error(_LE("Failed to load location strategy module "
                              "%(module)s: %(e)s"), {'module': module_name,
                                                     'e': e})
        return modules

    _available_strategies = _load_strategies()

    # TODO(kadachi): Not used but don't remove this until glance_store
    #                development/migration stage.
    def verify_location_strategy(conf=None, strategies=_available_strategies):
        """Validate user configured 'location_strategy' option value."""
        if not conf:
            conf = CONF.location_strategy
        if conf not in strategies:
            msg = (_('Invalid location_strategy option: %(name)s. '
                     'The valid strategy option(s) is(are): %(strategies)s') %
                   {'name': conf, 'strategies': ", ".join(strategies.keys())})
            LOG.error(msg)
            raise RuntimeError(msg)

    def get_ordered_locations(locations, **kwargs):
        """
        Order image location list by configured strategy.

        :param locations: The original image location list.
        :param kwargs: Strategy-specific arguments for under layer strategy module.
        :returns: The image location list with strategy-specific order.
        """
        if not locations:
            return []
        strategy_module = _available_strategies[CONF.location_strategy]
        return strategy_module.get_ordered_locations(copy.deepcopy(locations),
                                                     **kwargs)

    def choose_best_location(locations, **kwargs):
        """
        Choose best location from image location list by configured strategy.

        :param locations: The original image location list.
        :param kwargs: Strategy-specific arguments for under layer strategy module.
        :returns: The best location from image location list.
        """
        locations = get_ordered_locations(locations, **kwargs)
        if locations:
            return locations[0]
        else:
            return None

this page last updated: 2026-03-19 02:17:34

Except where otherwise noted, this document is licensed under Creative Commons Attribution 3.0 License. See all OpenStack Legal Documents.

found an error? report a bug