Bump Image API version to 2.16
This API version increment is due to change I6a875a38bef5, which corrected the response code for the admin-only API call: PUT /v2/cache/{image_id} The call now returns 202 upon success (it had been returning 200). The intent of this version bump is to get the attention of operators to take note of this change; from now on, the call always returns 202 upon success regardless of what API version you request. Additionally, cleaned up some version tests that had gotten out of date and were not thoroughly testing version negotiation. Also, corrected the version negotiation code around the v2.13 API. The versions response had been modified by change I6882fd2381e6 to only include v2.13 when the 'enabled_backends' config option had a value, but the versions negotiation code was not updated to reflect that. Change-Id: I0cf35ed7e21497826cd581e59aa58774f030b9f6 Related-bug: #1971521
This commit is contained in:
parent
2e94e3dc71
commit
11989a18f4
@ -82,15 +82,16 @@ class VersionNegotiationFilter(wsgi.Middleware):
|
|||||||
allowed_versions['v2.6'] = 2
|
allowed_versions['v2.6'] = 2
|
||||||
allowed_versions['v2.7'] = 2
|
allowed_versions['v2.7'] = 2
|
||||||
allowed_versions['v2.9'] = 2
|
allowed_versions['v2.9'] = 2
|
||||||
allowed_versions['v2.13'] = 2
|
|
||||||
if CONF.image_cache_dir:
|
if CONF.image_cache_dir:
|
||||||
allowed_versions['v2.14'] = 2
|
allowed_versions['v2.14'] = 2
|
||||||
|
allowed_versions['v2.16'] = 2
|
||||||
allowed_versions['v2.15'] = 2
|
allowed_versions['v2.15'] = 2
|
||||||
if CONF.enabled_backends:
|
if CONF.enabled_backends:
|
||||||
allowed_versions['v2.8'] = 2
|
allowed_versions['v2.8'] = 2
|
||||||
allowed_versions['v2.10'] = 2
|
allowed_versions['v2.10'] = 2
|
||||||
allowed_versions['v2.11'] = 2
|
allowed_versions['v2.11'] = 2
|
||||||
allowed_versions['v2.12'] = 2
|
allowed_versions['v2.12'] = 2
|
||||||
|
allowed_versions['v2.13'] = 2
|
||||||
return allowed_versions
|
return allowed_versions
|
||||||
|
|
||||||
def _match_version_string(self, subject):
|
def _match_version_string(self, subject):
|
||||||
|
@ -79,7 +79,8 @@ class Controller(object):
|
|||||||
version_objs = []
|
version_objs = []
|
||||||
if CONF.image_cache_dir:
|
if CONF.image_cache_dir:
|
||||||
version_objs.extend([
|
version_objs.extend([
|
||||||
build_version_object(2.15, 'v2', 'CURRENT'),
|
build_version_object(2.16, 'v2', 'CURRENT'),
|
||||||
|
build_version_object(2.15, 'v2', 'SUPPORTED'),
|
||||||
build_version_object(2.14, 'v2', 'SUPPORTED'),
|
build_version_object(2.14, 'v2', 'SUPPORTED'),
|
||||||
])
|
])
|
||||||
else:
|
else:
|
||||||
|
@ -139,12 +139,19 @@ def get_versions_list(url, enabled_backends=False,
|
|||||||
] + image_versions[2:]
|
] + image_versions[2:]
|
||||||
|
|
||||||
if enabled_cache:
|
if enabled_cache:
|
||||||
|
image_versions[0]['status'] = 'SUPPORTED'
|
||||||
image_versions.insert(1, {
|
image_versions.insert(1, {
|
||||||
'id': 'v2.14',
|
'id': 'v2.14',
|
||||||
'status': 'SUPPORTED',
|
'status': 'SUPPORTED',
|
||||||
'links': [{'rel': 'self',
|
'links': [{'rel': 'self',
|
||||||
'href': '%s/v2/' % url}],
|
'href': '%s/v2/' % url}],
|
||||||
})
|
})
|
||||||
|
image_versions.insert(0, {
|
||||||
|
'id': 'v2.16',
|
||||||
|
'status': 'CURRENT',
|
||||||
|
'links': [{'rel': 'self',
|
||||||
|
'href': '%s/v2/' % url}],
|
||||||
|
})
|
||||||
|
|
||||||
return image_versions
|
return image_versions
|
||||||
|
|
||||||
@ -341,6 +348,11 @@ class VersionNegotiationTest(base.IsolatedUnitTest):
|
|||||||
self.middleware.process_request(request)
|
self.middleware.process_request(request)
|
||||||
self.assertEqual('/v2/images', request.path_info)
|
self.assertEqual('/v2/images', request.path_info)
|
||||||
|
|
||||||
|
def test_request_url_v2_15(self):
|
||||||
|
request = webob.Request.blank('/v2.15/images')
|
||||||
|
self.middleware.process_request(request)
|
||||||
|
self.assertEqual('/v2/images', request.path_info)
|
||||||
|
|
||||||
# note: these need separate unsupported/supported tests to reset the
|
# note: these need separate unsupported/supported tests to reset the
|
||||||
# the memoized allowed_versions in the VersionNegotiationFilter instance
|
# the memoized allowed_versions in the VersionNegotiationFilter instance
|
||||||
def test_request_url_v2_8_default_unsupported(self):
|
def test_request_url_v2_8_default_unsupported(self):
|
||||||
@ -387,31 +399,48 @@ class VersionNegotiationTest(base.IsolatedUnitTest):
|
|||||||
self.middleware.process_request(request)
|
self.middleware.process_request(request)
|
||||||
self.assertEqual('/v2/images', request.path_info)
|
self.assertEqual('/v2/images', request.path_info)
|
||||||
|
|
||||||
|
def test_request_url_v2_13_default_unsupported(self):
|
||||||
|
request = webob.Request.blank('/v2.13/images')
|
||||||
|
resp = self.middleware.process_request(request)
|
||||||
|
self.assertIsInstance(resp, versions.Controller)
|
||||||
|
|
||||||
def test_request_url_v2_13_enabled_supported(self):
|
def test_request_url_v2_13_enabled_supported(self):
|
||||||
|
self.config(enabled_backends='slow:one,fast:two')
|
||||||
request = webob.Request.blank('/v2.13/images')
|
request = webob.Request.blank('/v2.13/images')
|
||||||
self.middleware.process_request(request)
|
self.middleware.process_request(request)
|
||||||
self.assertEqual('/v2/images', request.path_info)
|
self.assertEqual('/v2/images', request.path_info)
|
||||||
|
|
||||||
|
def test_request_url_v2_14_default_unsupported(self):
|
||||||
|
request = webob.Request.blank('/v2.14/images')
|
||||||
|
resp = self.middleware.process_request(request)
|
||||||
|
self.assertIsInstance(resp, versions.Controller)
|
||||||
|
|
||||||
def test_request_url_v2_14_enabled_supported(self):
|
def test_request_url_v2_14_enabled_supported(self):
|
||||||
self.config(image_cache_dir='/tmp/cache')
|
self.config(image_cache_dir='/tmp/cache')
|
||||||
request = webob.Request.blank('/v2.14/images')
|
request = webob.Request.blank('/v2.14/images')
|
||||||
self.middleware.process_request(request)
|
self.middleware.process_request(request)
|
||||||
self.assertEqual('/v2/images', request.path_info)
|
self.assertEqual('/v2/images', request.path_info)
|
||||||
|
|
||||||
def test_request_url_v2_15_enabled_supported(self):
|
|
||||||
request = webob.Request.blank('/v2.15/images')
|
|
||||||
self.middleware.process_request(request)
|
|
||||||
self.assertEqual('/v2/images', request.path_info)
|
|
||||||
|
|
||||||
# version 2.16 does not exist
|
|
||||||
def test_request_url_v2_16_default_unsupported(self):
|
def test_request_url_v2_16_default_unsupported(self):
|
||||||
request = webob.Request.blank('/v2.16/images')
|
request = webob.Request.blank('/v2.16/images')
|
||||||
resp = self.middleware.process_request(request)
|
resp = self.middleware.process_request(request)
|
||||||
self.assertIsInstance(resp, versions.Controller)
|
self.assertIsInstance(resp, versions.Controller)
|
||||||
|
|
||||||
def test_request_url_v2_16_enabled_unsupported(self):
|
def test_request_url_v2_16_enabled_supported(self):
|
||||||
self.config(enabled_backends='slow:one,fast:two')
|
self.config(image_cache_dir='/tmp/cache')
|
||||||
request = webob.Request.blank('/v2.16/images')
|
request = webob.Request.blank('/v2.16/images')
|
||||||
|
self.middleware.process_request(request)
|
||||||
|
self.assertEqual('/v2/images', request.path_info)
|
||||||
|
|
||||||
|
# version 2.17 does not exist
|
||||||
|
def test_request_url_v2_17_default_unsupported(self):
|
||||||
|
request = webob.Request.blank('/v2.17/images')
|
||||||
|
resp = self.middleware.process_request(request)
|
||||||
|
self.assertIsInstance(resp, versions.Controller)
|
||||||
|
|
||||||
|
def test_request_url_v2_17_enabled_unsupported(self):
|
||||||
|
self.config(enabled_backends='slow:one,fast:two')
|
||||||
|
request = webob.Request.blank('/v2.17/images')
|
||||||
resp = self.middleware.process_request(request)
|
resp = self.middleware.process_request(request)
|
||||||
self.assertIsInstance(resp, versions.Controller)
|
self.assertIsInstance(resp, versions.Controller)
|
||||||
|
|
||||||
@ -438,38 +467,54 @@ class VersionsAndNegotiationTest(VersionNegotiationTest, VersionsTest):
|
|||||||
expected = "/%s/images" % major
|
expected = "/%s/images" % major
|
||||||
self.assertEqual(expected, request.path_info)
|
self.assertEqual(expected, request.path_info)
|
||||||
|
|
||||||
# the content of the version list depends on whether
|
# the content of the version list depends on two configuration
|
||||||
# CONF.enabled_backends is set or not, so check both cases
|
# options:
|
||||||
default = ''
|
# - CONF.enabled_backends
|
||||||
enabled = 'slow:one,fast:two'
|
# - CONF.image_cache_dir
|
||||||
|
# So we need to check a bunch of combinations
|
||||||
|
cache = '/var/cache'
|
||||||
|
multistore = 'slow:one,fast:two'
|
||||||
|
|
||||||
@ddt.data(default, enabled)
|
combos = ((None, None),
|
||||||
def test_current_is_negotiated(self, stores):
|
(None, multistore),
|
||||||
|
(cache, None),
|
||||||
|
(cache, multistore))
|
||||||
|
|
||||||
|
@ddt.data(*combos)
|
||||||
|
@ddt.unpack
|
||||||
|
def test_current_is_negotiated(self, cache, multistore):
|
||||||
# NOTE(rosmaita): Bug 1609571: the versions response was correct, but
|
# NOTE(rosmaita): Bug 1609571: the versions response was correct, but
|
||||||
# the negotiation had not been updated for the CURRENT version.
|
# the negotiation had not been updated for the CURRENT version.
|
||||||
self.config(enabled_backends=stores)
|
self.config(enabled_backends=multistore)
|
||||||
|
self.config(image_cache_dir=cache)
|
||||||
to_check = self._get_list_of_version_ids('CURRENT')
|
to_check = self._get_list_of_version_ids('CURRENT')
|
||||||
self.assertTrue(to_check)
|
self.assertTrue(to_check)
|
||||||
for version_id in to_check:
|
for version_id in to_check:
|
||||||
self._assert_version_is_negotiated(version_id)
|
self._assert_version_is_negotiated(version_id)
|
||||||
|
|
||||||
@ddt.data(default, enabled)
|
@ddt.data(*combos)
|
||||||
def test_supported_is_negotiated(self, stores):
|
@ddt.unpack
|
||||||
self.config(enabled_backends=stores)
|
def test_supported_is_negotiated(self, cache, multistore):
|
||||||
|
self.config(enabled_backends=multistore)
|
||||||
|
self.config(image_cache_dir=cache)
|
||||||
to_check = self._get_list_of_version_ids('SUPPORTED')
|
to_check = self._get_list_of_version_ids('SUPPORTED')
|
||||||
for version_id in to_check:
|
for version_id in to_check:
|
||||||
self._assert_version_is_negotiated(version_id)
|
self._assert_version_is_negotiated(version_id)
|
||||||
|
|
||||||
@ddt.data(default, enabled)
|
@ddt.data(*combos)
|
||||||
def test_deprecated_is_negotiated(self, stores):
|
@ddt.unpack
|
||||||
self.config(enabled_backends=stores)
|
def test_deprecated_is_negotiated(self, cache, multistore):
|
||||||
|
self.config(enabled_backends=multistore)
|
||||||
|
self.config(image_cache_dir=cache)
|
||||||
to_check = self._get_list_of_version_ids('DEPRECATED')
|
to_check = self._get_list_of_version_ids('DEPRECATED')
|
||||||
for version_id in to_check:
|
for version_id in to_check:
|
||||||
self._assert_version_is_negotiated(version_id)
|
self._assert_version_is_negotiated(version_id)
|
||||||
|
|
||||||
@ddt.data(default, enabled)
|
@ddt.data(*combos)
|
||||||
def test_experimental_is_negotiated(self, stores):
|
@ddt.unpack
|
||||||
self.config(enabled_backends=stores)
|
def test_experimental_is_negotiated(self, cache, multistore):
|
||||||
|
self.config(enabled_backends=multistore)
|
||||||
|
self.config(image_cache_dir=cache)
|
||||||
to_check = self._get_list_of_version_ids('EXPERIMENTAL')
|
to_check = self._get_list_of_version_ids('EXPERIMENTAL')
|
||||||
for version_id in to_check:
|
for version_id in to_check:
|
||||||
self._assert_version_is_negotiated(version_id)
|
self._assert_version_is_negotiated(version_id)
|
||||||
|
19
releasenotes/notes/api-2.16-8417b1e23322fedb.yaml
Normal file
19
releasenotes/notes/api-2.16-8417b1e23322fedb.yaml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
When the Glance image cache is being used, the CURRENT version of
|
||||||
|
the Image service API, as indicated in the ``GET /versions`` response,
|
||||||
|
is 2.16.
|
||||||
|
|
||||||
|
upgrade:
|
||||||
|
- |
|
||||||
|
The Image service API call ``PUT /v2/cache/{image_id}`` now returns
|
||||||
|
a 202 (Accepted) response code to indicate success. In glance 24.0.0
|
||||||
|
(the initial Yoga release), it had mistakenly returned a 200.
|
||||||
|
|
||||||
|
fixes:
|
||||||
|
- |
|
||||||
|
Bug `1971521 <https://bugs.launchpad.net/glance/+bug/1971521>`_:
|
||||||
|
Fixed the success response code of the REST API call
|
||||||
|
``PUT /v2/cache/{image_id}`` to be 202 (Accepted), following the
|
||||||
|
original design of the feature.
|
Loading…
x
Reference in New Issue
Block a user