Source code for glance.common.location_strategy.store_type
# 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.
"""Storage preference based location strategy module"""
from oslo_config import cfg
import six
import six.moves.urllib.parse as urlparse
from glance.i18n import _
# TODO(dharinic): The help text for ``store_type_preference`` must be
# edited to replace ``filesystem``and ``vmware_datastore`` with ``file``
# and ``vmware`` respectively upon resolution of Bug #1615852.
# Also, remove the Note from ``Possible Values`` sections upon
# resolution of Bug #1615852.
# NOTE(dharinic): We cannot restrict the choices for ``store_type_preference``
# for backward compatability reasons. See Bug #1615852.
store_type_opts = [
cfg.ListOpt('store_type_preference',
default=[],
help=_("""
Preference order of storage backends.
Provide a comma separated list of store names in the order in
which images should be retrieved from storage backends.
These store names must be registered with the ``stores``
configuration option.
NOTE: The ``store_type_preference`` configuration option is applied
only if ``store_type`` is chosen as a value for the
``location_strategy`` configuration option. An empty list will not
change the location order.
Possible values:
* Empty list
* Comma separated list of registered store names. Legal values are:
(NOTE: Use only the following choices, which, unfortunately,
are not entirely consistent with the store names used in other
similar configuration options. Please take extra care while
setting this option, and read the help text carefully when
setting other similar options.)
* filesystem
* http
* rbd
* swift
* sheepdog
* cinder
* vmware_datastore
Related options:
* location_strategy
* stores
"""))
]
CONF = cfg.CONF
CONF.register_opts(store_type_opts, group='store_type_location_strategy')
_STORE_TO_SCHEME_MAP = {}
[docs]def get_strategy_name():
"""Return strategy module name."""
return 'store_type'
[docs]def init():
"""Initialize strategy module."""
# NOTE(zhiyan): We have a plan to do a reusable glance client library for
# all clients like Nova and Cinder in near period, it would be able to
# contains common code to provide uniform image service interface for them,
# just like Brick in Cinder, this code can be moved to there and shared
# between Glance and client both side. So this implementation as far as
# possible to prevent make relationships with Glance(server)-specific code,
# for example: using functions within store module to validate
# 'store_type_preference' option.
mapping = {'filesystem': ['file', 'filesystem'],
'http': ['http', 'https'],
'rbd': ['rbd'],
'swift': ['swift', 'swift+https', 'swift+http'],
'sheepdog': ['sheepdog'],
'cinder': ['cinder'],
'vmware_datastore': ['vsphere']}
_STORE_TO_SCHEME_MAP.clear()
_STORE_TO_SCHEME_MAP.update(mapping)
[docs]def get_ordered_locations(locations, uri_key='url', **kwargs):
"""
Order image location list.
:param locations: The original image location list.
:param uri_key: The key name for location URI in image location dictionary.
:returns: The image location list with preferred store type order.
"""
def _foreach_store_type_preference():
store_types = CONF.store_type_location_strategy.store_type_preference
for preferred_store in store_types:
preferred_store = str(preferred_store).strip()
if not preferred_store:
continue
yield preferred_store
if not locations:
return locations
preferences = {}
others = []
for preferred_store in _foreach_store_type_preference():
preferences[preferred_store] = []
for location in locations:
uri = location.get(uri_key)
if not uri:
continue
pieces = urlparse.urlparse(uri.strip())
store_name = None
for store, schemes in six.iteritems(_STORE_TO_SCHEME_MAP):
if pieces.scheme.strip() in schemes:
store_name = store
break
if store_name in preferences:
preferences[store_name].append(location)
else:
others.append(location)
ret = []
# NOTE(zhiyan): While configuration again since py26 does not support
# ordereddict container.
for preferred_store in _foreach_store_type_preference():
ret.extend(preferences[preferred_store])
ret.extend(others)
return ret