Merge pull request #3896 from pluralsh/clean-blobstore-rebase

Remove blobstore from manifest builder
This commit is contained in:
Milos Gajdos 2023-05-19 15:05:16 +01:00 committed by GitHub
commit 983358f8e2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 24 additions and 68 deletions

View File

@ -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)
}

View File

@ -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 {

View File

@ -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)