-
Bug
-
Resolution: Done
-
Major
-
quay-v3.7.0, quay-v3.7.1, quay-v3.7.2, quay-v3.7.3, quay-v3.7.4, quay-v3.7.5
The following image: quay.io/openshift-scale/etcd-perf:latest consistently fails when trying to pull it through a proxy org. This happens because OCI image indexes normally do not specify a `mediaType` field in the root of manifest json.
As reported by PM: when trying to reproduce this on 3.7.3 Quay I could not successfully cache the image at all. Upon the first pull I would get the following error message on the client side:
Error response from daemon: received unexpected HTTP status: 500 Internal Server Error
And in the Quay logs:
gunicorn-registry stdout | 2022-07-18 10:01:11,466 [251] [ERROR] [gunicorn.error] Error handling request /v2/cache/etcd-perf/manifests/latest gunicorn-registry stdout | Traceback (most recent call last): gunicorn-registry stdout | File "/usr/local/lib/python3.8/site-packages/gunicorn/workers/base_async.py", line 55, in handle gunicorn-registry stdout | self.handle_request(listener_name, req, client, addr) gunicorn-registry stdout | File "/usr/local/lib/python3.8/site-packages/gunicorn/workers/ggevent.py", line 127, in handle_request gunicorn-registry stdout | super().handle_request(listener_name, req, sock, addr) gunicorn-registry stdout | File "/usr/local/lib/python3.8/site-packages/gunicorn/workers/base_async.py", line 108, in handle_request gunicorn-registry stdout | respiter = self.wsgi(environ, resp.start_response) gunicorn-registry stdout | File "/usr/local/lib/python3.8/site-packages/flask/app.py", line 2463, in __call__ gunicorn-registry stdout | return self.wsgi_app(environ, start_response) gunicorn-registry stdout | File "/usr/local/lib/python3.8/site-packages/werkzeug/middleware/proxy_fix.py", line 232, in __call__ gunicorn-registry stdout | return self.app(environ, start_response) gunicorn-registry stdout | File "/usr/local/lib/python3.8/site-packages/flask/app.py", line 2449, in wsgi_app gunicorn-registry stdout | response = self.handle_exception(e) gunicorn-registry stdout | File "/usr/local/lib/python3.8/site-packages/flask/app.py", line 1866, in handle_exception gunicorn-registry stdout | reraise(exc_type, exc_value, tb) gunicorn-registry stdout | File "/usr/local/lib/python3.8/site-packages/flask/_compat.py", line 39, in reraise gunicorn-registry stdout | raise value gunicorn-registry stdout | File "/usr/local/lib/python3.8/site-packages/flask/app.py", line 2446, in wsgi_app gunicorn-registry stdout | response = self.full_dispatch_request() gunicorn-registry stdout | File "/usr/local/lib/python3.8/site-packages/flask/app.py", line 1951, in full_dispatch_request gunicorn-registry stdout | rv = self.handle_user_exception(e) gunicorn-registry stdout | File "/usr/local/lib/python3.8/site-packages/flask/app.py", line 1820, in handle_user_exception gunicorn-registry stdout | reraise(exc_type, exc_value, tb) gunicorn-registry stdout | File "/usr/local/lib/python3.8/site-packages/flask/_compat.py", line 39, in reraise gunicorn-registry stdout | raise value gunicorn-registry stdout | File "/usr/local/lib/python3.8/site-packages/flask/app.py", line 1949, in full_dispatch_request gunicorn-registry stdout | rv = self.dispatch_request() gunicorn-registry stdout | File "/usr/local/lib/python3.8/site-packages/flask/app.py", line 1935, in dispatch_request gunicorn-registry stdout | return self.view_functions[rule.endpoint](**req.view_args) gunicorn-registry stdout | File "/quay-registry/endpoints/decorators.py", line 218, in wrapper gunicorn-registry stdout | return func(*args, **kwargs) gunicorn-registry stdout | File "/quay-registry/endpoints/decorators.py", line 91, in wrapper gunicorn-registry stdout | return func(*args, **kwargs) gunicorn-registry stdout | File "/quay-registry/auth/registry_jwt_auth.py", line 177, in wrapper gunicorn-registry stdout | return func(*args, **kwargs) gunicorn-registry stdout | File "/quay-registry/endpoints/v2/__init__.py", line 143, in wrapped gunicorn-registry stdout | return func(namespace_name, repo_name, *args, **kwargs) gunicorn-registry stdout | File "/quay-registry/endpoints/decorators.py", line 154, in wrapper gunicorn-registry stdout | return func(*args, **kwargs) gunicorn-registry stdout | File "/quay-registry/endpoints/decorators.py", line 54, in wrapper gunicorn-registry stdout | return func(namespace_name, repo_name, *args, **kwargs) gunicorn-registry stdout | File "/quay-registry/endpoints/v2/manifest.py", line 75, in fetch_manifest_by_tagname gunicorn-registry stdout | tag = registry_model.get_repo_tag(repository_ref, manifest_ref, raise_on_error=True) gunicorn-registry stdout | File "/quay-registry/data/registry_model/registry_proxy_model.py", line 217, in get_repo_tag gunicorn-registry stdout | _, tag = self._create_and_tag_manifest( gunicorn-registry stdout | File "/quay-registry/data/registry_model/registry_proxy_model.py", line 289, in _create_and_tag_manifest gunicorn-registry stdout | manifest, tag = create_manifest_fn(repo_ref, upstream_manifest, manifest_ref) gunicorn-registry stdout | File "/quay-registry/data/registry_model/registry_proxy_model.py", line 378, in _create_manifest_and_retarget_tag gunicorn-registry stdout | db_manifest = oci.manifest.create_manifest( gunicorn-registry stdout | File "/quay-registry/data/model/oci/manifest.py", line 143, in create_manifest gunicorn-registry stdout | media_type = Manifest.media_type.get_id(manifest.media_type) gunicorn-registry stdout | File "/quay-registry/image/shared/types.py", line 287, in media_type gunicorn-registry stdout | return self._parsed["mediaType"] gunicorn-registry stdout | KeyError: 'mediaType'
Oddly enough, when attempting to pull the same image through the cache but served from DockerHub neither of these issues occurred.