|
@@ -183,19 +183,39 @@ func DetectManifestMediaType(ra content.ReaderAt) (string, error) {
|
|
|
|
|
|
func DetectManifestBlobMediaType(dt []byte) (string, error) {
|
|
func DetectManifestBlobMediaType(dt []byte) (string, error) {
|
|
var mfst struct {
|
|
var mfst struct {
|
|
- MediaType string `json:"mediaType"`
|
|
|
|
|
|
+ MediaType *string `json:"mediaType"`
|
|
Config json.RawMessage `json:"config"`
|
|
Config json.RawMessage `json:"config"`
|
|
|
|
+ Manifests json.RawMessage `json:"manifests"`
|
|
|
|
+ Layers json.RawMessage `json:"layers"`
|
|
}
|
|
}
|
|
|
|
|
|
if err := json.Unmarshal(dt, &mfst); err != nil {
|
|
if err := json.Unmarshal(dt, &mfst); err != nil {
|
|
return "", err
|
|
return "", err
|
|
}
|
|
}
|
|
|
|
|
|
- if mfst.MediaType != "" {
|
|
|
|
- return mfst.MediaType, nil
|
|
|
|
|
|
+ mt := images.MediaTypeDockerSchema2ManifestList
|
|
|
|
+
|
|
|
|
+ if mfst.Config != nil || mfst.Layers != nil {
|
|
|
|
+ mt = images.MediaTypeDockerSchema2Manifest
|
|
|
|
+
|
|
|
|
+ if mfst.Manifests != nil {
|
|
|
|
+ return "", errors.Errorf("invalid ambiguous manifest and manifest list")
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- if mfst.Config != nil {
|
|
|
|
- return images.MediaTypeDockerSchema2Manifest, nil
|
|
|
|
|
|
+
|
|
|
|
+ if mfst.MediaType != nil {
|
|
|
|
+ switch *mfst.MediaType {
|
|
|
|
+ case images.MediaTypeDockerSchema2ManifestList, specs.MediaTypeImageIndex:
|
|
|
|
+ if mt != images.MediaTypeDockerSchema2ManifestList {
|
|
|
|
+ return "", errors.Errorf("mediaType in manifest does not match manifest contents")
|
|
|
|
+ }
|
|
|
|
+ mt = *mfst.MediaType
|
|
|
|
+ case images.MediaTypeDockerSchema2Manifest, specs.MediaTypeImageManifest:
|
|
|
|
+ if mt != images.MediaTypeDockerSchema2Manifest {
|
|
|
|
+ return "", errors.Errorf("mediaType in manifest does not match manifest contents")
|
|
|
|
+ }
|
|
|
|
+ mt = *mfst.MediaType
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- return images.MediaTypeDockerSchema2ManifestList, nil
|
|
|
|
|
|
+ return mt, nil
|
|
}
|
|
}
|