Support pulling of schema2 manifests directly via a manifest list tag
This change ensures that if a manifest list is requested with an accepts header for a *schema 2* manifest, the legacy manifest (if any) is returned as schema 2 if it was pushed as a schema 2 manifest (rather than being auto-converted to schema 1)
This commit is contained in:
		
							parent
							
								
									a35982f2be
								
							
						
					
					
						commit
						3c2e050593
					
				
					 14 changed files with 215 additions and 15 deletions
				
			
		|  | @ -20,6 +20,7 @@ from test.registry.protocols import Failures, Image, layer_bytes_for_contents, P | |||
| from app import instance_keys | ||||
| from data.model.tag import list_repository_tags | ||||
| from image.docker.schema1 import DOCKER_SCHEMA1_MANIFEST_CONTENT_TYPE | ||||
| from image.docker.schema2 import DOCKER_SCHEMA2_MANIFEST_CONTENT_TYPE | ||||
| from image.docker.schema2.list import DockerSchema2ManifestListBuilder | ||||
| from image.docker.schema2.manifest import DockerSchema2ManifestBuilder | ||||
| from util.security.registry_jwt import decode_bearer_header | ||||
|  | @ -1728,3 +1729,47 @@ def test_geo_blocking(pusher, puller, basic_images, liveserver_session, | |||
|   puller.pull(liveserver_session, 'devtable', 'newrepo', 'latest', basic_images, | ||||
|               credentials=credentials, options=options, | ||||
|               expected_failure=Failures.GEO_BLOCKED) | ||||
| 
 | ||||
| 
 | ||||
| @pytest.mark.parametrize('has_amd64_linux', [ | ||||
|   False, | ||||
|   True, | ||||
| ]) | ||||
| def test_pull_manifest_list_schema2_only(v22_protocol, basic_images, different_images, | ||||
|                                          liveserver_session, app_reloader, data_model, | ||||
|                                          has_amd64_linux): | ||||
|   """ Test: Push a new tag with a manifest list containing two manifests, one schema2 (possibly) | ||||
|       amd64 and one not, and pull it when only accepting a schema2 manifest type. Since the manifest | ||||
|       list content type is not being sent, this should return just the manifest (or none if no | ||||
|       linux+amd64 is present.) | ||||
|   """ | ||||
|   if data_model != 'oci_model': | ||||
|     return | ||||
| 
 | ||||
|   credentials = ('devtable', 'password') | ||||
| 
 | ||||
|   # Build the manifests that will go in the list. | ||||
|   options = ProtocolOptions() | ||||
|   blobs = {} | ||||
| 
 | ||||
|   first_manifest = v22_protocol.build_schema2(basic_images, blobs, options) | ||||
|   second_manifest = v22_protocol.build_schema2(different_images, blobs, options) | ||||
| 
 | ||||
|   # Create and push the manifest list. | ||||
|   builder = DockerSchema2ManifestListBuilder() | ||||
|   builder.add_manifest(first_manifest, 'amd64' if has_amd64_linux else 'amd32', 'linux') | ||||
|   builder.add_manifest(second_manifest, 'arm', 'linux') | ||||
|   manifestlist = builder.build() | ||||
| 
 | ||||
|   v22_protocol.push_list(liveserver_session, 'devtable', 'newrepo', 'latest', manifestlist, | ||||
|                          [first_manifest, second_manifest], blobs, | ||||
|                          credentials=credentials) | ||||
| 
 | ||||
|   # Pull and verify the manifest. | ||||
|   options.accept_mimetypes = [DOCKER_SCHEMA2_MANIFEST_CONTENT_TYPE] | ||||
|   result = v22_protocol.pull(liveserver_session, 'devtable', 'newrepo', 'latest', basic_images, | ||||
|                              credentials=credentials, options=options, | ||||
|                              expected_failure=None if has_amd64_linux else Failures.UNKNOWN_TAG) | ||||
| 
 | ||||
|   if has_amd64_linux: | ||||
|     assert result.manifests['latest'].media_type == DOCKER_SCHEMA2_MANIFEST_CONTENT_TYPE | ||||
|  |  | |||
		Reference in a new issue