text: # 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
  import stevedore
  
  from glance import i18n
  import glance.openstack.common.log as logging
  
  _ = i18n._
  _LE = i18n._LE
  
  location_strategy_opts = [
      cfg.StrOpt('location_strategy', default='location_order',
                 help=_("This value sets what strategy will be used to "
                        "determine the image location order. Currently "
                        "two strategies are packaged with Glance "
                        "'location_order' and 'store_type'."))
  ]
  
  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.warn(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.
      :return: 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.
      :return: The best location from image location list.
      """
      locations = get_ordered_locations(locations, **kwargs)
      if locations:
          return locations[0]
      else:
          return None
  