Skip to content

Commit 2bda676

Browse files
authored
feat: Support docker image manifest v2 schema1 scanning (#2815)
1 parent a4b9b3c commit 2bda676

File tree

2 files changed

+44
-1
lines changed

2 files changed

+44
-1
lines changed

changes/2815.feature.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Support docker image manifest v2 schema1.

src/ai/backend/manager/container_registry/base.py

+43-1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,14 @@ class BaseContainerRegistry(metaclass=ABCMeta):
6060
)
6161
MEDIA_TYPE_DOCKER_MANIFEST: Final[str] = "application/vnd.docker.distribution.manifest.v2+json"
6262

63+
# Legacy manifest types (deprecated)
64+
MEDIA_TYPE_DOCKER_MANIFEST_V1_PRETTY_JWS: Final[str] = (
65+
"application/vnd.docker.distribution.manifest.v1+prettyjws"
66+
)
67+
MEDIA_TYPE_DOCKER_MANIFEST_V1_JSON: Final[str] = (
68+
"application/vnd.docker.distribution.manifest.v1+json"
69+
)
70+
6371
def __init__(
6472
self,
6573
db: ExtendedAsyncSAEngine,
@@ -279,7 +287,7 @@ async def _scan_tag(
279287
return
280288
content_type = resp.headers["Content-Type"]
281289
resp.raise_for_status()
282-
resp_json = await resp.json()
290+
resp_json = json.loads(await resp.read())
283291

284292
async with aiotools.TaskGroup() as tg:
285293
match content_type:
@@ -295,6 +303,14 @@ async def _scan_tag(
295303
await self._process_oci_index(
296304
tg, sess, rqst_args, image, tag, resp_json
297305
)
306+
case (
307+
self.MEDIA_TYPE_DOCKER_MANIFEST_V1_PRETTY_JWS
308+
| self.MEDIA_TYPE_DOCKER_MANIFEST_V1_JSON
309+
):
310+
await self._process_docker_v1_image(
311+
tg, sess, rqst_args, image, tag, resp_json
312+
)
313+
298314
case _:
299315
log.warn("Unknown content type: {}", content_type)
300316
raise RuntimeError(
@@ -438,6 +454,32 @@ async def _process_docker_v2_image(
438454
}
439455
await self._read_manifest(image, tag, manifests)
440456

457+
async def _process_docker_v1_image(
458+
self,
459+
tg: aiotools.TaskGroup,
460+
sess: aiohttp.ClientSession,
461+
rqst_args: Mapping[str, Any],
462+
image: str,
463+
tag: str,
464+
image_info: Mapping[str, Any],
465+
) -> None:
466+
log.warning("Docker image manifest v1 is deprecated.")
467+
468+
architecture = image_info["architecture"]
469+
470+
manifest_list = [
471+
{
472+
"platform": {
473+
"os": "linux",
474+
"architecture": architecture,
475+
},
476+
"digest": tag,
477+
}
478+
]
479+
480+
rqst_args["headers"]["Accept"] = self.MEDIA_TYPE_DOCKER_MANIFEST
481+
await self._read_manifest_list(sess, manifest_list, rqst_args, image, tag)
482+
441483
async def _read_manifest(
442484
self,
443485
image: str,

0 commit comments

Comments
 (0)