diff --git a/manifest/schema2/builder.go b/manifest/schema2/builder.go index 52da82e3..585741d0 100644 --- a/manifest/schema2/builder.go +++ b/manifest/schema2/builder.go @@ -4,16 +4,12 @@ import ( "context" "github.com/distribution/distribution/v3" - "github.com/opencontainers/go-digest" ) // builder is a type for constructing manifests. type builder struct { - // bs is a BlobService used to publish the configuration blob. - bs distribution.BlobService - - // configMediaType is media type used to describe configuration - configMediaType string + // configDescriptor is used to describe configuration + configDescriptor distribution.Descriptor // configJSON references configJSON []byte @@ -26,11 +22,10 @@ type builder struct { // NewManifestBuilder is used to build new manifests for the current schema // version. It takes a BlobService so it can publish the configuration blob // as part of the Build process. -func NewManifestBuilder(bs distribution.BlobService, configMediaType string, configJSON []byte) distribution.ManifestBuilder { +func NewManifestBuilder(configDescriptor distribution.Descriptor, configJSON []byte) distribution.ManifestBuilder { mb := &builder{ - bs: bs, - configMediaType: configMediaType, - configJSON: make([]byte, len(configJSON)), + configDescriptor: configDescriptor, + configJSON: make([]byte, len(configJSON)), } copy(mb.configJSON, configJSON) @@ -45,30 +40,7 @@ func (mb *builder) Build(ctx context.Context) (distribution.Manifest, error) { } copy(m.Layers, mb.dependencies) - configDigest := digest.FromBytes(mb.configJSON) - - var err error - m.Config, err = mb.bs.Stat(ctx, configDigest) - switch err { - case nil: - // Override MediaType, since Put always replaces the specified media - // type with application/octet-stream in the descriptor it returns. - m.Config.MediaType = mb.configMediaType - return FromStruct(m) - case distribution.ErrBlobUnknown: - // nop - default: - return nil, err - } - - // Add config to the blob store - m.Config, err = mb.bs.Put(ctx, mb.configMediaType, mb.configJSON) - // Override MediaType, since Put always replaces the specified media - // type with application/octet-stream in the descriptor it returns. - m.Config.MediaType = mb.configMediaType - if err != nil { - return nil, err - } + m.Config = mb.configDescriptor return FromStruct(m) } diff --git a/manifest/schema2/builder_test.go b/manifest/schema2/builder_test.go index aa9f17c1..039246a3 100644 --- a/manifest/schema2/builder_test.go +++ b/manifest/schema2/builder_test.go @@ -9,28 +9,6 @@ import ( "github.com/opencontainers/go-digest" ) -type mockBlobService struct { - descriptors map[digest.Digest]distribution.Descriptor - distribution.BlobService -} - -func (bs *mockBlobService) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) { - if descriptor, ok := bs.descriptors[dgst]; ok { - return descriptor, nil - } - return distribution.Descriptor{}, distribution.ErrBlobUnknown -} - -func (bs *mockBlobService) Put(ctx context.Context, mediaType string, p []byte) (distribution.Descriptor, error) { - d := distribution.Descriptor{ - MediaType: "application/octet-stream", - Digest: digest.FromBytes(p), - Size: int64(len(p)), - } - bs.descriptors[d.Digest] = d - return d, nil -} - func TestBuilder(t *testing.T) { imgJSON := []byte(`{ "architecture": "amd64", @@ -150,8 +128,13 @@ func TestBuilder(t *testing.T) { }, } - bs := &mockBlobService{descriptors: make(map[digest.Digest]distribution.Descriptor)} - builder := NewManifestBuilder(bs, MediaTypeImageConfig, imgJSON) + d := distribution.Descriptor{ + Digest: digest.FromBytes(imgJSON), + Size: int64(len(imgJSON)), + MediaType: MediaTypeImageConfig, + } + + builder := NewManifestBuilder(d, imgJSON) for _, d := range descriptors { if err := builder.AppendReference(d); err != nil { @@ -164,12 +147,6 @@ func TestBuilder(t *testing.T) { t.Fatalf("Build returned error: %v", err) } - // Check that the config was put in the blob store - _, err = bs.Stat(context.Background(), configDigest) - if err != nil { - t.Fatal("config was not put in the blob store") - } - manifest := built.(*DeserializedManifest).Manifest if manifest.Versioned.SchemaVersion != 2 { diff --git a/testutil/manifests.go b/testutil/manifests.go index 2b421149..3a6a333b 100644 --- a/testutil/manifests.go +++ b/testutil/manifests.go @@ -44,7 +44,7 @@ func MakeManifestList(blobstatter distribution.BlobStatter, manifestDigests []di // // Deprecated: Docker Image Manifest v2, Schema 1 is deprecated since 2015. // Use Docker Image Manifest v2, Schema 2, or the OCI Image Specification. -func MakeSchema1Manifest(digests []digest.Digest) (distribution.Manifest, error) { +func MakeSchema1Manifest(digests []digest.Digest) (*schema1.SignedManifest, error) { mfst := schema1.Manifest{ Versioned: manifest.Versioned{ SchemaVersion: 1, @@ -76,9 +76,16 @@ func MakeSchema1Manifest(digests []digest.Digest) (distribution.Manifest, error) func MakeSchema2Manifest(repository distribution.Repository, digests []digest.Digest) (distribution.Manifest, error) { ctx := context.Background() blobStore := repository.Blobs(ctx) - builder := schema2.NewManifestBuilder(blobStore, schema2.MediaTypeImageConfig, []byte{}) - for _, d := range digests { - builder.AppendReference(distribution.Descriptor{Digest: d}) + + var configJSON []byte + + d, err := blobStore.Put(ctx, schema2.MediaTypeImageConfig, configJSON) + if err != nil { + return nil, fmt.Errorf("unexpected error storing content in blobstore: %v", err) + } + builder := schema2.NewManifestBuilder(d, configJSON) + for _, digest := range digests { + builder.AppendReference(distribution.Descriptor{Digest: digest}) } mfst, err := builder.Build(ctx)