Skip to content

Commit 0bf4a2e

Browse files
committed
Add OCI manifest to allowed media types of docker manifest list
Assisted by: cursor-compose-2.5 (cherry picked from commit e42c6ef)
1 parent ccdb928 commit 0bf4a2e

5 files changed

Lines changed: 186 additions & 0 deletions

File tree

CHANGES/+docker-list-schema.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Added OCI manifest as an allowed media type in the Docker manifest list schema.

MANIFEST.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ include test_requirements.txt
99
include unittest_requirements.txt
1010
exclude CONTRIBUTING.md
1111
exclude releasing.md
12+
include pulp_container/tests/unit/fixtures/*

pulp_container/app/json_schemas.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ def get_descriptor_schema(
124124
"enum": [
125125
MEDIA_TYPE.MANIFEST_V2,
126126
MEDIA_TYPE.MANIFEST_V1,
127+
MEDIA_TYPE.MANIFEST_OCI,
127128
],
128129
},
129130
"size": {"type": "number"},
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
{
2+
"schemaVersion": 2,
3+
"mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
4+
"manifests": [
5+
{
6+
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
7+
"size": 1157,
8+
"digest": "sha256:dbf39a38239100ad20536e75f0066163bdf989c8b6a07116c8814f991878756f",
9+
"platform": {
10+
"architecture": "amd64",
11+
"os": "windows",
12+
"os.version": "10.0.17763.7678"
13+
}
14+
},
15+
{
16+
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
17+
"size": 1157,
18+
"digest": "sha256:92ae77da69814eadc33ece22a9a1f564b508fd3bc0ab6c27f53ffb3b4e2f7ff0",
19+
"platform": {
20+
"architecture": "amd64",
21+
"os": "windows",
22+
"os.version": "10.0.20348.4052"
23+
}
24+
},
25+
{
26+
"mediaType": "application/vnd.oci.image.manifest.v1+json",
27+
"size": 662,
28+
"digest": "sha256:1c4aaca7ec29ab100a805a90718619dba7a542f7fadc6198c8f47b1c6fc058c5",
29+
"platform": {
30+
"architecture": "ppc64le",
31+
"os": "linux"
32+
}
33+
},
34+
{
35+
"mediaType": "application/vnd.oci.image.manifest.v1+json",
36+
"size": 567,
37+
"digest": "sha256:1f965b7a234671c706b444540c86033bbe667b3d6df3453b88a16bb897328bea",
38+
"platform": {
39+
"architecture": "unknown",
40+
"os": "unknown"
41+
}
42+
},
43+
{
44+
"mediaType": "application/vnd.oci.image.manifest.v1+json",
45+
"size": 567,
46+
"digest": "sha256:286b5e78baf03adff94af82199af6b936c701957d94dd001cae375af41519fd3",
47+
"platform": {
48+
"architecture": "unknown",
49+
"os": "unknown"
50+
}
51+
},
52+
{
53+
"mediaType": "application/vnd.oci.image.manifest.v1+json",
54+
"size": 662,
55+
"digest": "sha256:2a5038e0424aee30b8e1ecaf3889eb18b1496baca035b5cbdfeb79faa06e867a",
56+
"platform": {
57+
"architecture": "arm64",
58+
"os": "linux"
59+
}
60+
},
61+
{
62+
"mediaType": "application/vnd.oci.image.manifest.v1+json",
63+
"size": 662,
64+
"digest": "sha256:2ff824f3c5b87343601f88b944039949004c4b25d5c95b95b8d513d9592abfd9",
65+
"platform": {
66+
"architecture": "arm",
67+
"os": "linux",
68+
"variant": "v7"
69+
}
70+
},
71+
{
72+
"mediaType": "application/vnd.oci.image.manifest.v1+json",
73+
"size": 662,
74+
"digest": "sha256:31c852ef4caf457d598a67ef9a19626a99e0080186903e15f9cacac70eaeb08f",
75+
"platform": {
76+
"architecture": "arm",
77+
"os": "linux",
78+
"variant": "v6"
79+
}
80+
},
81+
{
82+
"mediaType": "application/vnd.oci.image.manifest.v1+json",
83+
"size": 567,
84+
"digest": "sha256:46d7dcf2110fc9e7eb1e8bc589d7507fb4db20b36a7ae401d0f7daa5457986cd",
85+
"platform": {
86+
"architecture": "unknown",
87+
"os": "unknown"
88+
}
89+
},
90+
{
91+
"mediaType": "application/vnd.oci.image.manifest.v1+json",
92+
"size": 567,
93+
"digest": "sha256:5af5b45d5d54da802b42c1754577d9b3b91b61bb20ca301b1de08e47b5027fb1",
94+
"platform": {
95+
"architecture": "unknown",
96+
"os": "unknown"
97+
}
98+
},
99+
{
100+
"mediaType": "application/vnd.oci.image.manifest.v1+json",
101+
"size": 567,
102+
"digest": "sha256:6312fce3d003e5b1973f64ff61d7465c0d8a3f6216123264fd8688caace685ce",
103+
"platform": {
104+
"architecture": "unknown",
105+
"os": "unknown"
106+
}
107+
},
108+
{
109+
"mediaType": "application/vnd.oci.image.manifest.v1+json",
110+
"size": 567,
111+
"digest": "sha256:725de179c309cd78dc85aa0e315f7a2c6230efe166d8a972113ecf47feb122d7",
112+
"platform": {
113+
"architecture": "unknown",
114+
"os": "unknown"
115+
}
116+
},
117+
{
118+
"mediaType": "application/vnd.oci.image.manifest.v1+json",
119+
"size": 662,
120+
"digest": "sha256:9f74979cb9d95b5dd3f695e567cd5cd1806a006895d80fa9002a9e68f607f495",
121+
"platform": {
122+
"architecture": "amd64",
123+
"os": "linux"
124+
}
125+
},
126+
{
127+
"mediaType": "application/vnd.oci.image.manifest.v1+json",
128+
"size": 662,
129+
"digest": "sha256:d5fcc1e6aaa51949c7d11e8ac9cf407efb9d52dd9f871542cfaf750c9b1ccc2b",
130+
"platform": {
131+
"architecture": "386",
132+
"os": "linux"
133+
}
134+
},
135+
{
136+
"mediaType": "application/vnd.oci.image.manifest.v1+json",
137+
"size": 567,
138+
"digest": "sha256:f5aa3faf94fb7c630ecb8bc6d4ba506cfdbd90ff8c882710b07fb953b4cf09ae",
139+
"platform": {
140+
"architecture": "unknown",
141+
"os": "unknown"
142+
}
143+
},
144+
{
145+
"mediaType": "application/vnd.oci.image.manifest.v1+json",
146+
"size": 662,
147+
"digest": "sha256:fa81566cb9a09b2cd72a703e17160c6cf6906a22d4eeae716ce7f0f42053efdb",
148+
"platform": {
149+
"architecture": "s390x",
150+
"os": "linux"
151+
}
152+
}
153+
]
154+
}

pulp_container/tests/unit/test_json_schemas.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import json
2+
from pathlib import Path
23

34
from django.test import TestCase
45
from jsonschema import Draft7Validator
@@ -197,3 +198,31 @@ def test_valid_manifest_with_invalid_layer_media_type(self):
197198
validate_manifest(manifest, MEDIA_TYPE.MANIFEST_OCI, "")
198199
except ManifestInvalid:
199200
self.fail()
201+
202+
203+
class TestDockerManifestListSchema(TestCase):
204+
"""A test case for validating Docker manifest list JSON schema."""
205+
206+
def test_ryuk_manifest_list_with_oci_entries(self):
207+
"""
208+
Validate a real Docker manifest list that references OCI image manifests.
209+
210+
testcontainers/ryuk:0.13.0 on Docker Hub publishes a Docker manifest list
211+
containing both Docker v2 and OCI image manifest entries.
212+
"""
213+
fixture_path = Path(__file__).parent / "fixtures" / "ryuk_0.13.0_manifest_list.json"
214+
manifest = json.loads(fixture_path.read_text())
215+
entry_media_types = {entry["mediaType"] for entry in manifest["manifests"]}
216+
217+
self.assertEqual(manifest["mediaType"], MEDIA_TYPE.MANIFEST_LIST)
218+
self.assertIn(MEDIA_TYPE.MANIFEST_V2, entry_media_types)
219+
self.assertIn(MEDIA_TYPE.MANIFEST_OCI, entry_media_types)
220+
221+
try:
222+
validate_manifest(
223+
manifest,
224+
MEDIA_TYPE.MANIFEST_LIST,
225+
"sha256:31b31269d06603366cbfd0284708dcd2e281e8a4188e53fce3d3304439d0df3d",
226+
)
227+
except ManifestInvalid:
228+
self.fail()

0 commit comments

Comments
 (0)