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

Skopeo copy fails manifest validation when creating repo on push

    XMLWordPrintable

Details

    • Bug
    • Resolution: Duplicate
    • Normal
    • None
    • None
    • quay
    • False
    • None
    • False
    • Quay
    • 0

    Description

      Skopeo copy will fail the push with the following error, but still write the manifest will still have been written to Quay's database:

      gunicorn-registry stdout | Traceback (most recent call last):
      gunicorn-registry stdout |   File "/quay-registry/image/oci/config.py", line 210, in __init__
      gunicorn-registry stdout |     validate_schema(self._parsed, OCIConfig.METASCHEMA)
      gunicorn-registry stdout |   File "/app/lib/python3.9/site-packages/jsonschema/validators.py", line 934, in validate
      gunicorn-registry stdout |     raise error
      gunicorn-registry stdout | jsonschema.exceptions.ValidationError: None is not of type 'array'
      gunicorn-registry stdout | Failed validating 'type' in schema['properties']['config']['properties']['Entrypoint']:
      gunicorn-registry stdout |     {'type': 'array'}
      gunicorn-registry stdout | On instance['config']['Entrypoint']:
      gunicorn-registry stdout |     None
      gunicorn-registry stdout | During handling of the above exception, another exception occurred:
      gunicorn-registry stdout | Traceback (most recent call last):
      gunicorn-registry stdout |   File "/app/lib/python3.9/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 "/app/lib/python3.9/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 "/app/lib/python3.9/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 "/app/lib/python3.9/site-packages/flask/app.py", line 2463, in __call__
      gunicorn-registry stdout |     return self.wsgi_app(environ, start_response)
      gunicorn-registry stdout |   File "/app/lib/python3.9/site-packages/werkzeug/middleware/proxy_fix.py", line 169, in __call__
      gunicorn-registry stdout |     return self.app(environ, start_response)
      gunicorn-registry stdout |   File "/app/lib/python3.9/site-packages/flask/app.py", line 2449, in wsgi_app
      gunicorn-registry stdout |     response = self.handle_exception(e)
      gunicorn-registry stdout |   File "/app/lib/python3.9/site-packages/flask/app.py", line 1866, in handle_exception
      gunicorn-registry stdout |     reraise(exc_type, exc_value, tb)
      gunicorn-registry stdout |   File "/app/lib/python3.9/site-packages/flask/_compat.py", line 39, in reraise
      gunicorn-registry stdout |     raise value
      gunicorn-registry stdout |   File "/app/lib/python3.9/site-packages/flask/app.py", line 2446, in wsgi_app
      gunicorn-registry stdout |     response = self.full_dispatch_request()
      gunicorn-registry stdout |   File "/app/lib/python3.9/site-packages/flask/app.py", line 1951, in full_dispatch_request
      gunicorn-registry stdout |     rv = self.handle_user_exception(e)
      gunicorn-registry stdout |   File "/app/lib/python3.9/site-packages/flask/app.py", line 1820, in handle_user_exception
      gunicorn-registry stdout |     reraise(exc_type, exc_value, tb)
      gunicorn-registry stdout |   File "/app/lib/python3.9/site-packages/flask/_compat.py", line 39, in reraise
      gunicorn-registry stdout |     raise value
      gunicorn-registry stdout |   File "/app/lib/python3.9/site-packages/flask/app.py", line 1949, in full_dispatch_request
      gunicorn-registry stdout |     rv = self.dispatch_request()
      gunicorn-registry stdout |   File "/app/lib/python3.9/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 228, 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/endpoints/v2/manifest.py", line 224, in wrapped
      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 173, in wrapped
      gunicorn-registry stdout |     return func(namespace_name, repo_name, *args, **kwargs)
      gunicorn-registry stdout |   File "/quay-registry/endpoints/decorators.py", line 164, in wrapper
      gunicorn-registry stdout |     return func(*args, **kwargs)
      gunicorn-registry stdout |   File "/quay-registry/endpoints/decorators.py", line 189, in wrapper
      gunicorn-registry stdout |     return func(*args, **kwargs)
      gunicorn-registry stdout |   File "/quay-registry/endpoints/v2/manifest.py", line 256, in write_manifest_by_tagname
      gunicorn-registry stdout |     return _write_manifest_and_log(namespace_name, repo_name, manifest_ref, parsed)
      gunicorn-registry stdout |   File "/quay-registry/endpoints/v2/manifest.py", line 366, in _write_manifest_and_log
      gunicorn-registry stdout |     repository_ref, manifest, tag = _write_manifest(
      gunicorn-registry stdout |   File "/quay-registry/endpoints/v2/manifest.py", line 408, in _write_manifest
      gunicorn-registry stdout |     manifest, tag = registry_model.create_manifest_and_retarget_tag(
      gunicorn-registry stdout |   File "/quay-registry/data/registry_model/registry_oci_model.py", line 360, in create_manifest_and_retarget_tag
      gunicorn-registry stdout |     created_manifest = oci.manifest.get_or_create_manifest(
      gunicorn-registry stdout |   File "/quay-registry/data/model/oci/manifest.py", line 239, in get_or_create_manifest
      gunicorn-registry stdout |     return _create_manifest(
      gunicorn-registry stdout |   File "/quay-registry/data/model/oci/manifest.py", line 361, in _create_manifest
      gunicorn-registry stdout |     labels = manifest_interface_instance.get_manifest_labels(retriever)
      gunicorn-registry stdout |   File "/quay-registry/image/oci/manifest.py", line 257, in get_manifest_labels
      gunicorn-registry stdout |     built_config = self._get_built_config(content_retriever)
      gunicorn-registry stdout |   File "/quay-registry/image/oci/manifest.py", line 474, in _get_built_config
      gunicorn-registry stdout |     self._cached_built_config = OCIConfig(Bytes.for_string_or_unicode(config_bytes))
      gunicorn-registry stdout |   File "/quay-registry/image/oci/config.py", line 212, in __init__
      gunicorn-registry stdout |     raise MalformedConfig("config data does not match schema: %s" % ve)
      gunicorn-registry stdout | image.oci.config.MalformedConfig: config data does not match schema: None is not of type 'array'
      gunicorn-registry stdout | Failed validating 'type' in schema['properties']['config']['properties']['Entrypoint']:
      gunicorn-registry stdout |     {'type': 'array'}
      gunicorn-registry stdout | On instance['config']['Entrypoint']:
      gunicorn-registry stdout |     None
      gunicorn-registry stdout | 2023-02-17 22:01:18,526 [215] [INFO] [gunicorn.access]  - - [17/Feb/2023:22:01:18 +0000] "PUT /v2/devtable/ubuntu/manifests/latest HTTP/1.1" 500 0 "-" "-"// code placeholder
      

      The parsed manifest failing validation in Quay when creating repo+pushing (w/ skopeo copy):

      {'architecture': 'amd64', 'config': {'Hostname': '', 'Domainname': '', 'User': '', 'AttachStdin': False, 'AttachStdout': False, 'AttachStderr': False, 'Tty': False, 'OpenStdin': False, 'StdinOnce': False, 'Env': ['PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'], 'Cmd': ['/bin/bash'], 'Image': 'sha256:269190441c1f8398e85a287ba6ac5568574f55bfcae7fb99bd253afad8cd8e69', 'Volumes': None, 'WorkingDir': '', 'Entrypoint': None, 'OnBuild': None, 'Labels': {'org.opencontainers.image.ref.name': 'ubuntu', 'org.opencontainers.image.version': '22.04'}}, 'container': '6be7983e643200aa82c27e883bf03ae871243571f93a39f39d11dd3c79c96611', 'container_config': {'Hostname': '6be7983e6432', 'Domainname': '', 'User': '', 'AttachStdin': False, 'AttachStdout': False, 'AttachStderr': False, 'Tty': False, 'OpenStdin': False, 'StdinOnce': False, 'Env': ['PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'], 'Cmd': ['/bin/sh', '-c', '#(nop) ', 'CMD ["/bin/bash"]'], 'Image': 'sha256:269190441c1f8398e85a287ba6ac5568574f55bfcae7fb99bd253afad8cd8e69', 'Volumes': None, 'WorkingDir': '', 'Entrypoint': None, 'OnBuild': None, 'Labels': {'org.opencontainers.image.ref.name': 'ubuntu', 'org.opencontainers.image.version': '22.04'}}, 'created': '2023-01-26T04:58:02.385638665Z', 'docker_version': '20.10.12', 'history': [{'created': '2023-01-26T04:57:59.893830181Z', 'created_by': '/bin/sh -c #(nop)  ARG RELEASE', 'empty_layer': True}, {'created': '2023-01-26T04:57:59.959936538Z', 'created_by': '/bin/sh -c #(nop)  ARG LAUNCHPAD_BUILD_ARCH', 'empty_layer': True}, {'created': '2023-01-26T04:58:00.031088326Z', 'created_by': '/bin/sh -c #(nop)  LABEL org.opencontainers.image.ref.name=ubuntu', 'empty_layer': True}, {'created': '2023-01-26T04:58:00.098806406Z', 'created_by': '/bin/sh -c #(nop)  LABEL org.opencontainers.image.version=22.04', 'empty_layer': True}, {'created': '2023-01-26T04:58:02.097080644Z', 'created_by': '/bin/sh -c #(nop) ADD file:18e71f049606f6339ce7a995839623f50e6ec6474bfd0a3a7ca799db726f47f6 in / '}, {'created': '2023-01-26T04:58:02.385638665Z', 'created_by': '/bin/sh -c #(nop)  CMD ["/bin/bash"]', 'empty_layer': True}], 'os': 'linux', 'rootfs': {'type': 'layers', 'diff_ids': ['sha256:c5ff2d88f67954bdcf1cfdd46fe3d683858d69c2cadd6660812edfc83726c654']} 

      But the manifest written is:

      {"schemaVersion": 2, "mediaType": "application/vnd.oci.image.manifest.v1+json", "config": {"mediaType": "application/vnd.oci.image.config.v1+json", "size": 2299, "digest": "sha256:58db3edaf2be6e80f628796355b1bdeaf8bea1692b402f48b7e7b8d1ff100b02"}, "layers": [{"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip", "size": 29528717, "digest": "sha256:677076032cca0a2362d25cf3660072e738d1b96fe860409a33ce901d695d7ee8"}]}

      Attachments

        Activity

          People

            sleesinc Kenny Lee Sin Cheong
            sleesinc Kenny Lee Sin Cheong
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: