Use only Glance V2 by default (with a compatibility option)

Glance V1 is deprecated we should start switching off it. Even more,
some features in Ironic already require V2 anyway.

This change switches everything to V2 by default, while leaving an option
to get previous behavior back. Features that already required V2 are
not affected by this option.

Change-Id: I6947a150fefb7fe3028a0a7c5208c6c343be8e0d
Closes-Bug: #1657475
This commit is contained in:
Dmitry Tantsur 2017-01-18 15:51:27 +01:00
parent f5735999c6
commit 72adb4fa5c
6 changed files with 44 additions and 10 deletions

View File

@ -1420,6 +1420,11 @@
# [hostname|IP]:port. (list value)
#glance_api_servers = <None>
# Glance API version (1 or 2) to use. (integer value)
# Minimum value: 1
# Maximum value: 2
#glance_api_version = 2
# Optional path to a CA certificate bundle to be used to
# validate the SSL certificate served by glance. It is used
# when glance_api_insecure is set to False. (string value)

View File

@ -45,8 +45,11 @@ def _get_glance_session():
return _GLANCE_SESSION
def GlanceImageService(client=None, version=1, context=None):
def GlanceImageService(client=None, version=None, context=None):
module_str = 'ironic.common.glance_service'
if version is None:
version = CONF.glance.glance_api_version
module = importutils.import_versioned_module(module_str, version,
'image_service')
service_class = getattr(module, 'GlanceImageService')
@ -258,7 +261,7 @@ protocol_mapping = {
}
def get_image_service(image_href, client=None, version=1, context=None):
def get_image_service(image_href, client=None, version=None, context=None):
"""Get image service instance to download the image.
:param image_href: String containing href to get image service for.

View File

@ -141,6 +141,9 @@ opts = [
help=_('Optional path to a CA certificate bundle to be used to '
'validate the SSL certificate served by glance. It is '
'used when glance_api_insecure is set to False.')),
cfg.IntOpt('glance_api_version',
help=_('Glance API version (1 or 2) to use.'),
min=1, max=2, default=2),
]

View File

@ -96,7 +96,8 @@ def _get_instance_image_info(node, ctx):
labels = ('kernel', 'ramdisk')
d_info = deploy_utils.get_image_instance_info(node)
if not (i_info.get('kernel') and i_info.get('ramdisk')):
glance_service = service.GlanceImageService(version=1, context=ctx)
glance_service = service.GlanceImageService(
version=CONF.glance.glance_api_version, context=ctx)
iproperties = glance_service.show(d_info['image_source'])['properties']
for label in labels:
i_info[label] = str(iproperties[label + '_id'])

View File

@ -24,6 +24,7 @@ from six.moves import http_client
from ironic.common import exception
from ironic.common.glance_service.v1 import image_service as glance_v1_service
from ironic.common.glance_service.v2 import image_service as glance_v2_service
from ironic.common import image_service
from ironic.tests import base
@ -254,31 +255,44 @@ class FileImageServiceTestCase(base.TestCase):
class ServiceGetterTestCase(base.TestCase):
@mock.patch.object(image_service, '_get_glance_session')
@mock.patch.object(glance_v1_service.GlanceImageService, '__init__',
@mock.patch.object(glance_v2_service.GlanceImageService, '__init__',
return_value=None, autospec=True)
def test_get_glance_image_service(self, glance_service_mock,
session_mock):
image_href = 'image-uuid'
self.context.auth_token = 'fake'
image_service.get_image_service(image_href, context=self.context)
glance_service_mock.assert_called_once_with(mock.ANY, None, 2,
self.context)
self.assertFalse(session_mock.called)
@mock.patch.object(image_service, '_get_glance_session')
@mock.patch.object(glance_v1_service.GlanceImageService, '__init__',
return_value=None, autospec=True)
def test_get_glance_image_service_default_v1(self, glance_service_mock,
session_mock):
self.config(glance_api_version=1, group='glance')
image_href = 'image-uuid'
self.context.auth_token = 'fake'
image_service.get_image_service(image_href, context=self.context)
glance_service_mock.assert_called_once_with(mock.ANY, None, 1,
self.context)
self.assertFalse(session_mock.called)
@mock.patch.object(image_service, '_get_glance_session')
@mock.patch.object(glance_v1_service.GlanceImageService, '__init__',
@mock.patch.object(glance_v2_service.GlanceImageService, '__init__',
return_value=None, autospec=True)
def test_get_glance_image_service_url(self, glance_service_mock,
session_mock):
image_href = 'glance://image-uuid'
self.context.auth_token = 'fake'
image_service.get_image_service(image_href, context=self.context)
glance_service_mock.assert_called_once_with(mock.ANY, None, 1,
glance_service_mock.assert_called_once_with(mock.ANY, None, 2,
self.context)
self.assertFalse(session_mock.called)
@mock.patch.object(image_service, '_get_glance_session')
@mock.patch.object(glance_v1_service.GlanceImageService, '__init__',
@mock.patch.object(glance_v2_service.GlanceImageService, '__init__',
return_value=None, autospec=True)
def test_get_glance_image_service_no_token(self, glance_service_mock,
session_mock):
@ -288,13 +302,13 @@ class ServiceGetterTestCase(base.TestCase):
sess.get_token.return_value = 'admin-token'
session_mock.return_value = sess
image_service.get_image_service(image_href, context=self.context)
glance_service_mock.assert_called_once_with(mock.ANY, None, 1,
glance_service_mock.assert_called_once_with(mock.ANY, None, 2,
self.context)
sess.get_token.assert_called_once_with()
self.assertEqual('admin-token', self.context.auth_token)
@mock.patch.object(image_service, '_get_glance_session')
@mock.patch.object(glance_v1_service.GlanceImageService, '__init__',
@mock.patch.object(glance_v2_service.GlanceImageService, '__init__',
return_value=None, autospec=True)
def test_get_glance_image_service_token_not_needed(self,
glance_service_mock,
@ -303,7 +317,7 @@ class ServiceGetterTestCase(base.TestCase):
self.context.auth_token = None
self.config(auth_strategy='noauth', group='glance')
image_service.get_image_service(image_href, context=self.context)
glance_service_mock.assert_called_once_with(mock.ANY, None, 1,
glance_service_mock.assert_called_once_with(mock.ANY, None, 2,
self.context)
self.assertFalse(session_mock.called)
self.assertIsNone(self.context.auth_token)

View File

@ -0,0 +1,8 @@
---
upgrade:
- |
Ironic now uses only Image (glance) V2 API by default. Usage of deprecated
V1 API for certain basic tasks can still be enabled by setting
"[glance]glance_api_version" to "1". This option, however, does not affect
temporary URL generation, as it always required V2 API and cannot work
with V1.