diff --git a/nvchecker_source/container.py b/nvchecker_source/container.py index 6fec208..fc06505 100644 --- a/nvchecker_source/container.py +++ b/nvchecker_source/container.py @@ -109,7 +109,13 @@ async def get_container_tag_update_time(info: Tuple[str, str, str, AuthInfo]): 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', + 'Accept': ', '.join([ + 'application/vnd.oci.image.manifest.v1+json', + 'application/vnd.oci.image.index.v1+json', + 'application/vnd.docker.distribution.manifest.v2+json', + 'application/vnd.docker.distribution.manifest.list.v2+json', + 'application/json', + ]), } # Get tag manifest @@ -121,6 +127,16 @@ async def get_container_tag_update_time(info: Tuple[str, str, str, AuthInfo]): return json.loads(data['history'][0]['v1Compatibility'])['created'] # For schema 2, we have to fetch the config's blob + # For multi-arch images, multiple manifests are bounded with the same tag. We should choose one and then request + # the manifest's detail + if data.get('manifests'): + # It's quite hard to find the manifest matching with current CPU architecture and system. + # For now we just choose the first and it should probably work for most cases + image_digest = data['manifests'][0]['digest'] + url = f'https://{registry_host}/v2/{image_path}/manifests/{image_digest}' + res = await session.get(url, headers=headers) + data = res.json() + digest = data['config']['digest'] url = f'https://{registry_host}/v2/{image_path}/blobs/{digest}' res = await session.get(url, headers=headers) diff --git a/tests/test_container.py b/tests/test_container.py index f0e5277..cdf6e47 100644 --- a/tests/test_container.py +++ b/tests/test_container.py @@ -13,6 +13,14 @@ async def test_container(get_version): }) == "linux" async def test_container_with_tag(get_version): + update_time = await get_version("bitnami/mongodb:5.0", { + "source": "container", + "container": "bitnami/mongodb:5.0", + }) + # the update time is changing occasionally, so we can not compare the exact time, otherwise the test will be failed in the future + assert datetime.date.fromisoformat(update_time.split('T')[0]) > datetime.date(2023, 12, 1) + +async def test_container_with_tag_and_multi_arch(get_version): update_time = await get_version("hello-world:linux", { "source": "container", "container": "library/hello-world:linux",