Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove blobstore from manifest builder #3896

Merged
merged 2 commits into from
May 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 6 additions & 34 deletions manifest/schema2/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)

Expand All @@ -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)
}
Expand Down
37 changes: 7 additions & 30 deletions manifest/schema2/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down
15 changes: 11 additions & 4 deletions testutil/manifests.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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)
Expand Down
Loading