Update schema2 builder to take media type

Modify manifest builder so it can be used to build
manifests with different configuration media types.
Rename config media type const to image config.

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
Signed-off-by: Derek McGowan <derek@mcgstyle.net>
This commit is contained in:
Derek McGowan 2016-12-14 16:17:20 -08:00
parent 923c7763b0
commit 8867e8fac3
No known key found for this signature in database
GPG key ID: F58C5D0A4405ACDB
8 changed files with 27 additions and 23 deletions

View file

@ -11,21 +11,25 @@ type builder struct {
// bs is a BlobService used to publish the configuration blob. // bs is a BlobService used to publish the configuration blob.
bs distribution.BlobService bs distribution.BlobService
// configMediaType is media type used to describe configuration
configMediaType string
// configJSON references // configJSON references
configJSON []byte configJSON []byte
// layers is a list of layer descriptors that gets built by successive // dependencies is a list of descriptors that gets built by successive
// calls to AppendReference. // calls to AppendReference. In case of image configuration these are layers.
layers []distribution.Descriptor dependencies []distribution.Descriptor
} }
// NewManifestBuilder is used to build new manifests for the current schema // NewManifestBuilder is used to build new manifests for the current schema
// version. It takes a BlobService so it can publish the configuration blob // version. It takes a BlobService so it can publish the configuration blob
// as part of the Build process. // as part of the Build process.
func NewManifestBuilder(bs distribution.BlobService, configJSON []byte) distribution.ManifestBuilder { func NewManifestBuilder(bs distribution.BlobService, configMediaType string, configJSON []byte) distribution.ManifestBuilder {
mb := &builder{ mb := &builder{
bs: bs, bs: bs,
configJSON: make([]byte, len(configJSON)), configMediaType: configMediaType,
configJSON: make([]byte, len(configJSON)),
} }
copy(mb.configJSON, configJSON) copy(mb.configJSON, configJSON)
@ -36,9 +40,9 @@ func NewManifestBuilder(bs distribution.BlobService, configJSON []byte) distribu
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: SchemaVersion, Versioned: SchemaVersion,
Layers: make([]distribution.Descriptor, len(mb.layers)), Layers: make([]distribution.Descriptor, len(mb.dependencies)),
} }
copy(m.Layers, mb.layers) copy(m.Layers, mb.dependencies)
configDigest := digest.FromBytes(mb.configJSON) configDigest := digest.FromBytes(mb.configJSON)
@ -48,7 +52,7 @@ func (mb *builder) Build(ctx context.Context) (distribution.Manifest, error) {
case nil: case nil:
// Override MediaType, since Put always replaces the specified media // Override MediaType, since Put always replaces the specified media
// type with application/octet-stream in the descriptor it returns. // type with application/octet-stream in the descriptor it returns.
m.Config.MediaType = MediaTypeConfig m.Config.MediaType = mb.configMediaType
return FromStruct(m) return FromStruct(m)
case distribution.ErrBlobUnknown: case distribution.ErrBlobUnknown:
// nop // nop
@ -57,10 +61,10 @@ func (mb *builder) Build(ctx context.Context) (distribution.Manifest, error) {
} }
// Add config to the blob store // Add config to the blob store
m.Config, err = mb.bs.Put(ctx, MediaTypeConfig, mb.configJSON) m.Config, err = mb.bs.Put(ctx, mb.configMediaType, mb.configJSON)
// Override MediaType, since Put always replaces the specified media // Override MediaType, since Put always replaces the specified media
// type with application/octet-stream in the descriptor it returns. // type with application/octet-stream in the descriptor it returns.
m.Config.MediaType = MediaTypeConfig m.Config.MediaType = mb.configMediaType
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -70,11 +74,11 @@ func (mb *builder) Build(ctx context.Context) (distribution.Manifest, error) {
// AppendReference adds a reference to the current ManifestBuilder. // AppendReference adds a reference to the current ManifestBuilder.
func (mb *builder) AppendReference(d distribution.Describable) error { func (mb *builder) AppendReference(d distribution.Describable) error {
mb.layers = append(mb.layers, d.Descriptor()) mb.dependencies = append(mb.dependencies, d.Descriptor())
return nil return nil
} }
// References returns the current references added to this builder. // References returns the current references added to this builder.
func (mb *builder) References() []distribution.Descriptor { func (mb *builder) References() []distribution.Descriptor {
return mb.layers return mb.dependencies
} }

View file

@ -166,7 +166,7 @@ func TestBuilder(t *testing.T) {
} }
bs := &mockBlobService{descriptors: make(map[digest.Digest]distribution.Descriptor)} bs := &mockBlobService{descriptors: make(map[digest.Digest]distribution.Descriptor)}
builder := NewManifestBuilder(bs, imgJSON) builder := NewManifestBuilder(bs, MediaTypeImageConfig, imgJSON)
for _, d := range descriptors { for _, d := range descriptors {
if err := builder.AppendReference(d); err != nil { if err := builder.AppendReference(d); err != nil {
@ -195,7 +195,7 @@ func TestBuilder(t *testing.T) {
if target.Digest != configDigest { if target.Digest != configDigest {
t.Fatalf("unexpected digest in target: %s", target.Digest.String()) t.Fatalf("unexpected digest in target: %s", target.Digest.String())
} }
if target.MediaType != MediaTypeConfig { if target.MediaType != MediaTypeImageConfig {
t.Fatalf("unexpected media type in target: %s", target.MediaType) t.Fatalf("unexpected media type in target: %s", target.MediaType)
} }
if target.Size != 3153 { if target.Size != 3153 {

View file

@ -14,8 +14,8 @@ const (
// MediaTypeManifest specifies the mediaType for the current version. // MediaTypeManifest specifies the mediaType for the current version.
MediaTypeManifest = "application/vnd.docker.distribution.manifest.v2+json" MediaTypeManifest = "application/vnd.docker.distribution.manifest.v2+json"
// MediaTypeConfig specifies the mediaType for the image configuration. // MediaTypeImageConfig specifies the mediaType for the image configuration.
MediaTypeConfig = "application/vnd.docker.container.image.v1+json" MediaTypeImageConfig = "application/vnd.docker.container.image.v1+json"
// MediaTypePluginConfig specifies the mediaType for plugin configuration. // MediaTypePluginConfig specifies the mediaType for plugin configuration.
MediaTypePluginConfig = "application/vnd.docker.plugin.v1+json" MediaTypePluginConfig = "application/vnd.docker.plugin.v1+json"

View file

@ -32,7 +32,7 @@ func TestManifest(t *testing.T) {
Config: distribution.Descriptor{ Config: distribution.Descriptor{
Digest: "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b", Digest: "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b",
Size: 985, Size: 985,
MediaType: MediaTypeConfig, MediaType: MediaTypeImageConfig,
}, },
Layers: []distribution.Descriptor{ Layers: []distribution.Descriptor{
{ {
@ -82,7 +82,7 @@ func TestManifest(t *testing.T) {
if target.Digest != "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b" { if target.Digest != "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b" {
t.Fatalf("unexpected digest in target: %s", target.Digest.String()) t.Fatalf("unexpected digest in target: %s", target.Digest.String())
} }
if target.MediaType != MediaTypeConfig { if target.MediaType != MediaTypeImageConfig {
t.Fatalf("unexpected media type in target: %s", target.MediaType) t.Fatalf("unexpected media type in target: %s", target.MediaType)
} }
if target.Size != 985 { if target.Size != 985 {

View file

@ -1218,7 +1218,7 @@ func testManifestAPISchema2(t *testing.T, env *testEnv, imageName reference.Name
Config: distribution.Descriptor{ Config: distribution.Descriptor{
Digest: "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b", Digest: "sha256:1a9ec845ee94c202b2d5da74a24f0ed2058318bfa9879fa541efaecba272e86b",
Size: 3253, Size: 3253,
MediaType: schema2.MediaTypeConfig, MediaType: schema2.MediaTypeImageConfig,
}, },
Layers: []distribution.Descriptor{ Layers: []distribution.Descriptor{
{ {

View file

@ -360,7 +360,7 @@ func (imh *imageManifestHandler) applyResourcePolicy(manifest distribution.Manif
class = "image" class = "image"
case *schema2.DeserializedManifest: case *schema2.DeserializedManifest:
switch m.Config.MediaType { switch m.Config.MediaType {
case schema2.MediaTypeConfig: case schema2.MediaTypeImageConfig:
class = "image" class = "image"
case schema2.MediaTypePluginConfig: case schema2.MediaTypePluginConfig:
class = "plugin" class = "plugin"

View file

@ -20,7 +20,7 @@ func TestVerifyManifestForeignLayer(t *testing.T) {
repo := makeRepository(t, registry, "test") repo := makeRepository(t, registry, "test")
manifestService := makeManifestService(t, repo) manifestService := makeManifestService(t, repo)
config, err := repo.Blobs(ctx).Put(ctx, schema2.MediaTypeConfig, nil) config, err := repo.Blobs(ctx).Put(ctx, schema2.MediaTypeImageConfig, nil)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View file

@ -73,7 +73,7 @@ func MakeSchema1Manifest(digests []digest.Digest) (distribution.Manifest, error)
func MakeSchema2Manifest(repository distribution.Repository, digests []digest.Digest) (distribution.Manifest, error) { func MakeSchema2Manifest(repository distribution.Repository, digests []digest.Digest) (distribution.Manifest, error) {
ctx := context.Background() ctx := context.Background()
blobStore := repository.Blobs(ctx) blobStore := repository.Blobs(ctx)
builder := schema2.NewManifestBuilder(blobStore, []byte{}) builder := schema2.NewManifestBuilder(blobStore, schema2.MediaTypeImageConfig, []byte{})
for _, digest := range digests { for _, digest := range digests {
builder.AppendReference(distribution.Descriptor{Digest: digest}) builder.AppendReference(distribution.Descriptor{Digest: digest})
} }