Merge "Use the catalog to retrieve glance_api_servers"
This commit is contained in:
commit
75212a9df6
@ -54,15 +54,8 @@ global_opts = [
|
||||
cfg.StrOpt('my_ip',
|
||||
default=netutils.get_my_ipv4(),
|
||||
help='IP address of this host'),
|
||||
cfg.StrOpt('glance_host',
|
||||
default='$my_ip',
|
||||
help='Default glance host name or IP'),
|
||||
cfg.IntOpt('glance_port',
|
||||
default=9292,
|
||||
min=1, max=65535,
|
||||
help='Default glance port'),
|
||||
cfg.ListOpt('glance_api_servers',
|
||||
default=['$glance_host:$glance_port'],
|
||||
default=None,
|
||||
help='A list of the URLs of glance API servers available to '
|
||||
'cinder ([http[s]://][hostname|ip]:port). If protocol '
|
||||
'is not specified it defaults to http.'),
|
||||
|
@ -92,7 +92,8 @@ class RequestContext(context.RequestContext):
|
||||
# Only include required parts of service_catalog
|
||||
self.service_catalog = [s for s in service_catalog
|
||||
if s.get('type') in
|
||||
('identity', 'compute', 'object-store')]
|
||||
('identity', 'compute', 'object-store',
|
||||
'image')]
|
||||
else:
|
||||
# if list is empty or none
|
||||
self.service_catalog = []
|
||||
|
@ -36,7 +36,7 @@ from six.moves import range
|
||||
from six.moves import urllib
|
||||
|
||||
from cinder import exception
|
||||
from cinder.i18n import _LE, _LW
|
||||
from cinder.i18n import _, _LE, _LW
|
||||
|
||||
|
||||
glance_opts = [
|
||||
@ -45,6 +45,12 @@ glance_opts = [
|
||||
help='A list of url schemes that can be downloaded directly '
|
||||
'via the direct_url. Currently supported schemes: '
|
||||
'[file].'),
|
||||
cfg.StrOpt('glance_catalog_info',
|
||||
default='image:glance:publicURL',
|
||||
help='Info to match when looking for glance in the service '
|
||||
'catalog. Format is: separated values of the form: '
|
||||
'<service_type>:<service_name>:<endpoint_type> - '
|
||||
'Only used if glance_api_servers are not provided.'),
|
||||
]
|
||||
glance_core_properties_opts = [
|
||||
cfg.ListOpt('glance_core_properties',
|
||||
@ -97,23 +103,44 @@ def _create_glance_client(context, netloc, use_ssl, version=None):
|
||||
return glanceclient.Client(str(version), endpoint, **params)
|
||||
|
||||
|
||||
def get_api_servers():
|
||||
def get_api_servers(context):
|
||||
"""Return Iterable over shuffled api servers.
|
||||
|
||||
Shuffle a list of CONF.glance_api_servers and return an iterator
|
||||
Shuffle a list of glance_api_servers and return an iterator
|
||||
that will cycle through the list, looping around to the beginning
|
||||
if necessary.
|
||||
if necessary. If CONF.glance_api_servers is None then they will
|
||||
be retrieved from the catalog.
|
||||
"""
|
||||
api_servers = []
|
||||
for api_server in CONF.glance_api_servers:
|
||||
api_servers_info = []
|
||||
|
||||
if CONF.glance_api_servers is None:
|
||||
info = CONF.glance_catalog_info
|
||||
try:
|
||||
service_type, service_name, endpoint_type = info.split(':')
|
||||
except ValueError:
|
||||
raise exception.InvalidConfigurationValue(_(
|
||||
"Failed to parse the configuration option "
|
||||
"'glance_catalog_info', must be in the form "
|
||||
"<service_type>:<service_name>:<endpoint_type>"))
|
||||
for entry in context.service_catalog:
|
||||
if entry.get('type') == service_type:
|
||||
api_servers.append(
|
||||
entry.get('endpoints')[0].get(endpoint_type))
|
||||
else:
|
||||
for api_server in CONF.glance_api_servers:
|
||||
api_servers.append(api_server)
|
||||
|
||||
for api_server in api_servers:
|
||||
if '//' not in api_server:
|
||||
api_server = 'http://' + api_server
|
||||
url = urllib.parse.urlparse(api_server)
|
||||
netloc = url.netloc
|
||||
use_ssl = (url.scheme == 'https')
|
||||
api_servers.append((netloc, use_ssl))
|
||||
random.shuffle(api_servers)
|
||||
return itertools.cycle(api_servers)
|
||||
api_servers_info.append((netloc, use_ssl))
|
||||
|
||||
random.shuffle(api_servers_info)
|
||||
return itertools.cycle(api_servers_info)
|
||||
|
||||
|
||||
class GlanceClientWrapper(object):
|
||||
@ -149,7 +176,7 @@ class GlanceClientWrapper(object):
|
||||
def _create_onetime_client(self, context, version):
|
||||
"""Create a client that will be used for one call."""
|
||||
if self.api_servers is None:
|
||||
self.api_servers = get_api_servers()
|
||||
self.api_servers = get_api_servers(context)
|
||||
self.netloc, self.use_ssl = next(self.api_servers)
|
||||
return _create_glance_client(context,
|
||||
self.netloc,
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
|
||||
import datetime
|
||||
import itertools
|
||||
|
||||
import glanceclient.exc
|
||||
import mock
|
||||
@ -94,8 +95,12 @@ class TestGlanceImageService(test.TestCase):
|
||||
super(TestGlanceImageService, self).setUp()
|
||||
|
||||
client = glance_stubs.StubGlanceClient()
|
||||
service_catalog = [{u'type': u'image', u'name': u'glance',
|
||||
u'endpoints': [{
|
||||
u'publicURL': u'http://example.com:9292'}]}]
|
||||
self.service = self._create_image_service(client)
|
||||
self.context = context.RequestContext('fake', 'fake', auth_token=True)
|
||||
self.context.service_catalog = service_catalog
|
||||
self.stubs.Set(glance.time, 'sleep', lambda s: None)
|
||||
|
||||
def _create_image_service(self, client):
|
||||
@ -123,6 +128,11 @@ class TestGlanceImageService(test.TestCase):
|
||||
updated_at=self.NOW_GLANCE_FORMAT,
|
||||
deleted_at=self.NOW_GLANCE_FORMAT)
|
||||
|
||||
def test_get_api_servers(self):
|
||||
result = glance.get_api_servers(self.context)
|
||||
expected = (u'example.com:9292', False)
|
||||
self.assertEqual(expected, next(result))
|
||||
|
||||
def test_create_with_instance_id(self):
|
||||
"""Ensure instance_id is persisted as an image-property."""
|
||||
fixture = {'name': 'test image',
|
||||
@ -533,7 +543,10 @@ class TestGlanceImageService(test.TestCase):
|
||||
|
||||
@mock.patch('six.moves.builtins.open')
|
||||
@mock.patch('shutil.copyfileobj')
|
||||
def test_download_from_direct_file(self, mock_copyfileobj, mock_open):
|
||||
@mock.patch('cinder.image.glance.get_api_servers',
|
||||
return_value=itertools.cycle([(False, 'localhost:9292')]))
|
||||
def test_download_from_direct_file(self, api_servers,
|
||||
mock_copyfileobj, mock_open):
|
||||
fixture = self._make_fixture(name='test image',
|
||||
locations=[{'url': 'file:///tmp/test'}])
|
||||
image_id = self.service.create(self.context, fixture)['id']
|
||||
@ -545,7 +558,9 @@ class TestGlanceImageService(test.TestCase):
|
||||
|
||||
@mock.patch('six.moves.builtins.open')
|
||||
@mock.patch('shutil.copyfileobj')
|
||||
def test_download_from_direct_file_non_file(self,
|
||||
@mock.patch('cinder.image.glance.get_api_servers',
|
||||
return_value=itertools.cycle([(False, 'localhost:9292')]))
|
||||
def test_download_from_direct_file_non_file(self, api_servers,
|
||||
mock_copyfileobj, mock_open):
|
||||
fixture = self._make_fixture(name='test image',
|
||||
direct_url='swift+http://test/image')
|
||||
@ -734,7 +749,9 @@ class TestGlanceClientVersion(test.TestCase):
|
||||
self.assertEqual('2', _mockglanceclient.call_args[0][0])
|
||||
|
||||
@mock.patch('cinder.image.glance.glanceclient.Client')
|
||||
def test_call_glance_version_by_arg(self, _mockglanceclient):
|
||||
@mock.patch('cinder.image.glance.get_api_servers',
|
||||
return_value=itertools.cycle([(False, 'localhost:9292')]))
|
||||
def test_call_glance_version_by_arg(self, api_servers, _mockglanceclient):
|
||||
"""Test glance version set by arg to GlanceClientWrapper"""
|
||||
glance_wrapper = glance.GlanceClientWrapper()
|
||||
glance_wrapper.call('fake_context', 'method', version=2)
|
||||
|
@ -82,7 +82,7 @@ class ContextTestCase(test.TestCase):
|
||||
object_catalog = [{u'name': u'swift', u'type': u'object-store'}]
|
||||
ctxt = context.RequestContext('111', '222',
|
||||
service_catalog=service_catalog)
|
||||
self.assertEqual(3, len(ctxt.service_catalog))
|
||||
self.assertEqual(4, len(ctxt.service_catalog))
|
||||
return_compute = [v for v in ctxt.service_catalog if
|
||||
v['type'] == u'compute']
|
||||
return_object = [v for v in ctxt.service_catalog if
|
||||
|
Loading…
Reference in New Issue
Block a user