diff --git a/api-ref/source/versions/index.rst b/api-ref/source/versions/index.rst index b2fe30f392..2468a1a74a 100644 --- a/api-ref/source/versions/index.rst +++ b/api-ref/source/versions/index.rst @@ -24,6 +24,10 @@ Image Service Versions Version History *************** +**Pike changes** + +- version 2.6 is EXPERIMENTAL + **Ocata changes** - version 2.5 is CURRENT diff --git a/api-ref/source/versions/samples/image-versions-response.json b/api-ref/source/versions/samples/image-versions-response.json index df42d87775..8c9fdf886d 100644 --- a/api-ref/source/versions/samples/image-versions-response.json +++ b/api-ref/source/versions/samples/image-versions-response.json @@ -1,5 +1,15 @@ { "versions": [ + { + "id": "v2.6", + "links": [ + { + "href": "http://glance.openstack.example.org/v2/", + "rel": "self" + } + ], + "status": "EXPERIMENTAL" + }, { "id": "v2.5", "links": [ diff --git a/glance/api/middleware/version_negotiation.py b/glance/api/middleware/version_negotiation.py index 8d30fffedd..12839ef801 100644 --- a/glance/api/middleware/version_negotiation.py +++ b/glance/api/middleware/version_negotiation.py @@ -84,6 +84,7 @@ class VersionNegotiationFilter(wsgi.Middleware): allowed_versions['v2.3'] = 2 allowed_versions['v2.4'] = 2 allowed_versions['v2.5'] = 2 + allowed_versions['v2.6'] = 2 return allowed_versions def _match_version_string(self, subject): diff --git a/glance/api/versions.py b/glance/api/versions.py index 8bcc9fd2fe..1d5a05d854 100644 --- a/glance/api/versions.py +++ b/glance/api/versions.py @@ -74,6 +74,7 @@ class Controller(object): version_objs = [] if CONF.enable_v2_api: version_objs.extend([ + build_version_object(2.6, 'v2', 'EXPERIMENTAL'), build_version_object(2.5, 'v2', 'CURRENT'), build_version_object(2.4, 'v2', 'SUPPORTED'), build_version_object(2.3, 'v2', 'SUPPORTED'), diff --git a/glance/tests/functional/test_api.py b/glance/tests/functional/test_api.py index 26af8c150b..47b6e03bea 100644 --- a/glance/tests/functional/test_api.py +++ b/glance/tests/functional/test_api.py @@ -32,6 +32,11 @@ class TestApiVersions(functional.FunctionalTest): url = 'http://127.0.0.1:%d/v%%s/' % self.api_port versions = {'versions': [ + { + 'id': 'v2.6', + 'status': 'EXPERIMENTAL', + 'links': [{'rel': 'self', 'href': url % '2'}], + }, { 'id': 'v2.5', 'status': 'CURRENT', @@ -89,6 +94,11 @@ class TestApiVersions(functional.FunctionalTest): url = 'http://127.0.0.1:%d/v%%s/' % self.api_port versions = {'versions': [ + { + 'id': 'v2.6', + 'status': 'EXPERIMENTAL', + 'links': [{'rel': 'self', 'href': url % '2'}], + }, { 'id': 'v2.5', 'status': 'CURRENT', @@ -164,6 +174,11 @@ class TestApiPaths(functional.FunctionalTest): url = 'http://127.0.0.1:%d/v%%s/' % self.api_port self.versions = {'versions': [ + { + 'id': 'v2.6', + 'status': 'EXPERIMENTAL', + 'links': [{'rel': 'self', 'href': url % '2'}], + }, { 'id': 'v2.5', 'status': 'CURRENT', diff --git a/glance/tests/unit/test_versions.py b/glance/tests/unit/test_versions.py index aed722a717..6074bda69d 100644 --- a/glance/tests/unit/test_versions.py +++ b/glance/tests/unit/test_versions.py @@ -36,6 +36,12 @@ class VersionsTest(base.IsolatedUnitTest): self.assertEqual('application/json', res.content_type) results = jsonutils.loads(res.body)['versions'] expected = [ + { + 'id': 'v2.6', + 'status': 'EXPERIMENTAL', + 'links': [{'rel': 'self', + 'href': 'http://127.0.0.1:9292/v2/'}], + }, { 'id': 'v2.5', 'status': 'CURRENT', @@ -97,6 +103,12 @@ class VersionsTest(base.IsolatedUnitTest): self.assertEqual('application/json', res.content_type) results = jsonutils.loads(res.body)['versions'] expected = [ + { + 'id': 'v2.6', + 'status': 'EXPERIMENTAL', + 'links': [{'rel': 'self', + 'href': 'https://example.com:9292/v2/'}], + }, { 'id': 'v2.5', 'status': 'CURRENT', @@ -157,6 +169,12 @@ class VersionsTest(base.IsolatedUnitTest): self.assertEqual('application/json', res.content_type) results = jsonutils.loads(res.body)['versions'] expected = [ + { + 'id': 'v2.6', + 'status': 'EXPERIMENTAL', + 'links': [{'rel': 'self', + 'href': 'http://localhost:9292/v2/'}], + }, { 'id': 'v2.5', 'status': 'CURRENT', @@ -218,6 +236,12 @@ class VersionsTest(base.IsolatedUnitTest): self.assertEqual('application/json', res.content_type) results = jsonutils.loads(res.body)['versions'] expected = [ + { + 'id': 'v2.6', + 'status': 'EXPERIMENTAL', + 'links': [{'rel': 'self', + 'href': 'https://localhost:9292/v2/'}], + }, { 'id': 'v2.5', 'status': 'CURRENT', @@ -332,13 +356,18 @@ class VersionNegotiationTest(base.IsolatedUnitTest): self.middleware.process_request(request) self.assertEqual('/v2/images', request.path_info) - def test_request_url_v2_6_unsupported(self): + def test_request_url_v2_6(self): request = webob.Request.blank('/v2.6/images') + self.middleware.process_request(request) + self.assertEqual('/v2/images', request.path_info) + + def test_request_url_v2_7_unsupported(self): + request = webob.Request.blank('/v2.7/images') resp = self.middleware.process_request(request) self.assertIsInstance(resp, versions.Controller) - def test_request_url_v4_unsupported(self): - request = webob.Request.blank('/v4/images') + def test_request_url_v3_unsupported(self): + request = webob.Request.blank('/v3/images') resp = self.middleware.process_request(request) self.assertIsInstance(resp, versions.Controller) @@ -381,3 +410,8 @@ class VersionsAndNegotiationTest(VersionNegotiationTest, VersionsTest): to_check = self._get_list_of_version_ids('DEPRECATED') for version_id in to_check: self._assert_version_is_negotiated(version_id) + + def test_experimental_is_negotiated(self): + to_check = self._get_list_of_version_ids('EXPERIMENTAL') + for version_id in to_check: + self._assert_version_is_negotiated(version_id) diff --git a/releasenotes/notes/api-minor-ver-bump-2-6-aa3591fc58f08055.yaml b/releasenotes/notes/api-minor-ver-bump-2-6-aa3591fc58f08055.yaml new file mode 100644 index 0000000000..73c3baba75 --- /dev/null +++ b/releasenotes/notes/api-minor-ver-bump-2-6-aa3591fc58f08055.yaml @@ -0,0 +1,26 @@ +--- +prelude: > + - The *minor* version of the Images API v2 is bumped to **2.6** + to introduce an EXPERIMENTAL version of the API that includes + the new calls introduced for the Minimal Viable Product delivery + of the `refactored image import`_ functionality. Version **2.5** + remains the CURRENT version of the Images API. +upgrade: + - | + An **EXPERIMENTAL** version of the Images API supplied by Glance + is introduced as **2.6**. It includes the new API calls introduced + for the `refactored image import`_ functionality. This functionality + is **not** enabled by default, so the CURRENT version of the Images + API remains at 2.5. There are no changes to the version 2.5 API in + this release, so all version 2.5 calls will work whether or not the + new import functionality is enabled or not. + + The version 2.6 API is being introduced as EXPERIMENTAL because it + is a Minimal Viable Product delivery of the functionality described + in the `refactored image import`_ specification. As an MVP, the + responses described in that specification are abbreviated in version + 2.6. It is expected that version 2.6 will be completed in Queens, + but at this time, we encourage operators to try out the new + functionality, but keep in mind its EXPERIMENTAL nature. + + .. _`refactored image import`: https://specs.openstack.org/openstack/glance-specs/specs/mitaka/approved/image-import/image-import-refactor.html