Uploaded image for project: 'Project Quay'
  1. Project Quay
  2. PROJQUAY-4254

Cannot cache (pull-thru) OCI image index

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • Major
    • quay-v3.7.6, quay-v3.8.0
    • quay-v3.7.0, quay-v3.7.1, quay-v3.7.2, quay-v3.7.3, quay-v3.7.4, quay-v3.7.5
    • quay
    • 0

    Description

      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.

      Attachments

        Activity

          People

            fmissi Flavian Missi
            fmissi Flavian Missi
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: