lilydjwg / nvchecker

New version checker for software releases
MIT License
425 stars 68 forks source link

test_container fails #245

Closed yan12125 closed 9 months ago

yan12125 commented 9 months ago

@bianjp

Test failure log ``` $ pytest tests/test_container.py::test_container_with_tag =========================================================================== test session starts ============================================================================ platform linux -- Python 3.11.6, pytest-7.4.3, pluggy-1.3.0 rootdir: /home/yen/var/local/Computer/archlinux/nvchecker configfile: pyproject.toml plugins: anyio-3.7.1, httpbin-2.0.0, flaky-3.7.0, asyncio-0.23.0 asyncio: mode=Mode.STRICT collected 1 item tests/test_container.py F [100%] ================================================================================= FAILURES ================================================================================= _________________________________________________________________________ test_container_with_tag __________________________________________________________________________ get_version = .__call__ at 0x7f5c42e05da0> async def test_container_with_tag(get_version): > update_time = await get_version("hello-world:linux", { "source": "container", "container": "library/hello-world:linux", }) tests/test_container.py:16: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ tests/conftest.py:57: in __call__ newvers = await run(entries) tests/conftest.py:50: in run vers, _has_failures = await main.run(result_coro, runner_coro) nvchecker/__main__.py:102: in run return await result_fu nvchecker/core.py:397: in process_result logger.exception('error processing result', result=r) /usr/lib/python3.11/site-packages/structlog/_log_levels.py:88: in exception return self.error(event, *args, **kw) /usr/lib/python3.11/site-packages/structlog/_log_levels.py:168: in meth return self._proxy_to_logger(name, event, **kw) /usr/lib/python3.11/site-packages/structlog/_base.py:222: in _proxy_to_logger args, kw = self._process_event(method_name, event, event_kw) /usr/lib/python3.11/site-packages/structlog/_base.py:171: in _process_event event_dict = proc(self._logger, method_name, event_dict) nvchecker/core.py:395: in process_result r1 = _process_result(r) nvchecker/core.py:342: in _process_result logger.error('unexpected error happened', /usr/lib/python3.11/site-packages/structlog/_log_levels.py:168: in meth return self._proxy_to_logger(name, event, **kw) /usr/lib/python3.11/site-packages/structlog/_base.py:222: in _proxy_to_logger args, kw = self._process_event(method_name, event, event_kw) /usr/lib/python3.11/site-packages/structlog/_base.py:171: in _process_event event_dict = proc(self._logger, method_name, event_dict) tests/conftest.py:87: in proc raise exc nvchecker/util.py:298: in run_one version = await self.func( nvchecker_source/container.py:146: in get_version return await cache.get(key, get_container_tag_update_time) nvchecker/util.py:237: in get r = await fu _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ info = ('library/hello-world', 'linux', 'registry-1.docker.io', AuthInfo(service='registry.docker.io', realm='https://auth.docker.io/token')) async def get_container_tag_update_time(info: Tuple[str, str, str, AuthInfo]): ''' Find the update time of a container tag. In fact, it's the creation time of the image ID referred by the tag. Tag itself does not have any update time. ''' image_path, image_tag, registry_host, auth_info = info token = await get_auth_token(auth_info, image_path) # HTTP headers headers = { 'Authorization': f'Bearer {token}', # Prefer Image Manifest Version 2, Schema 2: https://distribution.github.io/distribution/spec/manifest-v2-2/ 'Accept': 'application/vnd.docker.distribution.manifest.v2+json, application/vnd.docker.container.image.v1+json, application/json', } # Get tag manifest url = f'https://{registry_host}/v2/{image_path}/manifests/{image_tag}' res = await session.get(url, headers=headers) data = res.json() # Schema 1 returns the creation time in the response if data['schemaVersion'] == 1: return json.loads(data['history'][0]['v1Compatibility'])['created'] # For schema 2, we have to fetch the config's blob > digest = data['config']['digest'] E KeyError: 'config' nvchecker_source/container.py:124: KeyError ========================================================================= short test summary info ========================================================================== FAILED tests/test_container.py::test_container_with_tag - KeyError: 'config' ============================================================================ 1 failed in 1.93s ============================================================================= ```

Here is a dump of results from the relevant API (prettified JSON):

data.json ```JSON { "manifests": [ { "annotations": { "org.opencontainers.image.revision": "3fb6ebca4163bf5b9cc496ac3e8f11cb1e754aee", "org.opencontainers.image.source": "https://github.com/docker-library/hello-world.git#3fb6ebca4163bf5b9cc496ac3e8f11cb1e754aee:amd64/hello-world", "org.opencontainers.image.url": "https://hub.docker.com/_/hello-world", "org.opencontainers.image.version": "linux" }, "digest": "sha256:e2fc4e5012d16e7fe466f5291c476431beaa1f9b90a5c2125b493ed28e2aba57", "mediatype": "application/vnd.oci.image.manifest.v1+json", "platform": { "architecture": "amd64", "os": "linux" }, "size": 861 }, { "annotations": { "vnd.docker.reference.digest": "sha256:e2fc4e5012d16e7fe466f5291c476431beaa1f9b90a5c2125b493ed28e2aba57", "vnd.docker.reference.type": "attestation-manifest" }, "digest": "sha256:579b3724a7b189f6dca599a46f16d801a43d5def185de0b7bcd5fb9d1e312c27", "mediatype": "application/vnd.oci.image.manifest.v1+json", "platform": { "architecture": "unknown", "os": "unknown" }, "size": 837 }, { "annotations": { "org.opencontainers.image.revision": "3fb6ebca4163bf5b9cc496ac3e8f11cb1e754aee", "org.opencontainers.image.source": "https://github.com/docker-library/hello-world.git#3fb6ebca4163bf5b9cc496ac3e8f11cb1e754aee:arm32v5/hello-world", "org.opencontainers.image.url": "https://hub.docker.com/_/hello-world", "org.opencontainers.image.version": "linux" }, "digest": "sha256:c2d891e5c2fb4c723efb72b064be3351189f62222bd3681ce7e57f2a1527362c", "mediatype": "application/vnd.oci.image.manifest.v1+json", "platform": { "architecture": "arm", "os": "linux", "variant": "v5" }, "size": 863 }, { "annotations": { "vnd.docker.reference.digest": "sha256:c2d891e5c2fb4c723efb72b064be3351189f62222bd3681ce7e57f2a1527362c", "vnd.docker.reference.type": "attestation-manifest" }, "digest": "sha256:6901d6a88eee6e90f0baa62b020bb61c4f13194cbcd9bf568ab66e8cc3f940dd", "mediatype": "application/vnd.oci.image.manifest.v1+json", "platform": { "architecture": "unknown", "os": "unknown" }, "size": 566 }, { "annotations": { "org.opencontainers.image.revision": "3fb6ebca4163bf5b9cc496ac3e8f11cb1e754aee", "org.opencontainers.image.source": "https://github.com/docker-library/hello-world.git#3fb6ebca4163bf5b9cc496ac3e8f11cb1e754aee:arm32v7/hello-world", "org.opencontainers.image.url": "https://hub.docker.com/_/hello-world", "org.opencontainers.image.version": "linux" }, "digest": "sha256:20aea1c63c90d5e117db787c9fe1a8cd0ad98bedb5fd711273ffe05c084ff18a", "mediatype": "application/vnd.oci.image.manifest.v1+json", "platform": { "architecture": "arm", "os": "linux", "variant": "v7" }, "size": 863 }, { "annotations": { "vnd.docker.reference.digest": "sha256:20aea1c63c90d5e117db787c9fe1a8cd0ad98bedb5fd711273ffe05c084ff18a", "vnd.docker.reference.type": "attestation-manifest" }, "digest": "sha256:70304c314d8a61ba1b36518624bb00bfff8d4b6016153792042de43f0453ca61", "mediatype": "application/vnd.oci.image.manifest.v1+json", "platform": { "architecture": "unknown", "os": "unknown" }, "size": 837 }, { "annotations": { "org.opencontainers.image.revision": "3fb6ebca4163bf5b9cc496ac3e8f11cb1e754aee", "org.opencontainers.image.source": "https://github.com/docker-library/hello-world.git#3fb6ebca4163bf5b9cc496ac3e8f11cb1e754aee:arm64v8/hello-world", "org.opencontainers.image.url": "https://hub.docker.com/_/hello-world", "org.opencontainers.image.version": "linux" }, "digest": "sha256:2d4e459f4ecb5329407ae3e47cbc107a2fbace221354ca75960af4c047b3cb13", "mediatype": "application/vnd.oci.image.manifest.v1+json", "platform": { "architecture": "arm64", "os": "linux", "variant": "v8" }, "size": 863 }, { "annotations": { "vnd.docker.reference.digest": "sha256:2d4e459f4ecb5329407ae3e47cbc107a2fbace221354ca75960af4c047b3cb13", "vnd.docker.reference.type": "attestation-manifest" }, "digest": "sha256:1f11fbd1720fcae3e402fc3eecb7d57c67023d2d1e11becc99ad9c7fe97d65ca", "mediatype": "application/vnd.oci.image.manifest.v1+json", "platform": { "architecture": "unknown", "os": "unknown" }, "size": 837 }, { "annotations": { "org.opencontainers.image.revision": "3fb6ebca4163bf5b9cc496ac3e8f11cb1e754aee", "org.opencontainers.image.source": "https://github.com/docker-library/hello-world.git#3fb6ebca4163bf5b9cc496ac3e8f11cb1e754aee:i386/hello-world", "org.opencontainers.image.url": "https://hub.docker.com/_/hello-world", "org.opencontainers.image.version": "linux" }, "digest": "sha256:dbbd3cf666311ad526fad9d1746177469268f32fd91b371df2ebd1c84eb22f23", "mediatype": "application/vnd.oci.image.manifest.v1+json", "platform": { "architecture": "386", "os": "linux" }, "size": 860 }, { "annotations": { "vnd.docker.reference.digest": "sha256:dbbd3cf666311ad526fad9d1746177469268f32fd91b371df2ebd1c84eb22f23", "vnd.docker.reference.type": "attestation-manifest" }, "digest": "sha256:18b1c92de36d42c75440c6fd6b25605cc91709d176faaccca8afe58b317bc33a", "mediatype": "application/vnd.oci.image.manifest.v1+json", "platform": { "architecture": "unknown", "os": "unknown" }, "size": 566 }, { "annotations": { "org.opencontainers.image.revision": "3fb6ebca4163bf5b9cc496ac3e8f11cb1e754aee", "org.opencontainers.image.source": "https://github.com/docker-library/hello-world.git#3fb6ebca4163bf5b9cc496ac3e8f11cb1e754aee:mips64le/hello-world", "org.opencontainers.image.url": "https://hub.docker.com/_/hello-world", "org.opencontainers.image.version": "linux" }, "digest": "sha256:c19784034d46da48550487c5c44639f5f92d48be7b9baf4d67b5377a454d92af", "mediatype": "application/vnd.oci.image.manifest.v1+json", "platform": { "architecture": "mips64le", "os": "linux" }, "size": 864 }, { "annotations": { "vnd.docker.reference.digest": "sha256:c19784034d46da48550487c5c44639f5f92d48be7b9baf4d67b5377a454d92af", "vnd.docker.reference.type": "attestation-manifest" }, "digest": "sha256:951bcd144ddccd1ee902dc180b435faabaaa6a8747e70cbc893f2dca16badb94", "mediatype": "application/vnd.oci.image.manifest.v1+json", "platform": { "architecture": "unknown", "os": "unknown" }, "size": 566 }, { "annotations": { "org.opencontainers.image.revision": "3fb6ebca4163bf5b9cc496ac3e8f11cb1e754aee", "org.opencontainers.image.source": "https://github.com/docker-library/hello-world.git#3fb6ebca4163bf5b9cc496ac3e8f11cb1e754aee:ppc64le/hello-world", "org.opencontainers.image.url": "https://hub.docker.com/_/hello-world", "org.opencontainers.image.version": "linux" }, "digest": "sha256:f0c95f1ebb50c9b0b3e3416fb9dd4d1d197386a076c464cceea3d1f94c321b8f", "mediatype": "application/vnd.oci.image.manifest.v1+json", "platform": { "architecture": "ppc64le", "os": "linux" }, "size": 863 }, { "annotations": { "vnd.docker.reference.digest": "sha256:f0c95f1ebb50c9b0b3e3416fb9dd4d1d197386a076c464cceea3d1f94c321b8f", "vnd.docker.reference.type": "attestation-manifest" }, "digest": "sha256:838d191bca398e46cddebc48e816da83b0389d4ed2d64f408d618521b8fd1a57", "mediatype": "application/vnd.oci.image.manifest.v1+json", "platform": { "architecture": "unknown", "os": "unknown" }, "size": 837 }, { "annotations": { "org.opencontainers.image.revision": "3fb6ebca4163bf5b9cc496ac3e8f11cb1e754aee", "org.opencontainers.image.source": "https://github.com/docker-library/hello-world.git#3fb6ebca4163bf5b9cc496ac3e8f11cb1e754aee:riscv64/hello-world", "org.opencontainers.image.url": "https://hub.docker.com/_/hello-world", "org.opencontainers.image.version": "linux" }, "digest": "sha256:8d064a6fc27fd5e97fa8225994a1addd872396236367745bea30c92d6c032fa3", "mediatype": "application/vnd.oci.image.manifest.v1+json", "platform": { "architecture": "riscv64", "os": "linux" }, "size": 863 }, { "annotations": { "vnd.docker.reference.digest": "sha256:8d064a6fc27fd5e97fa8225994a1addd872396236367745bea30c92d6c032fa3", "vnd.docker.reference.type": "attestation-manifest" }, "digest": "sha256:48147407c4594e45b7c3f0be1019bb0f44d78d7f037ce63e0e3da75b256f849e", "mediatype": "application/vnd.oci.image.manifest.v1+json", "platform": { "architecture": "unknown", "os": "unknown" }, "size": 837 }, { "annotations": { "org.opencontainers.image.revision": "3fb6ebca4163bf5b9cc496ac3e8f11cb1e754aee", "org.opencontainers.image.source": "https://github.com/docker-library/hello-world.git#3fb6ebca4163bf5b9cc496ac3e8f11cb1e754aee:s390x/hello-world", "org.opencontainers.image.url": "https://hub.docker.com/_/hello-world", "org.opencontainers.image.version": "linux" }, "digest": "sha256:65f4b0d1802589b418bb6774d85de3d1a11d5bd971ee73cb8569504d928bb5d9", "mediatype": "application/vnd.oci.image.manifest.v1+json", "platform": { "architecture": "s390x", "os": "linux" }, "size": 861 }, { "annotations": { "vnd.docker.reference.digest": "sha256:65f4b0d1802589b418bb6774d85de3d1a11d5bd971ee73cb8569504d928bb5d9", "vnd.docker.reference.type": "attestation-manifest" }, "digest": "sha256:50f420e8710676da03668e446f1f51097b745e3e2c9807b018e569d26d4f65f7", "mediatype": "application/vnd.oci.image.manifest.v1+json", "platform": { "architecture": "unknown", "os": "unknown" }, "size": 837 } ], "mediatype": "application/vnd.oci.image.index.v1+json", "schemaversion": 2 } ```

It seems there are different formats for manifests with "schemaversion": 2 [1]? Maybe nvchecker needs to handle different cases.

[1] https://distribution.github.io/distribution/spec/manifest-v2-2/

bianjp commented 9 months ago

For multi-arch images, registry will return Manifest List instead of Image Manifest: https://distribution.github.io/distribution/spec/manifest-v2-2/#manifest-list.

This case was not handled previously. I'll make a new PR to fix it.

yan12125 commented 9 months ago

Thanks for the fix. I backported it as part of 2.13 update for https://archlinux.org/packages/extra/any/nvchecker/