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:
parent
923c7763b0
commit
8867e8fac3
8 changed files with 27 additions and 23 deletions
|
@ -11,20 +11,24 @@ 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,
|
||||||
|
configMediaType: configMediaType,
|
||||||
configJSON: make([]byte, len(configJSON)),
|
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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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{
|
||||||
{
|
{
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue