Remove Glance v1 API support
The Glance v1 API is about to be removed. Cinder support for using the current v2 API was added in Pike, but we allowed selection of which version to use through the glance_api_version config option. That option was also deprecated in Pike. This removes the config option to allow selection and switches things over to only use Glance API v2. Change-Id: Ice379db9ae83420bacf9e96e242c7515930eae86
This commit is contained in:
parent
bfcef9cb6b
commit
d76fef6bf4
@ -279,12 +279,6 @@ class VolumeActionsController(wsgi.Controller):
|
||||
if image_metadata['visibility'] == 'public':
|
||||
authorize(context, 'upload_public')
|
||||
|
||||
if CONF.glance_api_version != 2:
|
||||
# Replace visibility with is_public for Glance V1
|
||||
image_metadata['is_public'] = (
|
||||
image_metadata['visibility'] == 'public')
|
||||
image_metadata.pop('visibility', None)
|
||||
|
||||
image_metadata['protected'] = (
|
||||
utils.get_bool_param('protected', image_metadata))
|
||||
|
||||
|
@ -53,12 +53,6 @@ global_opts = [
|
||||
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.'),
|
||||
cfg.IntOpt('glance_api_version',
|
||||
default=2,
|
||||
deprecated_for_removal=True,
|
||||
deprecated_since="11.0.0",
|
||||
deprecated_reason='Glance v1 support will be removed in Queens',
|
||||
help='Version of the glance API to use'),
|
||||
cfg.IntOpt('glance_num_retries',
|
||||
min=0,
|
||||
default=0,
|
||||
|
@ -62,7 +62,6 @@ glance_core_properties_opts = [
|
||||
CONF = cfg.CONF
|
||||
CONF.register_opts(glance_opts)
|
||||
CONF.register_opts(glance_core_properties_opts)
|
||||
CONF.import_opt('glance_api_version', 'cinder.common.config')
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
@ -82,10 +81,8 @@ def _parse_image_ref(image_href):
|
||||
return (image_id, netloc, use_ssl)
|
||||
|
||||
|
||||
def _create_glance_client(context, netloc, use_ssl, version=None):
|
||||
def _create_glance_client(context, netloc, use_ssl):
|
||||
"""Instantiate a new glanceclient.Client object."""
|
||||
if version is None:
|
||||
version = CONF.glance_api_version
|
||||
params = {}
|
||||
if use_ssl:
|
||||
scheme = 'https'
|
||||
@ -101,7 +98,7 @@ def _create_glance_client(context, netloc, use_ssl, version=None):
|
||||
params['timeout'] = CONF.glance_request_timeout
|
||||
endpoint = '%s://%s' % (scheme, netloc)
|
||||
params['global_request_id'] = context.global_id
|
||||
return glanceclient.Client(str(version), endpoint, **params)
|
||||
return glanceclient.Client('2', endpoint, **params)
|
||||
|
||||
|
||||
def get_api_servers(context):
|
||||
@ -147,34 +144,31 @@ def get_api_servers(context):
|
||||
class GlanceClientWrapper(object):
|
||||
"""Glance client wrapper class that implements retries."""
|
||||
|
||||
def __init__(self, context=None, netloc=None, use_ssl=False,
|
||||
version=None):
|
||||
def __init__(self, context=None, netloc=None, use_ssl=False):
|
||||
if netloc is not None:
|
||||
self.client = self._create_static_client(context,
|
||||
netloc,
|
||||
use_ssl, version)
|
||||
use_ssl)
|
||||
else:
|
||||
self.client = None
|
||||
self.api_servers = None
|
||||
self.version = version
|
||||
|
||||
def _create_static_client(self, context, netloc, use_ssl, version):
|
||||
def _create_static_client(self, context, netloc, use_ssl):
|
||||
"""Create a client that we'll use for every call."""
|
||||
self.netloc = netloc
|
||||
self.use_ssl = use_ssl
|
||||
self.version = version
|
||||
return _create_glance_client(context,
|
||||
self.netloc,
|
||||
self.use_ssl, self.version)
|
||||
self.use_ssl)
|
||||
|
||||
def _create_onetime_client(self, context, version):
|
||||
def _create_onetime_client(self, context):
|
||||
"""Create a client that will be used for one call."""
|
||||
if self.api_servers is None:
|
||||
self.api_servers = get_api_servers(context)
|
||||
self.netloc, self.use_ssl = next(self.api_servers)
|
||||
return _create_glance_client(context,
|
||||
self.netloc,
|
||||
self.use_ssl, version)
|
||||
self.use_ssl)
|
||||
|
||||
def call(self, context, method, *args, **kwargs):
|
||||
"""Call a glance client method.
|
||||
@ -182,7 +176,6 @@ class GlanceClientWrapper(object):
|
||||
If we get a connection error,
|
||||
retry the request according to CONF.glance_num_retries.
|
||||
"""
|
||||
version = kwargs.pop('version', self.version)
|
||||
|
||||
retry_excs = (glanceclient.exc.ServiceUnavailable,
|
||||
glanceclient.exc.InvalidEndpoint,
|
||||
@ -190,8 +183,7 @@ class GlanceClientWrapper(object):
|
||||
num_attempts = 1 + CONF.glance_num_retries
|
||||
|
||||
for attempt in range(1, num_attempts + 1):
|
||||
client = self.client or self._create_onetime_client(context,
|
||||
version)
|
||||
client = self.client or self._create_onetime_client(context)
|
||||
try:
|
||||
controller = getattr(client,
|
||||
kwargs.pop('controller', 'images'))
|
||||
@ -248,16 +240,6 @@ class GlanceImageService(object):
|
||||
if param in params:
|
||||
_params[param] = params.get(param)
|
||||
|
||||
# NOTE(geguileo): We set is_public default value for v1 because we want
|
||||
# to retrieve all images by default. We don't need to send v2
|
||||
# equivalent - "visible" - because its default value when omitted is
|
||||
# "public, private, shared", which will return all.
|
||||
if CONF.glance_api_version <= 1:
|
||||
# ensure filters is a dict
|
||||
_params.setdefault('filters', {})
|
||||
# NOTE(vish): don't filter out private images
|
||||
_params['filters'].setdefault('is_public', 'none')
|
||||
|
||||
return _params
|
||||
|
||||
def show(self, context, image_id):
|
||||
@ -280,12 +262,9 @@ class GlanceImageService(object):
|
||||
the backend storage location, or (None, None) if these attributes are
|
||||
not shown by Glance.
|
||||
"""
|
||||
if CONF.glance_api_version == 1:
|
||||
# image location not available in v1
|
||||
return (None, None)
|
||||
try:
|
||||
# direct_url is returned by v2 api
|
||||
client = GlanceClientWrapper(version=2)
|
||||
client = GlanceClientWrapper()
|
||||
image_meta = client.call(context, 'get', image_id)
|
||||
except Exception:
|
||||
_reraise_translated_image_exception(image_id)
|
||||
@ -304,9 +283,7 @@ class GlanceImageService(object):
|
||||
|
||||
Returns a dict containing image metadata on success.
|
||||
"""
|
||||
if CONF.glance_api_version != 2:
|
||||
raise exception.Invalid("Image API version 2 is disabled.")
|
||||
client = GlanceClientWrapper(version=2)
|
||||
client = GlanceClientWrapper()
|
||||
try:
|
||||
return client.call(context, 'add_location',
|
||||
image_id, url, metadata)
|
||||
@ -360,39 +337,30 @@ class GlanceImageService(object):
|
||||
# directly. We need the custom properties to identify properties to
|
||||
# remove if purge_props is True. Save the custom properties before
|
||||
# translate.
|
||||
if CONF.glance_api_version > 1 and purge_props:
|
||||
if purge_props:
|
||||
props_to_update = image_meta.get('properties', {}).keys()
|
||||
|
||||
image_meta = self._translate_to_glance(image_meta)
|
||||
# NOTE(dosaboy): see comment in bug 1210467
|
||||
if CONF.glance_api_version == 1:
|
||||
image_meta['purge_props'] = purge_props
|
||||
|
||||
# NOTE(bcwaldon): id is not an editable field, but it is likely to be
|
||||
# passed in by calling code. Let's be nice and ignore it.
|
||||
image_meta.pop('id', None)
|
||||
try:
|
||||
# NOTE(dosaboy): the v2 api separates update from upload
|
||||
if CONF.glance_api_version > 1:
|
||||
if data:
|
||||
self._client.call(context, 'upload', image_id, data)
|
||||
if image_meta:
|
||||
if purge_props:
|
||||
# Properties to remove are those not specified in
|
||||
# input properties.
|
||||
cur_image_meta = self.show(context, image_id)
|
||||
cur_props = cur_image_meta['properties'].keys()
|
||||
remove_props = list(set(cur_props) -
|
||||
set(props_to_update))
|
||||
image_meta['remove_props'] = remove_props
|
||||
image_meta = self._client.call(context, 'update', image_id,
|
||||
**image_meta)
|
||||
else:
|
||||
image_meta = self._client.call(context, 'get', image_id)
|
||||
else:
|
||||
if data:
|
||||
image_meta['data'] = data
|
||||
if data:
|
||||
self._client.call(context, 'upload', image_id, data)
|
||||
if image_meta:
|
||||
if purge_props:
|
||||
# Properties to remove are those not specified in
|
||||
# input properties.
|
||||
cur_image_meta = self.show(context, image_id)
|
||||
cur_props = cur_image_meta['properties'].keys()
|
||||
remove_props = list(set(cur_props) -
|
||||
set(props_to_update))
|
||||
image_meta['remove_props'] = remove_props
|
||||
image_meta = self._client.call(context, 'update', image_id,
|
||||
**image_meta)
|
||||
else:
|
||||
image_meta = self._client.call(context, 'get', image_id)
|
||||
except Exception:
|
||||
_reraise_translated_image_exception(image_id)
|
||||
else:
|
||||
@ -420,27 +388,23 @@ class GlanceImageService(object):
|
||||
:param image: glance image object
|
||||
:return: image metadata dictionary
|
||||
"""
|
||||
if CONF.glance_api_version == 2:
|
||||
if self._image_schema is None:
|
||||
self._image_schema = self._client.call(context, 'get',
|
||||
controller='schemas',
|
||||
schema_name='image',
|
||||
version=2)
|
||||
# NOTE(aarefiev): get base image property, store image 'schema'
|
||||
# is redundant, so ignore it.
|
||||
image_meta = {key: getattr(image, key)
|
||||
for key in image.keys()
|
||||
if self._image_schema.is_base_property(key) is True
|
||||
and key != 'schema'}
|
||||
if self._image_schema is None:
|
||||
self._image_schema = self._client.call(context, 'get',
|
||||
controller='schemas',
|
||||
schema_name='image')
|
||||
# NOTE(aarefiev): get base image property, store image 'schema'
|
||||
# is redundant, so ignore it.
|
||||
image_meta = {key: getattr(image, key)
|
||||
for key in image.keys()
|
||||
if self._image_schema.is_base_property(key) is True
|
||||
and key != 'schema'}
|
||||
|
||||
# NOTE(aarefiev): nova is expected that all image properties
|
||||
# (custom or defined in schema-image.json) stores in
|
||||
# 'properties' key.
|
||||
image_meta['properties'] = {
|
||||
key: getattr(image, key) for key in image.keys()
|
||||
if self._image_schema.is_base_property(key) is False}
|
||||
else:
|
||||
image_meta = _extract_attributes(image)
|
||||
# NOTE(aarefiev): nova is expected that all image properties
|
||||
# (custom or defined in schema-image.json) stores in
|
||||
# 'properties' key.
|
||||
image_meta['properties'] = {
|
||||
key: getattr(image, key) for key in image.keys()
|
||||
if self._image_schema.is_base_property(key) is False}
|
||||
|
||||
image_meta = _convert_timestamps_to_datetimes(image_meta)
|
||||
image_meta = _convert_from_string(image_meta)
|
||||
@ -453,11 +417,10 @@ class GlanceImageService(object):
|
||||
|
||||
# NOTE(tsekiyama): From the Image API v2, custom properties must
|
||||
# be stored in image_meta directly, instead of the 'properties' key.
|
||||
if CONF.glance_api_version >= 2:
|
||||
properties = image_meta.get('properties')
|
||||
if properties:
|
||||
image_meta.update(properties)
|
||||
del image_meta['properties']
|
||||
properties = image_meta.get('properties')
|
||||
if properties:
|
||||
image_meta.update(properties)
|
||||
del image_meta['properties']
|
||||
|
||||
return image_meta
|
||||
|
||||
@ -545,11 +508,8 @@ def _extract_attributes(image):
|
||||
'container_format', 'status', 'id',
|
||||
'name', 'created_at', 'updated_at',
|
||||
'deleted', 'deleted_at', 'checksum',
|
||||
'min_disk', 'min_ram', 'protected']
|
||||
if CONF.glance_api_version == 2:
|
||||
IMAGE_ATTRIBUTES.append('visibility')
|
||||
else:
|
||||
IMAGE_ATTRIBUTES.append('is_public')
|
||||
'min_disk', 'min_ram', 'protected',
|
||||
'visibility']
|
||||
|
||||
output = {}
|
||||
|
||||
|
@ -1327,8 +1327,6 @@ class VolumeImageActionsTest(test.TestCase):
|
||||
mock_copy_volume_to_image.side_effect = \
|
||||
self.fake_rpc_copy_volume_to_image
|
||||
|
||||
self.override_config('glance_api_version', 2)
|
||||
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, volume.id),
|
||||
use_admin_context=self.context.is_admin)
|
||||
|
@ -108,7 +108,7 @@ class TestGlanceImageService(test.TestCase):
|
||||
self.mock_object(glance.time, 'sleep', return_value=None)
|
||||
|
||||
def _create_image_service(self, client):
|
||||
def _fake_create_glance_client(context, netloc, use_ssl, version):
|
||||
def _fake_create_glance_client(context, netloc, use_ssl):
|
||||
return client
|
||||
|
||||
self.mock_object(glance, '_create_glance_client',
|
||||
@ -251,19 +251,8 @@ class TestGlanceImageService(test.TestCase):
|
||||
self.assertEqual('test image', image_metas[0]['name'])
|
||||
self.assertEqual('private', image_metas[0]['visibility'])
|
||||
|
||||
def test_detail_v1(self):
|
||||
"""Confirm we send is_public = None as default when using Glance v1."""
|
||||
self.override_config('glance_api_version', 1)
|
||||
with mock.patch.object(self.service, '_client') as client_mock:
|
||||
client_mock.return_value = []
|
||||
result = self.service.detail(self.context)
|
||||
self.assertListEqual([], result)
|
||||
client_mock.call.assert_called_once_with(self.context, 'list',
|
||||
filters={'is_public': 'none'})
|
||||
|
||||
def test_detail_v2(self):
|
||||
"""Check we don't send is_public key by default with Glance v2."""
|
||||
self.override_config('glance_api_version', 2)
|
||||
with mock.patch.object(self.service, '_client') as client_mock:
|
||||
client_mock.return_value = []
|
||||
result = self.service.detail(self.context)
|
||||
@ -381,10 +370,6 @@ class TestGlanceImageService(test.TestCase):
|
||||
new_image_data = self.service.show(self.context, image_id)
|
||||
self.assertEqual('new image name', new_image_data['name'])
|
||||
|
||||
def test_update_v2(self):
|
||||
self.flags(glance_api_version=2)
|
||||
self.test_update()
|
||||
|
||||
def test_update_with_data(self):
|
||||
fixture = self._make_fixture(name='test image')
|
||||
image = self.service.create(self.context, fixture)
|
||||
@ -397,37 +382,21 @@ class TestGlanceImageService(test.TestCase):
|
||||
self.assertEqual(256, new_image_data['size'])
|
||||
self.assertEqual('new image name', new_image_data['name'])
|
||||
|
||||
def test_update_with_data_v2(self):
|
||||
self.flags(glance_api_version=2)
|
||||
self.test_update_with_data()
|
||||
|
||||
@mock.patch.object(glance.GlanceImageService, '_translate_from_glance')
|
||||
@mock.patch.object(glance.GlanceImageService, 'show')
|
||||
@ddt.data(1, 2)
|
||||
def test_update_purge_props(self, ver, show, translate_from_glance):
|
||||
self.flags(glance_api_version=ver)
|
||||
|
||||
def test_update_purge_props(self, show, translate_from_glance):
|
||||
image_id = mock.sentinel.image_id
|
||||
client = mock.Mock(call=mock.Mock())
|
||||
service = glance.GlanceImageService(client=client)
|
||||
|
||||
image_meta = {'properties': {'k1': 'v1'}}
|
||||
client.call.return_value = {'k1': 'v1'}
|
||||
if ver == 2:
|
||||
show.return_value = {'properties': {'k2': 'v2'}}
|
||||
show.return_value = {'properties': {'k2': 'v2'}}
|
||||
translate_from_glance.return_value = image_meta.copy()
|
||||
|
||||
ret = service.update(self.context, image_id, image_meta)
|
||||
self.assertDictEqual(image_meta, ret)
|
||||
if ver == 2:
|
||||
client.call.assert_called_once_with(
|
||||
self.context, 'update', image_id, k1='v1', remove_props=['k2'])
|
||||
else:
|
||||
client.call.assert_called_once_with(
|
||||
self.context, 'update', image_id, properties={'k1': 'v1'},
|
||||
purge_props=True)
|
||||
translate_from_glance.assert_called_once_with(self.context,
|
||||
{'k1': 'v1'})
|
||||
client.call.assert_called_once_with(
|
||||
self.context, 'update', image_id, k1='v1', remove_props=['k2'])
|
||||
|
||||
def test_delete(self):
|
||||
fixture1 = self._make_fixture(name='test image 1')
|
||||
@ -619,7 +588,6 @@ class TestGlanceImageService(test.TestCase):
|
||||
image_id = self.service.create(self.context, fixture)['id']
|
||||
writer = NullWriter()
|
||||
self.flags(allowed_direct_url_schemes=['file'])
|
||||
self.flags(glance_api_version=2)
|
||||
self.service.download(self.context, image_id, writer)
|
||||
mock_copyfileobj.assert_called_once_with(mock.ANY, writer)
|
||||
|
||||
@ -634,7 +602,6 @@ class TestGlanceImageService(test.TestCase):
|
||||
image_id = self.service.create(self.context, fixture)['id']
|
||||
writer = NullWriter()
|
||||
self.flags(allowed_direct_url_schemes=['file'])
|
||||
self.flags(glance_api_version=2)
|
||||
self.service.download(self.context, image_id, writer)
|
||||
self.assertIsNone(mock_copyfileobj.call_args)
|
||||
|
||||
@ -709,7 +676,6 @@ class TestGlanceImageService(test.TestCase):
|
||||
@mock.patch('cinder.image.glance.CONF')
|
||||
def test_v2_passes_visibility_param(self, config):
|
||||
|
||||
config.glance_api_version = 2
|
||||
config.glance_num_retries = 0
|
||||
|
||||
metadata = {
|
||||
@ -749,7 +715,6 @@ class TestGlanceImageService(test.TestCase):
|
||||
@mock.patch('cinder.image.glance.CONF')
|
||||
def test_extracting_v2_boot_properties(self, config):
|
||||
|
||||
config.glance_api_version = 2
|
||||
config.glance_num_retries = 0
|
||||
|
||||
metadata = {
|
||||
@ -791,26 +756,6 @@ class TestGlanceImageService(test.TestCase):
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
def test_translate_to_glance(self):
|
||||
self.flags(glance_api_version=1)
|
||||
client = glance_stubs.StubGlanceClient()
|
||||
service = self._create_image_service(client)
|
||||
|
||||
metadata = {
|
||||
'id': 1,
|
||||
'size': 2,
|
||||
'min_disk': 2,
|
||||
'min_ram': 2,
|
||||
'properties': {'kernel_id': 'foo',
|
||||
'ramdisk_id': 'bar',
|
||||
'x_billinginfo': '123'},
|
||||
}
|
||||
|
||||
actual = service._translate_to_glance(metadata)
|
||||
expected = metadata
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
def test_translate_to_glance_v2(self):
|
||||
self.flags(glance_api_version=2)
|
||||
client = glance_stubs.StubGlanceClient()
|
||||
service = self._create_image_service(client)
|
||||
|
||||
@ -836,41 +781,6 @@ class TestGlanceImageService(test.TestCase):
|
||||
}
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
|
||||
class TestGlanceClientVersion(test.TestCase):
|
||||
"""Tests the version of the glance client generated."""
|
||||
|
||||
@mock.patch('cinder.image.glance.glanceclient.Client')
|
||||
def test_glance_version_by_flag(self, _mockglanceclient):
|
||||
"""Test glance version set by flag is honoured."""
|
||||
ctx = mock.MagicMock()
|
||||
glance.GlanceClientWrapper(ctx, 'fake_host', 9292)
|
||||
self.assertEqual('2', _mockglanceclient.call_args[0][0])
|
||||
self.flags(glance_api_version=1)
|
||||
glance.GlanceClientWrapper(ctx, 'fake_host', 9292)
|
||||
self.assertEqual('1', _mockglanceclient.call_args[0][0])
|
||||
CONF.reset()
|
||||
|
||||
@mock.patch('cinder.image.glance.glanceclient.Client')
|
||||
def test_glance_version_by_arg(self, _mockglanceclient):
|
||||
"""Test glance version set by arg to GlanceClientWrapper"""
|
||||
ctx = mock.MagicMock()
|
||||
glance.GlanceClientWrapper(ctx, 'fake_host', 9292, version=1)
|
||||
self.assertEqual('1', _mockglanceclient.call_args[0][0])
|
||||
glance.GlanceClientWrapper(ctx, 'fake_host', 9292, version=2)
|
||||
self.assertEqual('2', _mockglanceclient.call_args[0][0])
|
||||
|
||||
@mock.patch('cinder.image.glance.glanceclient.Client')
|
||||
@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()
|
||||
ctx = mock.MagicMock()
|
||||
glance_wrapper.call(ctx, 'method', version=2)
|
||||
|
||||
self.assertEqual('2', _mockglanceclient.call_args[0][0])
|
||||
|
||||
@mock.patch('cinder.image.glance.glanceclient.Client')
|
||||
@mock.patch('cinder.image.glance.get_api_servers',
|
||||
return_value=itertools.cycle([(False, 'localhost:9292')]))
|
||||
@ -882,8 +792,7 @@ class TestGlanceClientVersion(test.TestCase):
|
||||
side_effect=glanceclient.exc.HTTPOverLimit)
|
||||
self.mock_object(glance_wrapper, 'client', fake_client)
|
||||
self.assertRaises(exception.ImageLimitExceeded,
|
||||
glance_wrapper.call, 'fake_context', 'method',
|
||||
version=2)
|
||||
glance_wrapper.call, 'fake_context', 'method')
|
||||
|
||||
|
||||
def _create_failing_glance_client(info):
|
||||
@ -943,7 +852,7 @@ class TestGlanceImageServiceClient(test.TestCase):
|
||||
|
||||
class MyGlanceStubClient(object):
|
||||
def __init__(inst, version, *args, **kwargs):
|
||||
self.assertEqual("2", version)
|
||||
self.assertEqual('2', version)
|
||||
self.assertEqual("http://fake_host:9292", args[0])
|
||||
self.assertTrue(kwargs['token'])
|
||||
self.assertNotIn('timeout', kwargs)
|
||||
|
@ -269,7 +269,6 @@ class CopyVolumeToImageTestCase(base.BaseVolumeTestCase):
|
||||
def _test_copy_volume_to_image_with_image_volume(
|
||||
self, mock_copy, mock_create, mock_quota_commit,
|
||||
mock_quota_reserve):
|
||||
self.flags(glance_api_version=2)
|
||||
self.volume.driver.configuration.image_upload_use_cinder_backend = True
|
||||
self.addCleanup(fake_image.FakeImageService_reset)
|
||||
image_service = fake_image.FakeImageService()
|
||||
|
@ -225,8 +225,7 @@ volume_opts = [
|
||||
'create a cloned volume and register its location to '
|
||||
'the image service, instead of uploading the volume '
|
||||
'content. The cinder backend and locations support '
|
||||
'must be enabled in the image service, and '
|
||||
'glance_api_version must be set to 2.'),
|
||||
'must be enabled in the image service.'),
|
||||
cfg.BoolOpt('image_upload_use_internal_tenant',
|
||||
default=False,
|
||||
help='If set to True, the image volume created by '
|
||||
|
@ -38,7 +38,6 @@ Volume, set the following options in the ``DEFAULT`` section of the
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
glance_api_version = 2
|
||||
allowed_direct_url_schemes = cinder
|
||||
|
||||
To enable the :command:`openstack image create --volume <volume>` command to
|
||||
|
@ -213,8 +213,6 @@ To use this feature, you must configure the Block Storage service, as follows:
|
||||
- Set the ``netapp_copyoffload_tool_path`` configuration option to the path to
|
||||
the NetApp Copy Offload binary.
|
||||
|
||||
- Set the ``glance_api_version`` configuration option to ``2``.
|
||||
|
||||
.. important::
|
||||
|
||||
This feature requires that:
|
||||
|
@ -26,8 +26,6 @@
|
||||
- (List) 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.
|
||||
* - ``glance_api_ssl_compression`` = ``False``
|
||||
- (Boolean) Enables or disables negotiation of SSL layer compression. In some cases disabling compression can improve data throughput, such as when high network bandwidth is available and you use compressed image formats like qcow2.
|
||||
* - ``glance_api_version`` = ``1``
|
||||
- (Integer) Version of the glance API to use
|
||||
* - ``glance_ca_certificates_file`` = ``None``
|
||||
- (String) Location of ca certificates file to use for glance client requests.
|
||||
* - ``glance_catalog_info`` = ``image:glance:publicURL``
|
||||
@ -41,7 +39,7 @@
|
||||
* - ``image_conversion_dir`` = ``$state_path/conversion``
|
||||
- (String) Directory used for temporary storage during image conversion
|
||||
* - ``image_upload_use_cinder_backend`` = ``False``
|
||||
- (Boolean) If set to True, upload-to-image in raw format will create a cloned volume and register its location to the image service, instead of uploading the volume content. The cinder backend and locations support must be enabled in the image service, and glance_api_version must be set to 2.
|
||||
- (Boolean) If set to True, upload-to-image in raw format will create a cloned volume and register its location to the image service, instead of uploading the volume content. The cinder backend and locations support must be enabled in the image service.
|
||||
* - ``image_upload_use_internal_tenant`` = ``False``
|
||||
- (Boolean) If set to True, the image volume created by upload-to-image will be placed in the internal tenant. Otherwise, the image volume is created in the current context's tenant.
|
||||
* - ``image_volume_cache_enabled`` = ``False``
|
||||
|
@ -0,0 +1,7 @@
|
||||
---
|
||||
upgrade:
|
||||
- |
|
||||
The Glance v1 API has been deprecated and will soon be removed. Cinder
|
||||
support for using the v1 API was deprecated in the Pike release and
|
||||
is now no longer available. The ``glance_api_version`` configuration
|
||||
option to support version selection has now been removed.
|
Loading…
x
Reference in New Issue
Block a user