Move MediaType into manifest.Versioned

This makes content type sniffing cleaner. The document just needs to be
decoded into a manifest.Versioned structure. It's no longer a two-step
process.

Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
pull/1281/head
Aaron Lehmann 2016-01-06 14:15:14 -08:00
parent 697af09566
commit 6d17423a6d
7 changed files with 11 additions and 23 deletions

View File

@ -17,6 +17,7 @@ const MediaTypeManifestList = "application/vnd.docker.distribution.manifest.list
// packages version of the manifest. // packages version of the manifest.
var SchemaVersion = manifest.Versioned{ var SchemaVersion = manifest.Versioned{
SchemaVersion: 2, SchemaVersion: 2,
MediaType: MediaTypeManifestList,
} }
func init() { func init() {
@ -68,10 +69,6 @@ type ManifestDescriptor struct {
type ManifestList struct { type ManifestList struct {
manifest.Versioned manifest.Versioned
// MediaType is the media type of this document. It should always
// be set to MediaTypeManifestList.
MediaType string `json:"mediaType"`
// Config references the image configuration as a blob. // Config references the image configuration as a blob.
Manifests []ManifestDescriptor `json:"manifests"` Manifests []ManifestDescriptor `json:"manifests"`
} }
@ -102,7 +99,6 @@ type DeserializedManifestList struct {
func FromDescriptors(descriptors []ManifestDescriptor) (*DeserializedManifestList, error) { func FromDescriptors(descriptors []ManifestDescriptor) (*DeserializedManifestList, error) {
m := ManifestList{ m := ManifestList{
Versioned: SchemaVersion, Versioned: SchemaVersion,
MediaType: MediaTypeManifestList,
} }
m.Manifests = make([]ManifestDescriptor, len(descriptors), len(descriptors)) m.Manifests = make([]ManifestDescriptor, len(descriptors), len(descriptors))

View File

@ -4,7 +4,6 @@ import (
"github.com/docker/distribution" "github.com/docker/distribution"
"github.com/docker/distribution/context" "github.com/docker/distribution/context"
"github.com/docker/distribution/digest" "github.com/docker/distribution/digest"
"github.com/docker/distribution/manifest"
) )
// builder is a type for constructing manifests. // builder is a type for constructing manifests.
@ -36,10 +35,7 @@ func NewManifestBuilder(bs distribution.BlobService, configJSON []byte) distribu
// Build produces a final manifest from the given references. // Build produces a final manifest from the given references.
func (mb *builder) Build(ctx context.Context) (distribution.Manifest, error) { func (mb *builder) Build(ctx context.Context) (distribution.Manifest, error) {
m := Manifest{ m := Manifest{
Versioned: manifest.Versioned{ Versioned: SchemaVersion,
SchemaVersion: 2,
},
MediaType: MediaTypeManifest,
Layers: make([]distribution.Descriptor, len(mb.layers)), Layers: make([]distribution.Descriptor, len(mb.layers)),
} }
copy(m.Layers, mb.layers) copy(m.Layers, mb.layers)

View File

@ -27,6 +27,7 @@ var (
// packages version of the manifest. // packages version of the manifest.
SchemaVersion = manifest.Versioned{ SchemaVersion = manifest.Versioned{
SchemaVersion: 2, SchemaVersion: 2,
MediaType: MediaTypeManifest,
} }
) )
@ -50,7 +51,6 @@ func init() {
// Manifest defines a schema2 manifest. // Manifest defines a schema2 manifest.
type Manifest struct { type Manifest struct {
manifest.Versioned manifest.Versioned
MediaType string `json:"mediaType"`
// Config references the image configuration as a blob. // Config references the image configuration as a blob.
Config distribution.Descriptor `json:"config"` Config distribution.Descriptor `json:"config"`

View File

@ -29,7 +29,6 @@ var expectedManifestSerialization = []byte(`{
func TestManifest(t *testing.T) { func TestManifest(t *testing.T) {
manifest := Manifest{ manifest := Manifest{
Versioned: SchemaVersion, Versioned: SchemaVersion,
MediaType: MediaTypeManifest,
Config: distribution.Descriptor{ Config: distribution.Descriptor{
Digest: "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b", Digest: "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b",
Size: 985, Size: 985,

View File

@ -1,9 +1,12 @@
package manifest package manifest
// Versioned provides a struct with just the manifest schemaVersion. Incoming // Versioned provides a struct with the manifest schemaVersion and . Incoming
// content with unknown schema version can be decoded against this struct to // content with unknown schema version can be decoded against this struct to
// check the version. // check the version.
type Versioned struct { type Versioned struct {
// SchemaVersion is the image manifest schema that this image follows // SchemaVersion is the image manifest schema that this image follows
SchemaVersion int `json:"schemaVersion"` SchemaVersion int `json:"schemaVersion"`
// MediaType is the media type of this schema.
MediaType string `json:"mediaType,omitempty"`
} }

View File

@ -1096,8 +1096,8 @@ func testManifestAPISchema2(t *testing.T, env *testEnv, imageName string) manife
manifest := &schema2.Manifest{ manifest := &schema2.Manifest{
Versioned: manifest.Versioned{ Versioned: manifest.Versioned{
SchemaVersion: 2, SchemaVersion: 2,
MediaType: schema2.MediaTypeManifest,
}, },
MediaType: schema2.MediaTypeManifest,
Config: distribution.Descriptor{ Config: distribution.Descriptor{
Digest: "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b", Digest: "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b",
Size: 3253, Size: 3253,
@ -1410,8 +1410,8 @@ func testManifestAPIManifestList(t *testing.T, env *testEnv, args manifestArgs)
manifestList := &manifestlist.ManifestList{ manifestList := &manifestlist.ManifestList{
Versioned: manifest.Versioned{ Versioned: manifest.Versioned{
SchemaVersion: 2, SchemaVersion: 2,
MediaType: manifestlist.MediaTypeManifestList,
}, },
MediaType: manifestlist.MediaTypeManifestList,
Manifests: []manifestlist.ManifestDescriptor{ Manifests: []manifestlist.ManifestDescriptor{
{ {
Descriptor: distribution.Descriptor{ Descriptor: distribution.Descriptor{

View File

@ -95,19 +95,13 @@ func (ms *manifestStore) Get(ctx context.Context, dgst digest.Digest, options ..
return ms.schema1Handler.Unmarshal(ctx, dgst, content) return ms.schema1Handler.Unmarshal(ctx, dgst, content)
case 2: case 2:
// This can be an image manifest or a manifest list // This can be an image manifest or a manifest list
var mediaType struct { switch versioned.MediaType {
MediaType string `json:"mediaType"`
}
if err = json.Unmarshal(content, &mediaType); err != nil {
return nil, err
}
switch mediaType.MediaType {
case schema2.MediaTypeManifest: case schema2.MediaTypeManifest:
return ms.schema2Handler.Unmarshal(ctx, dgst, content) return ms.schema2Handler.Unmarshal(ctx, dgst, content)
case manifestlist.MediaTypeManifestList: case manifestlist.MediaTypeManifestList:
return ms.manifestListHandler.Unmarshal(ctx, dgst, content) return ms.manifestListHandler.Unmarshal(ctx, dgst, content)
default: default:
return nil, distribution.ErrManifestVerification{fmt.Errorf("unrecognized manifest content type %s", mediaType.MediaType)} return nil, distribution.ErrManifestVerification{fmt.Errorf("unrecognized manifest content type %s", versioned.MediaType)}
} }
} }