replace uses of Descriptor alias

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn
2024-09-06 11:59:19 +02:00
parent 740b31105e
commit 0ab7f326e6
54 changed files with 417 additions and 381 deletions

View File

@@ -16,6 +16,7 @@ import (
"github.com/distribution/distribution/v3/testutil"
"github.com/distribution/reference"
"github.com/opencontainers/go-digest"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
)
// TestWriteSeek tests that the current file size can be
@@ -133,7 +134,7 @@ func TestSimpleBlobUpload(t *testing.T) {
}
sha256Digest := digest.NewDigest("sha256", h)
desc, err := blobUpload.Commit(ctx, distribution.Descriptor{Digest: dgst})
desc, err := blobUpload.Commit(ctx, v1.Descriptor{Digest: dgst})
if err != nil {
t.Fatalf("unexpected error finishing layer upload: %v", err)
}
@@ -285,7 +286,7 @@ func TestSimpleBlobRead(t *testing.T) {
t.Fatalf("error getting seeker size for random layer: %v", err)
}
descBefore := distribution.Descriptor{Digest: dgst, MediaType: "application/octet-stream", Size: randomLayerSize}
descBefore := v1.Descriptor{Digest: dgst, MediaType: "application/octet-stream", Size: randomLayerSize}
t.Logf("desc: %v", descBefore)
desc, err = addBlob(ctx, bs, descBefore, randomLayerReader)
@@ -398,7 +399,7 @@ func TestBlobMount(t *testing.T) {
t.Fatalf("unexpected error uploading layer data: %v", err)
}
desc, err := blobUpload.Commit(ctx, distribution.Descriptor{Digest: dgst})
desc, err := blobUpload.Commit(ctx, v1.Descriptor{Digest: dgst})
if err != nil {
t.Fatalf("unexpected error finishing layer upload: %v", err)
}
@@ -555,7 +556,7 @@ func simpleUpload(t *testing.T, bs distribution.BlobIngester, blob []byte, expec
t.Fatalf("digest not as expected: %v != %v", dgst, expectedDigest)
}
desc, err := wr.Commit(ctx, distribution.Descriptor{Digest: dgst})
desc, err := wr.Commit(ctx, v1.Descriptor{Digest: dgst})
if err != nil {
t.Fatalf("unexpected error committing write: %v", err)
}
@@ -593,18 +594,18 @@ func seekerSize(seeker io.ReadSeeker) (int64, error) {
// addBlob simply consumes the reader and inserts into the blob service,
// returning a descriptor on success.
func addBlob(ctx context.Context, bs distribution.BlobIngester, desc distribution.Descriptor, rd io.Reader) (distribution.Descriptor, error) {
func addBlob(ctx context.Context, bs distribution.BlobIngester, desc v1.Descriptor, rd io.Reader) (v1.Descriptor, error) {
wr, err := bs.Create(ctx)
if err != nil {
return distribution.Descriptor{}, err
return v1.Descriptor{}, err
}
// nolint:errcheck
defer wr.Cancel(ctx)
if nn, err := io.Copy(wr, rd); err != nil {
return distribution.Descriptor{}, err
return v1.Descriptor{}, err
} else if nn != desc.Size {
return distribution.Descriptor{}, fmt.Errorf("incorrect number of bytes copied: %v != %v", nn, desc.Size)
return v1.Descriptor{}, fmt.Errorf("incorrect number of bytes copied: %v != %v", nn, desc.Size)
}
return wr.Commit(ctx, desc)

View File

@@ -9,6 +9,7 @@ import (
"github.com/distribution/distribution/v3/internal/dcontext"
"github.com/distribution/distribution/v3/registry/storage/driver"
"github.com/opencontainers/go-digest"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
)
// blobStore implements the read side of the blob store interface over a
@@ -59,7 +60,7 @@ func (bs *blobStore) Open(ctx context.Context, dgst digest.Digest) (io.ReadSeekC
// Put stores the content p in the blob store, calculating the digest. If the
// content is already present, only the digest will be returned. This should
// only be used for small objects, such as manifests. This implemented as a convenience for other Put implementations
func (bs *blobStore) Put(ctx context.Context, mediaType string, p []byte) (distribution.Descriptor, error) {
func (bs *blobStore) Put(ctx context.Context, mediaType string, p []byte) (v1.Descriptor, error) {
dgst := digest.FromBytes(p)
desc, err := bs.statter.Stat(ctx, dgst)
if err == nil {
@@ -68,16 +69,16 @@ func (bs *blobStore) Put(ctx context.Context, mediaType string, p []byte) (distr
} else if err != distribution.ErrBlobUnknown {
dcontext.GetLogger(ctx).Errorf("blobStore: error stating content (%v): %v", dgst, err)
// real error, return it
return distribution.Descriptor{}, err
return v1.Descriptor{}, err
}
bp, err := bs.path(dgst)
if err != nil {
return distribution.Descriptor{}, err
return v1.Descriptor{}, err
}
// TODO(stevvooe): Write out mediatype here, as well.
return distribution.Descriptor{
return v1.Descriptor{
Size: int64(len(p)),
// NOTE(stevvooe): The central blob store firewalls media types from
@@ -161,21 +162,21 @@ var _ distribution.BlobDescriptorService = &blobStatter{}
// Stat implements BlobStatter.Stat by returning the descriptor for the blob
// in the main blob store. If this method returns successfully, there is
// strong guarantee that the blob exists and is available.
func (bs *blobStatter) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) {
func (bs *blobStatter) Stat(ctx context.Context, dgst digest.Digest) (v1.Descriptor, error) {
path, err := pathFor(blobDataPathSpec{
digest: dgst,
})
if err != nil {
return distribution.Descriptor{}, err
return v1.Descriptor{}, err
}
fi, err := bs.driver.Stat(ctx, path)
if err != nil {
switch err := err.(type) {
case driver.PathNotFoundError:
return distribution.Descriptor{}, distribution.ErrBlobUnknown
return v1.Descriptor{}, distribution.ErrBlobUnknown
default:
return distribution.Descriptor{}, err
return v1.Descriptor{}, err
}
}
@@ -184,14 +185,14 @@ func (bs *blobStatter) Stat(ctx context.Context, dgst digest.Digest) (distributi
// calculated a blob path and then detected a directory. We log the
// error and then error on the side of not knowing about the blob.
dcontext.GetLogger(ctx).Warnf("blob path should not be a directory: %q", path)
return distribution.Descriptor{}, distribution.ErrBlobUnknown
return v1.Descriptor{}, distribution.ErrBlobUnknown
}
// TODO(stevvooe): Add method to resolve the mediatype. We can store and
// cache a "global" media type for the blob, even if a specific repo has a
// mediatype that overrides the main one.
return distribution.Descriptor{
return v1.Descriptor{
Size: fi.Size(),
// NOTE(stevvooe): The central blob store firewalls media types from
@@ -206,6 +207,6 @@ func (bs *blobStatter) Clear(ctx context.Context, dgst digest.Digest) error {
return distribution.ErrUnsupported
}
func (bs *blobStatter) SetDescriptor(ctx context.Context, dgst digest.Digest, desc distribution.Descriptor) error {
func (bs *blobStatter) SetDescriptor(ctx context.Context, dgst digest.Digest, desc v1.Descriptor) error {
return distribution.ErrUnsupported
}

View File

@@ -12,6 +12,7 @@ import (
"github.com/distribution/distribution/v3/internal/dcontext"
storagedriver "github.com/distribution/distribution/v3/registry/storage/driver"
"github.com/opencontainers/go-digest"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/sirupsen/logrus"
)
@@ -54,11 +55,11 @@ func (bw *blobWriter) StartedAt() time.Time {
// Commit marks the upload as completed, returning a valid descriptor. The
// final size and digest are checked against the first descriptor provided.
func (bw *blobWriter) Commit(ctx context.Context, desc distribution.Descriptor) (distribution.Descriptor, error) {
func (bw *blobWriter) Commit(ctx context.Context, desc v1.Descriptor) (v1.Descriptor, error) {
dcontext.GetLogger(ctx).Debug("(*blobWriter).Commit")
if err := bw.fileWriter.Commit(ctx); err != nil {
return distribution.Descriptor{}, err
return v1.Descriptor{}, err
}
bw.Close()
@@ -66,24 +67,24 @@ func (bw *blobWriter) Commit(ctx context.Context, desc distribution.Descriptor)
canonical, err := bw.validateBlob(ctx, desc)
if err != nil {
return distribution.Descriptor{}, err
return v1.Descriptor{}, err
}
if err := bw.moveBlob(ctx, canonical); err != nil {
return distribution.Descriptor{}, err
return v1.Descriptor{}, err
}
if err := bw.blobStore.linkBlob(ctx, canonical, desc.Digest); err != nil {
return distribution.Descriptor{}, err
return v1.Descriptor{}, err
}
if err := bw.removeResources(ctx); err != nil {
return distribution.Descriptor{}, err
return v1.Descriptor{}, err
}
err = bw.blobStore.blobAccessController.SetDescriptor(ctx, canonical.Digest, canonical)
if err != nil {
return distribution.Descriptor{}, err
return v1.Descriptor{}, err
}
bw.committed = true
@@ -160,7 +161,7 @@ func (bw *blobWriter) Close() error {
// validateBlob checks the data against the digest, returning an error if it
// does not match. The canonical descriptor is returned.
func (bw *blobWriter) validateBlob(ctx context.Context, desc distribution.Descriptor) (distribution.Descriptor, error) {
func (bw *blobWriter) validateBlob(ctx context.Context, desc v1.Descriptor) (v1.Descriptor, error) {
var (
verified, fullHash bool
canonical digest.Digest
@@ -169,7 +170,7 @@ func (bw *blobWriter) validateBlob(ctx context.Context, desc distribution.Descri
if desc.Digest == "" {
// if no descriptors are provided, we have nothing to validate
// against. We don't really want to support this for the registry.
return distribution.Descriptor{}, distribution.ErrBlobInvalidDigest{
return v1.Descriptor{}, distribution.ErrBlobInvalidDigest{
Reason: fmt.Errorf("cannot validate against empty digest"),
}
}
@@ -186,11 +187,11 @@ func (bw *blobWriter) validateBlob(ctx context.Context, desc distribution.Descri
desc.Size = 0
default:
// Any other error we want propagated up the stack.
return distribution.Descriptor{}, err
return v1.Descriptor{}, err
}
} else {
if fi.IsDir() {
return distribution.Descriptor{}, fmt.Errorf("unexpected directory at upload location %q", bw.path)
return v1.Descriptor{}, fmt.Errorf("unexpected directory at upload location %q", bw.path)
}
size = fi.Size()
@@ -198,7 +199,7 @@ func (bw *blobWriter) validateBlob(ctx context.Context, desc distribution.Descri
if desc.Size > 0 {
if desc.Size != size {
return distribution.Descriptor{}, distribution.ErrBlobInvalidLength
return v1.Descriptor{}, distribution.ErrBlobInvalidLength
}
} else {
// if provided 0 or negative length, we can assume caller doesn't know or
@@ -226,7 +227,7 @@ func (bw *blobWriter) validateBlob(ctx context.Context, desc distribution.Descri
// Not using resumable digests, so we need to hash the entire layer.
fullHash = true
} else {
return distribution.Descriptor{}, err
return v1.Descriptor{}, err
}
if fullHash {
@@ -249,14 +250,14 @@ func (bw *blobWriter) validateBlob(ctx context.Context, desc distribution.Descri
// Read the file from the backend driver and validate it.
fr, err := newFileReader(ctx, bw.driver, bw.path, desc.Size)
if err != nil {
return distribution.Descriptor{}, err
return v1.Descriptor{}, err
}
defer fr.Close()
tr := io.TeeReader(fr, digester.Hash())
if _, err := io.Copy(verifier, tr); err != nil {
return distribution.Descriptor{}, err
return v1.Descriptor{}, err
}
canonical = digester.Digest()
@@ -271,7 +272,7 @@ func (bw *blobWriter) validateBlob(ctx context.Context, desc distribution.Descri
"provided": desc.Digest,
}, "canonical", "provided").
Errorf("canonical digest does match provided digest")
return distribution.Descriptor{}, distribution.ErrBlobInvalidDigest{
return v1.Descriptor{}, distribution.ErrBlobInvalidDigest{
Digest: desc.Digest,
Reason: fmt.Errorf("content does not match digest"),
}
@@ -290,7 +291,7 @@ func (bw *blobWriter) validateBlob(ctx context.Context, desc distribution.Descri
// moveBlob moves the data into its final, hash-qualified destination,
// identified by dgst. The layer should be validated before commencing the
// move.
func (bw *blobWriter) moveBlob(ctx context.Context, desc distribution.Descriptor) error {
func (bw *blobWriter) moveBlob(ctx context.Context, desc v1.Descriptor) error {
blobPath, err := pathFor(blobDataPathSpec{
digest: desc.Digest,
})

View File

@@ -6,6 +6,7 @@ import (
"fmt"
"github.com/distribution/distribution/v3"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
)
// BlobDescriptorCacheProvider provides repository scoped
@@ -18,7 +19,7 @@ type BlobDescriptorCacheProvider interface {
// ValidateDescriptor provides a helper function to ensure that caches have
// common criteria for admitting descriptors.
func ValidateDescriptor(desc distribution.Descriptor) error {
func ValidateDescriptor(desc v1.Descriptor) error {
if err := desc.Digest.Validate(); err != nil {
return err
}

View File

@@ -7,6 +7,7 @@ import (
"github.com/distribution/distribution/v3"
digest "github.com/opencontainers/go-digest"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
)
func TestCacheSet(t *testing.T) {
@@ -21,7 +22,7 @@ func TestCacheSet(t *testing.T) {
t.Fatalf("Unexpected error %v, expected %v", err, distribution.ErrBlobUnknown)
}
desc := distribution.Descriptor{
desc := v1.Descriptor{
Digest: dgst,
}
if err := backend.SetDescriptor(ctx, dgst, desc); err != nil {
@@ -43,7 +44,7 @@ func TestCacheSet(t *testing.T) {
t.Fatalf("Unexpected descriptor %v, expected %v", cache.sets[dgst][0], desc)
}
desc2 := distribution.Descriptor{
desc2 := v1.Descriptor{
Digest: digest.Digest("dontvalidate 2"),
}
cache.sets[dgst] = append(cache.sets[dgst], desc2)
@@ -69,7 +70,7 @@ func TestCacheError(t *testing.T) {
t.Fatalf("Unexpected error %v, expected %v", err, distribution.ErrBlobUnknown)
}
desc := distribution.Descriptor{
desc := v1.Descriptor{
Digest: dgst,
}
if err := backend.SetDescriptor(ctx, dgst, desc); err != nil {
@@ -92,36 +93,36 @@ func TestCacheError(t *testing.T) {
func newTestStatter() *testStatter {
return &testStatter{
stats: []digest.Digest{},
sets: map[digest.Digest][]distribution.Descriptor{},
sets: map[digest.Digest][]v1.Descriptor{},
}
}
func newErrTestStatter(err error) *testStatter {
return &testStatter{
sets: map[digest.Digest][]distribution.Descriptor{},
sets: map[digest.Digest][]v1.Descriptor{},
err: err,
}
}
type testStatter struct {
stats []digest.Digest
sets map[digest.Digest][]distribution.Descriptor
sets map[digest.Digest][]v1.Descriptor
err error
}
func (s *testStatter) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) {
func (s *testStatter) Stat(ctx context.Context, dgst digest.Digest) (v1.Descriptor, error) {
if s.err != nil {
return distribution.Descriptor{}, s.err
return v1.Descriptor{}, s.err
}
if set := s.sets[dgst]; len(set) > 0 {
return set[len(set)-1], nil
}
return distribution.Descriptor{}, distribution.ErrBlobUnknown
return v1.Descriptor{}, distribution.ErrBlobUnknown
}
func (s *testStatter) SetDescriptor(ctx context.Context, dgst digest.Digest, desc distribution.Descriptor) error {
func (s *testStatter) SetDescriptor(ctx context.Context, dgst digest.Digest, desc v1.Descriptor) error {
s.sets[dgst] = append(s.sets[dgst], desc)
return s.err
}

View File

@@ -8,6 +8,7 @@ import (
"github.com/distribution/distribution/v3"
"github.com/distribution/distribution/v3/registry/storage/cache"
"github.com/opencontainers/go-digest"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
)
// CheckBlobDescriptorCache takes a cache implementation through a common set
@@ -36,7 +37,7 @@ func checkBlobDescriptorCacheEmptyRepository(ctx context.Context, t *testing.T,
t.Fatalf("unexpected error getting repository: %v", err)
}
if err := cache.SetDescriptor(ctx, "", distribution.Descriptor{
if err := cache.SetDescriptor(ctx, "", v1.Descriptor{
Digest: "sha384:abc",
Size: 10,
MediaType: "application/octet-stream",
@@ -44,7 +45,7 @@ func checkBlobDescriptorCacheEmptyRepository(ctx context.Context, t *testing.T,
t.Fatalf("expected error with invalid digest: %v", err)
}
if err := cache.SetDescriptor(ctx, "sha384:abc111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", distribution.Descriptor{
if err := cache.SetDescriptor(ctx, "sha384:abc111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", v1.Descriptor{
Digest: "",
Size: 10,
MediaType: "application/octet-stream",
@@ -67,7 +68,7 @@ func checkBlobDescriptorCacheEmptyRepository(ctx context.Context, t *testing.T,
func checkBlobDescriptorCacheSetAndRead(ctx context.Context, t *testing.T, provider cache.BlobDescriptorCacheProvider) {
localDigest := digest.Digest("sha384:abc111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111")
expected := distribution.Descriptor{
expected := v1.Descriptor{
Digest: "sha256:abc1111111111111111111111111111111111111111111111111111111111111",
Size: 10,
MediaType: "application/octet-stream",
@@ -152,7 +153,7 @@ func checkBlobDescriptorCacheSetAndRead(ctx context.Context, t *testing.T, provi
func checkBlobDescriptorCacheClear(ctx context.Context, t *testing.T, provider cache.BlobDescriptorCacheProvider) {
localDigest := digest.Digest("sha384:def111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111")
expected := distribution.Descriptor{
expected := v1.Descriptor{
Digest: "sha256:def1111111111111111111111111111111111111111111111111111111111111",
Size: 10,
MediaType: "application/octet-stream",

View File

@@ -7,6 +7,7 @@ import (
"github.com/distribution/distribution/v3/internal/dcontext"
prometheus "github.com/distribution/distribution/v3/metrics"
"github.com/opencontainers/go-digest"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
)
type cachedBlobStatter struct {
@@ -32,7 +33,7 @@ func NewCachedBlobStatter(cache distribution.BlobDescriptorService, backend dist
}
}
func (cbds *cachedBlobStatter) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) {
func (cbds *cachedBlobStatter) Stat(ctx context.Context, dgst digest.Digest) (v1.Descriptor, error) {
cacheRequestCount.Inc(1)
// try getting from cache
@@ -75,7 +76,7 @@ func (cbds *cachedBlobStatter) Clear(ctx context.Context, dgst digest.Digest) er
return nil
}
func (cbds *cachedBlobStatter) SetDescriptor(ctx context.Context, dgst digest.Digest, desc distribution.Descriptor) error {
func (cbds *cachedBlobStatter) SetDescriptor(ctx context.Context, dgst digest.Digest, desc v1.Descriptor) error {
if err := cbds.cache.SetDescriptor(ctx, dgst, desc); err != nil {
dcontext.GetLoggerWithField(ctx, "blob", dgst).WithError(err).Error("error from cache setting desc")
}

View File

@@ -9,6 +9,7 @@ import (
"github.com/distribution/reference"
"github.com/hashicorp/golang-lru/arc/v2"
"github.com/opencontainers/go-digest"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
)
const (
@@ -26,7 +27,7 @@ type descriptorCacheKey struct {
}
type inMemoryBlobDescriptorCacheProvider struct {
lru *arc.ARCCache[descriptorCacheKey, distribution.Descriptor]
lru *arc.ARCCache[descriptorCacheKey, v1.Descriptor]
}
// NewInMemoryBlobDescriptorCacheProvider returns a new mapped-based cache for
@@ -35,7 +36,7 @@ func NewInMemoryBlobDescriptorCacheProvider(size int) cache.BlobDescriptorCacheP
if size <= 0 {
size = math.MaxInt
}
lruCache, err := arc.NewARC[descriptorCacheKey, distribution.Descriptor](size)
lruCache, err := arc.NewARC[descriptorCacheKey, v1.Descriptor](size)
if err != nil {
// NewARC can only fail if size is <= 0, so this unreachable
panic(err)
@@ -62,9 +63,9 @@ func (imbdcp *inMemoryBlobDescriptorCacheProvider) RepositoryScoped(repo string)
}, nil
}
func (imbdcp *inMemoryBlobDescriptorCacheProvider) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) {
func (imbdcp *inMemoryBlobDescriptorCacheProvider) Stat(ctx context.Context, dgst digest.Digest) (v1.Descriptor, error) {
if err := dgst.Validate(); err != nil {
return distribution.Descriptor{}, err
return v1.Descriptor{}, err
}
key := descriptorCacheKey{
@@ -74,7 +75,7 @@ func (imbdcp *inMemoryBlobDescriptorCacheProvider) Stat(ctx context.Context, dgs
if ok {
return descriptor, nil
}
return distribution.Descriptor{}, distribution.ErrBlobUnknown
return v1.Descriptor{}, distribution.ErrBlobUnknown
}
func (imbdcp *inMemoryBlobDescriptorCacheProvider) Clear(ctx context.Context, dgst digest.Digest) error {
@@ -85,7 +86,7 @@ func (imbdcp *inMemoryBlobDescriptorCacheProvider) Clear(ctx context.Context, dg
return nil
}
func (imbdcp *inMemoryBlobDescriptorCacheProvider) SetDescriptor(ctx context.Context, dgst digest.Digest, desc distribution.Descriptor) error {
func (imbdcp *inMemoryBlobDescriptorCacheProvider) SetDescriptor(ctx context.Context, dgst digest.Digest, desc v1.Descriptor) error {
_, err := imbdcp.Stat(ctx, dgst)
if err == distribution.ErrBlobUnknown {
if dgst.Algorithm() != desc.Digest.Algorithm() && dgst != desc.Digest {
@@ -121,9 +122,9 @@ type repositoryScopedInMemoryBlobDescriptorCache struct {
parent *inMemoryBlobDescriptorCacheProvider // allows lazy allocation of repo's map
}
func (rsimbdcp *repositoryScopedInMemoryBlobDescriptorCache) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) {
func (rsimbdcp *repositoryScopedInMemoryBlobDescriptorCache) Stat(ctx context.Context, dgst digest.Digest) (v1.Descriptor, error) {
if err := dgst.Validate(); err != nil {
return distribution.Descriptor{}, err
return v1.Descriptor{}, err
}
key := descriptorCacheKey{
@@ -134,7 +135,7 @@ func (rsimbdcp *repositoryScopedInMemoryBlobDescriptorCache) Stat(ctx context.Co
if ok {
return descriptor, nil
}
return distribution.Descriptor{}, distribution.ErrBlobUnknown
return v1.Descriptor{}, distribution.ErrBlobUnknown
}
func (rsimbdcp *repositoryScopedInMemoryBlobDescriptorCache) Clear(ctx context.Context, dgst digest.Digest) error {
@@ -146,7 +147,7 @@ func (rsimbdcp *repositoryScopedInMemoryBlobDescriptorCache) Clear(ctx context.C
return nil
}
func (rsimbdcp *repositoryScopedInMemoryBlobDescriptorCache) SetDescriptor(ctx context.Context, dgst digest.Digest, desc distribution.Descriptor) error {
func (rsimbdcp *repositoryScopedInMemoryBlobDescriptorCache) SetDescriptor(ctx context.Context, dgst digest.Digest, desc v1.Descriptor) error {
if err := dgst.Validate(); err != nil {
return err
}

View File

@@ -9,6 +9,7 @@ import (
"github.com/distribution/distribution/v3/registry/storage/cache"
"github.com/docker/go-metrics"
"github.com/opencontainers/go-digest"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
)
type prometheusCacheProvider struct {
@@ -24,14 +25,14 @@ func NewPrometheusCacheProvider(wrap cache.BlobDescriptorCacheProvider, name, he
}
}
func (p *prometheusCacheProvider) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) {
func (p *prometheusCacheProvider) Stat(ctx context.Context, dgst digest.Digest) (v1.Descriptor, error) {
start := time.Now()
d, e := p.BlobDescriptorCacheProvider.Stat(ctx, dgst)
p.latencyTimer.WithValues("Stat").UpdateSince(start)
return d, e
}
func (p *prometheusCacheProvider) SetDescriptor(ctx context.Context, dgst digest.Digest, desc distribution.Descriptor) error {
func (p *prometheusCacheProvider) SetDescriptor(ctx context.Context, dgst digest.Digest, desc v1.Descriptor) error {
start := time.Now()
e := p.BlobDescriptorCacheProvider.SetDescriptor(ctx, dgst, desc)
p.latencyTimer.WithValues("SetDescriptor").UpdateSince(start)
@@ -43,14 +44,14 @@ type prometheusRepoCacheProvider struct {
latencyTimer metrics.LabeledTimer
}
func (p *prometheusRepoCacheProvider) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) {
func (p *prometheusRepoCacheProvider) Stat(ctx context.Context, dgst digest.Digest) (v1.Descriptor, error) {
start := time.Now()
d, e := p.BlobDescriptorService.Stat(ctx, dgst)
p.latencyTimer.WithValues("RepoStat").UpdateSince(start)
return d, e
}
func (p *prometheusRepoCacheProvider) SetDescriptor(ctx context.Context, dgst digest.Digest, desc distribution.Descriptor) error {
func (p *prometheusRepoCacheProvider) SetDescriptor(ctx context.Context, dgst digest.Digest, desc v1.Descriptor) error {
start := time.Now()
e := p.BlobDescriptorService.SetDescriptor(ctx, dgst, desc)
p.latencyTimer.WithValues("RepoSetDescriptor").UpdateSince(start)

View File

@@ -10,6 +10,7 @@ import (
"github.com/distribution/distribution/v3/registry/storage/cache/metrics"
"github.com/distribution/reference"
"github.com/opencontainers/go-digest"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/redis/go-redis/v9"
)
@@ -66,9 +67,9 @@ func (rbds *redisBlobDescriptorService) RepositoryScoped(repo string) (distribut
}
// Stat retrieves the descriptor data from the redis hash entry.
func (rbds *redisBlobDescriptorService) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) {
func (rbds *redisBlobDescriptorService) Stat(ctx context.Context, dgst digest.Digest) (v1.Descriptor, error) {
if err := dgst.Validate(); err != nil {
return distribution.Descriptor{}, err
return v1.Descriptor{}, err
}
return rbds.stat(ctx, dgst)
@@ -91,33 +92,33 @@ func (rbds *redisBlobDescriptorService) Clear(ctx context.Context, dgst digest.D
return nil
}
func (rbds *redisBlobDescriptorService) stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) {
func (rbds *redisBlobDescriptorService) stat(ctx context.Context, dgst digest.Digest) (v1.Descriptor, error) {
cmd := rbds.pool.HMGet(ctx, rbds.blobDescriptorHashKey(dgst), "digest", "size", "mediatype")
reply, err := cmd.Result()
if err != nil {
return distribution.Descriptor{}, err
return v1.Descriptor{}, err
}
// NOTE(stevvooe): The "size" field used to be "length". We treat a
// missing "size" field here as an unknown blob, which causes a cache
// miss, effectively migrating the field.
if len(reply) < 3 || reply[0] == nil || reply[1] == nil { // don't care if mediatype is nil
return distribution.Descriptor{}, distribution.ErrBlobUnknown
return v1.Descriptor{}, distribution.ErrBlobUnknown
}
var desc distribution.Descriptor
var desc v1.Descriptor
digestString, ok := reply[0].(string)
if !ok {
return distribution.Descriptor{}, fmt.Errorf("digest is not a string")
return v1.Descriptor{}, fmt.Errorf("digest is not a string")
}
desc.Digest = digest.Digest(digestString)
sizeString, ok := reply[1].(string)
if !ok {
return distribution.Descriptor{}, fmt.Errorf("size is not a string")
return v1.Descriptor{}, fmt.Errorf("size is not a string")
}
size, err := strconv.ParseInt(sizeString, 10, 64)
if err != nil {
return distribution.Descriptor{}, err
return v1.Descriptor{}, err
}
desc.Size = size
if reply[2] != nil {
@@ -132,7 +133,7 @@ func (rbds *redisBlobDescriptorService) stat(ctx context.Context, dgst digest.Di
// SetDescriptor sets the descriptor data for the given digest using a redis
// hash. A hash is used here since we may store unrelated fields about a layer
// in the future.
func (rbds *redisBlobDescriptorService) SetDescriptor(ctx context.Context, dgst digest.Digest, desc distribution.Descriptor) error {
func (rbds *redisBlobDescriptorService) SetDescriptor(ctx context.Context, dgst digest.Digest, desc v1.Descriptor) error {
if err := dgst.Validate(); err != nil {
return err
}
@@ -144,7 +145,7 @@ func (rbds *redisBlobDescriptorService) SetDescriptor(ctx context.Context, dgst
return rbds.setDescriptor(ctx, dgst, desc)
}
func (rbds *redisBlobDescriptorService) setDescriptor(ctx context.Context, dgst digest.Digest, desc distribution.Descriptor) error {
func (rbds *redisBlobDescriptorService) setDescriptor(ctx context.Context, dgst digest.Digest, desc v1.Descriptor) error {
cmd := rbds.pool.HMSet(ctx, rbds.blobDescriptorHashKey(dgst), "digest", desc.Digest.String(), "size", desc.Size)
if cmd.Err() != nil {
return cmd.Err()
@@ -171,33 +172,33 @@ var _ distribution.BlobDescriptorService = &repositoryScopedRedisBlobDescriptorS
// Stat ensures that the digest is a member of the specified repository and
// forwards the descriptor request to the global blob store. If the media type
// differs for the repository, we override it.
func (rsrbds *repositoryScopedRedisBlobDescriptorService) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) {
func (rsrbds *repositoryScopedRedisBlobDescriptorService) Stat(ctx context.Context, dgst digest.Digest) (v1.Descriptor, error) {
if err := dgst.Validate(); err != nil {
return distribution.Descriptor{}, err
return v1.Descriptor{}, err
}
pool := rsrbds.upstream.pool
// Check membership to repository first
member, err := pool.SIsMember(ctx, rsrbds.repositoryBlobSetKey(rsrbds.repo), dgst.String()).Result()
if err != nil {
return distribution.Descriptor{}, err
return v1.Descriptor{}, err
}
if !member {
return distribution.Descriptor{}, distribution.ErrBlobUnknown
return v1.Descriptor{}, distribution.ErrBlobUnknown
}
upstream, err := rsrbds.upstream.stat(ctx, dgst)
if err != nil {
return distribution.Descriptor{}, err
return v1.Descriptor{}, err
}
// We allow a per repository mediatype, let's look it up here.
mediatype, err := pool.HGet(ctx, rsrbds.blobDescriptorHashKey(dgst), "mediatype").Result()
if err != nil {
if err == redis.Nil {
return distribution.Descriptor{}, distribution.ErrBlobUnknown
return v1.Descriptor{}, distribution.ErrBlobUnknown
}
return distribution.Descriptor{}, err
return v1.Descriptor{}, err
}
if mediatype != "" {
@@ -225,7 +226,7 @@ func (rsrbds *repositoryScopedRedisBlobDescriptorService) Clear(ctx context.Cont
return rsrbds.upstream.Clear(ctx, dgst)
}
func (rsrbds *repositoryScopedRedisBlobDescriptorService) SetDescriptor(ctx context.Context, dgst digest.Digest, desc distribution.Descriptor) error {
func (rsrbds *repositoryScopedRedisBlobDescriptorService) SetDescriptor(ctx context.Context, dgst digest.Digest, desc v1.Descriptor) error {
if err := dgst.Validate(); err != nil {
return err
}
@@ -243,7 +244,7 @@ func (rsrbds *repositoryScopedRedisBlobDescriptorService) SetDescriptor(ctx cont
return rsrbds.setDescriptor(ctx, dgst, desc)
}
func (rsrbds *repositoryScopedRedisBlobDescriptorService) setDescriptor(ctx context.Context, dgst digest.Digest, desc distribution.Descriptor) error {
func (rsrbds *repositoryScopedRedisBlobDescriptorService) setDescriptor(ctx context.Context, dgst digest.Digest, desc v1.Descriptor) error {
conn := rsrbds.upstream.pool
_, err := conn.SAdd(ctx, rsrbds.repositoryBlobSetKey(rsrbds.repo), dgst.String()).Result()
if err != nil {

View File

@@ -9,6 +9,7 @@ import (
"github.com/distribution/distribution/v3/registry/storage/driver"
"github.com/distribution/reference"
"github.com/opencontainers/go-digest"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
)
func emit(format string, a ...interface{}) {
@@ -65,7 +66,7 @@ func MarkAndSweep(ctx context.Context, storageDriver driver.StorageDriver, regis
err = manifestEnumerator.Enumerate(ctx, func(dgst digest.Digest) error {
if opts.RemoveUntagged {
// fetch all tags where this manifest is the latest one
tags, err := repository.Tags(ctx).Lookup(ctx, distribution.Descriptor{Digest: dgst})
tags, err := repository.Tags(ctx).Lookup(ctx, v1.Descriptor{Digest: dgst})
if err != nil {
return fmt.Errorf("failed to retrieve tags for digest %v: %v", dgst, err)
}

View File

@@ -14,6 +14,7 @@ import (
"github.com/distribution/distribution/v3/testutil"
"github.com/distribution/reference"
"github.com/opencontainers/go-digest"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
)
type image struct {
@@ -250,7 +251,7 @@ func TestDeleteManifestIfTagNotFound(t *testing.T) {
manifestEnumerator, _ := manifestService.(distribution.ManifestEnumerator)
err = manifestEnumerator.Enumerate(ctx, func(dgst digest.Digest) error {
return repo.Tags(ctx).Tag(ctx, "test", distribution.Descriptor{Digest: dgst})
return repo.Tags(ctx).Tag(ctx, "test", v1.Descriptor{Digest: dgst})
})
if err != nil {
t.Fatalf("manifest enumeration failed: %v", err)
@@ -306,7 +307,7 @@ func TestDeleteManifestIndexWithDanglingReferences(t *testing.T) {
image1 := uploadRandomOCIImage(t, repo)
image2 := uploadRandomOCIImage(t, repo)
ii, _ := ocischema.FromDescriptors([]distribution.Descriptor{
ii, _ := ocischema.FromDescriptors([]v1.Descriptor{
{Digest: image1.manifestDigest}, {Digest: image2.manifestDigest},
}, map[string]string{})
@@ -315,7 +316,7 @@ func TestDeleteManifestIndexWithDanglingReferences(t *testing.T) {
t.Fatalf("manifest upload failed: %v", err)
}
err = repo.Tags(ctx).Tag(ctx, "test", distribution.Descriptor{Digest: id})
err = repo.Tags(ctx).Tag(ctx, "test", v1.Descriptor{Digest: id})
if err != nil {
t.Fatalf("Failed to delete tag: %v", err)
}
@@ -359,7 +360,7 @@ func TestDeleteManifestIndexIfTagNotFound(t *testing.T) {
image1 := uploadRandomOCIImage(t, repo)
image2 := uploadRandomOCIImage(t, repo)
ii, _ := ocischema.FromDescriptors([]distribution.Descriptor{
ii, _ := ocischema.FromDescriptors([]v1.Descriptor{
{Digest: image1.manifestDigest}, {Digest: image2.manifestDigest},
}, map[string]string{})
@@ -368,7 +369,7 @@ func TestDeleteManifestIndexIfTagNotFound(t *testing.T) {
t.Fatalf("manifest upload failed: %v", err)
}
err = repo.Tags(ctx).Tag(ctx, "test", distribution.Descriptor{Digest: d4})
err = repo.Tags(ctx).Tag(ctx, "test", v1.Descriptor{Digest: d4})
if err != nil {
t.Fatalf("Failed to delete tag: %v", err)
}
@@ -466,7 +467,7 @@ func TestGCWithUnknownRepository(t *testing.T) {
repo := makeRepository(t, registry, "nonexistentrepo")
image := uploadRandomSchema2Image(t, repo)
err := repo.Tags(ctx).Tag(ctx, "image", distribution.Descriptor{Digest: image.manifestDigest})
err := repo.Tags(ctx).Tag(ctx, "image", v1.Descriptor{Digest: image.manifestDigest})
if err != nil {
t.Fatalf("Failed to tag descriptor: %v", err)
}
@@ -729,7 +730,7 @@ func TestTaggedManifestlistWithUntaggedManifest(t *testing.T) {
t.Fatalf("Failed to add manifest list: %v", err)
}
err = repo.Tags(ctx).Tag(ctx, "test", distribution.Descriptor{Digest: dgst})
err = repo.Tags(ctx).Tag(ctx, "test", v1.Descriptor{Digest: dgst})
if err != nil {
t.Fatalf("Failed to delete tag: %v", err)
}
@@ -821,12 +822,12 @@ func TestUnTaggedManifestlistWithTaggedManifest(t *testing.T) {
image1 := uploadRandomSchema2Image(t, repo)
image2 := uploadRandomSchema2Image(t, repo)
err = repo.Tags(ctx).Tag(ctx, "image1", distribution.Descriptor{Digest: image1.manifestDigest})
err = repo.Tags(ctx).Tag(ctx, "image1", v1.Descriptor{Digest: image1.manifestDigest})
if err != nil {
t.Fatalf("Failed to delete tag: %v", err)
}
err = repo.Tags(ctx).Tag(ctx, "image2", distribution.Descriptor{Digest: image2.manifestDigest})
err = repo.Tags(ctx).Tag(ctx, "image2", v1.Descriptor{Digest: image2.manifestDigest})
if err != nil {
t.Fatalf("Failed to delete tag: %v", err)
}

View File

@@ -14,6 +14,7 @@ import (
"github.com/distribution/reference"
"github.com/google/uuid"
"github.com/opencontainers/go-digest"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
)
// linkPathFunc describes a function that can resolve a link based on the
@@ -45,7 +46,7 @@ type linkedBlobStore struct {
var _ distribution.BlobStore = &linkedBlobStore{}
func (lbs *linkedBlobStore) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) {
func (lbs *linkedBlobStore) Stat(ctx context.Context, dgst digest.Digest) (v1.Descriptor, error) {
return lbs.blobAccessController.Stat(ctx, dgst)
}
@@ -81,17 +82,17 @@ func (lbs *linkedBlobStore) ServeBlob(ctx context.Context, w http.ResponseWriter
return lbs.blobServer.ServeBlob(ctx, w, r, canonical.Digest)
}
func (lbs *linkedBlobStore) Put(ctx context.Context, mediaType string, p []byte) (distribution.Descriptor, error) {
func (lbs *linkedBlobStore) Put(ctx context.Context, mediaType string, p []byte) (v1.Descriptor, error) {
dgst := digest.FromBytes(p)
// Place the data in the blob store first.
desc, err := lbs.blobStore.Put(ctx, mediaType, p)
if err != nil {
dcontext.GetLogger(ctx).Errorf("error putting into main store: %v", err)
return distribution.Descriptor{}, err
return v1.Descriptor{}, err
}
if err := lbs.blobAccessController.SetDescriptor(ctx, dgst, desc); err != nil {
return distribution.Descriptor{}, err
return v1.Descriptor{}, err
}
// TODO(stevvooe): Write out mediatype if incoming differs from what is
@@ -270,24 +271,24 @@ func (lbs *linkedBlobStore) Enumerate(ctx context.Context, ingestor func(digest.
})
}
func (lbs *linkedBlobStore) mount(ctx context.Context, sourceRepo reference.Named, dgst digest.Digest, sourceStat *distribution.Descriptor) (distribution.Descriptor, error) {
var stat distribution.Descriptor
func (lbs *linkedBlobStore) mount(ctx context.Context, sourceRepo reference.Named, dgst digest.Digest, sourceStat *v1.Descriptor) (v1.Descriptor, error) {
var stat v1.Descriptor
if sourceStat == nil {
// look up the blob info from the sourceRepo if not already provided
repo, err := lbs.registry.Repository(ctx, sourceRepo)
if err != nil {
return distribution.Descriptor{}, err
return v1.Descriptor{}, err
}
stat, err = repo.Blobs(ctx).Stat(ctx, dgst)
if err != nil {
return distribution.Descriptor{}, err
return v1.Descriptor{}, err
}
} else {
// use the provided blob info
stat = *sourceStat
}
desc := distribution.Descriptor{
desc := v1.Descriptor{
Size: stat.Size,
// NOTE(stevvooe): The central blob store firewalls media types from
@@ -323,7 +324,7 @@ func (lbs *linkedBlobStore) newBlobUpload(ctx context.Context, uuid, path string
// linkBlob links a valid, written blob into the registry under the named
// repository for the upload controller.
func (lbs *linkedBlobStore) linkBlob(ctx context.Context, canonical distribution.Descriptor, aliases ...digest.Digest) error {
func (lbs *linkedBlobStore) linkBlob(ctx context.Context, canonical v1.Descriptor, aliases ...digest.Digest) error {
dgsts := append([]digest.Digest{canonical.Digest}, aliases...)
// TODO(stevvooe): Need to write out mediatype for only canonical hash
@@ -365,19 +366,19 @@ type linkedBlobStatter struct {
var _ distribution.BlobDescriptorService = &linkedBlobStatter{}
func (lbs *linkedBlobStatter) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) {
func (lbs *linkedBlobStatter) Stat(ctx context.Context, dgst digest.Digest) (v1.Descriptor, error) {
blobLinkPath, err := lbs.linkPath(lbs.repository.Named().Name(), dgst)
if err != nil {
return distribution.Descriptor{}, err
return v1.Descriptor{}, err
}
target, err := lbs.blobStore.readlink(ctx, blobLinkPath)
if err != nil {
switch err := err.(type) {
case driver.PathNotFoundError:
return distribution.Descriptor{}, distribution.ErrBlobUnknown
return v1.Descriptor{}, distribution.ErrBlobUnknown
default:
return distribution.Descriptor{}, err
return v1.Descriptor{}, err
}
}
@@ -401,7 +402,7 @@ func (lbs *linkedBlobStatter) Clear(ctx context.Context, dgst digest.Digest) (er
return lbs.blobStore.driver.Delete(ctx, blobLinkPath)
}
func (lbs *linkedBlobStatter) SetDescriptor(ctx context.Context, dgst digest.Digest, desc distribution.Descriptor) error {
func (lbs *linkedBlobStatter) SetDescriptor(ctx context.Context, dgst digest.Digest, desc v1.Descriptor) error {
// The canonical descriptor for a blob is set at the commit phase of upload
return nil
}

View File

@@ -13,6 +13,7 @@ import (
"github.com/distribution/distribution/v3/testutil"
"github.com/distribution/reference"
"github.com/opencontainers/go-digest"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
)
func TestLinkedBlobStoreEnumerator(t *testing.T) {
@@ -38,7 +39,7 @@ func TestLinkedBlobStoreEnumerator(t *testing.T) {
t.Fatalf("unexpected error copying to upload: %v", err)
}
if _, err := wr.Commit(fooEnv.ctx, distribution.Descriptor{Digest: dgst}); err != nil {
if _, err := wr.Commit(fooEnv.ctx, v1.Descriptor{Digest: dgst}); err != nil {
t.Fatalf("unexpected error finishing upload: %v", err)
}
}
@@ -95,7 +96,7 @@ func TestLinkedBlobStoreCreateWithMountFrom(t *testing.T) {
t.Fatalf("unexpected error copying to upload: %v", err)
}
if _, err := wr.Commit(fooEnv.ctx, distribution.Descriptor{Digest: dgst}); err != nil {
if _, err := wr.Commit(fooEnv.ctx, v1.Descriptor{Digest: dgst}); err != nil {
t.Fatalf("unexpected error finishing upload: %v", err)
}
}
@@ -154,7 +155,7 @@ func TestLinkedBlobStoreCreateWithMountFrom(t *testing.T) {
if err != nil {
t.Fatal(err)
}
prepolutatedDescriptor := distribution.Descriptor{
prepolutatedDescriptor := v1.Descriptor{
Digest: dgst,
Size: size,
MediaType: "application/octet-stream",
@@ -223,16 +224,16 @@ type mockBlobDescriptorService struct {
var _ distribution.BlobDescriptorService = &mockBlobDescriptorService{}
func (bs *mockBlobDescriptorService) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) {
func (bs *mockBlobDescriptorService) Stat(ctx context.Context, dgst digest.Digest) (v1.Descriptor, error) {
statter, ok := bs.BlobDescriptorService.(*linkedBlobStatter)
if !ok {
return distribution.Descriptor{}, fmt.Errorf("unexpected blob descriptor service: %T", bs.BlobDescriptorService)
return v1.Descriptor{}, fmt.Errorf("unexpected blob descriptor service: %T", bs.BlobDescriptorService)
}
name := statter.repository.Named()
canonical, err := reference.WithDigest(name, dgst)
if err != nil {
return distribution.Descriptor{}, fmt.Errorf("failed to make canonical reference: %v", err)
return v1.Descriptor{}, fmt.Errorf("failed to make canonical reference: %v", err)
}
bs.stats[canonical.String()]++
@@ -243,7 +244,7 @@ func (bs *mockBlobDescriptorService) Stat(ctx context.Context, dgst digest.Diges
// statCrossMountCreateOptions ensures the expected options type is passed, and optionally pre-fills the cross-mount stat info
type statCrossMountCreateOption struct {
desc distribution.Descriptor
desc v1.Descriptor
}
var _ distribution.BlobCreateOption = statCrossMountCreateOption{}

View File

@@ -9,6 +9,7 @@ import (
"github.com/distribution/distribution/v3/manifest/manifestlist"
"github.com/distribution/distribution/v3/manifest/ocischema"
"github.com/opencontainers/go-digest"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
)
// manifestListHandler is a ManifestHandler that covers schema2 manifest lists.
@@ -104,7 +105,7 @@ func (ms *manifestListHandler) verifyManifest(ctx context.Context, mnfst distrib
}
// platformMustExist checks if a descriptor within an index should be validated as existing before accepting the manifest into the registry.
func (ms *manifestListHandler) platformMustExist(descriptor distribution.Descriptor) bool {
func (ms *manifestListHandler) platformMustExist(descriptor v1.Descriptor) bool {
// If there are no image platforms configured to validate, we must check the existence of all child images.
if len(ms.validateImageIndexes.imagePlatforms) == 0 {
return true

View File

@@ -96,12 +96,12 @@ func testManifestStorage(t *testing.T, options ...RegistryOption) {
m := &schema2.Manifest{
Versioned: specs.Versioned{SchemaVersion: 2},
MediaType: schema2.MediaTypeManifest,
Config: distribution.Descriptor{
Config: v1.Descriptor{
Digest: digest.FromBytes(sampleConfig),
Size: int64(len(sampleConfig)),
MediaType: schema2.MediaTypeImageConfig,
},
Layers: []distribution.Descriptor{},
Layers: []v1.Descriptor{},
}
// Build up some test layers and add them to the manifest, saving the
@@ -114,7 +114,7 @@ func testManifestStorage(t *testing.T, options ...RegistryOption) {
}
testLayers[dgst] = rs
layer := distribution.Descriptor{
layer := v1.Descriptor{
Digest: dgst,
Size: 6323,
MediaType: schema2.MediaTypeLayer,
@@ -133,10 +133,10 @@ func testManifestStorage(t *testing.T, options ...RegistryOption) {
t.Fatalf("unexpected error copying to upload: %v", err)
}
if _, err := wr.Commit(env.ctx, distribution.Descriptor{Digest: dgst}); err != nil {
if _, err := wr.Commit(env.ctx, v1.Descriptor{Digest: dgst}); err != nil {
t.Fatalf("unexpected error finishing upload: %v", err)
}
if err := builder.AppendReference(distribution.Descriptor{Digest: dgst, MediaType: schema2.MediaTypeLayer}); err != nil {
if err := builder.AppendReference(v1.Descriptor{Digest: dgst, MediaType: schema2.MediaTypeLayer}); err != nil {
t.Fatalf("unexpected error appending references: %v", err)
}
}
@@ -336,7 +336,7 @@ func testOCIManifestStorage(t *testing.T, testname string, includeMediaTypes boo
OS: "CP/M",
}
mfstDescriptors := []distribution.Descriptor{
mfstDescriptors := []v1.Descriptor{
createOciManifestDescriptor(t, testname, mfst, platformSpec),
}
@@ -460,7 +460,7 @@ func TestIndexManifestStorageWithoutImageCheck(t *testing.T) {
OS: "CP/M",
}
ociManifestDescriptors := []distribution.Descriptor{
ociManifestDescriptors := []v1.Descriptor{
createOciManifestDescriptor(t, t.Name(), manifest, ociPlatformSpec),
}
@@ -547,7 +547,7 @@ func TestIndexManifestStorageWithSelectivePlatforms(t *testing.T) {
OS: "CP/M",
}
manifestDescriptors := []distribution.Descriptor{
manifestDescriptors := []v1.Descriptor{
createOciManifestDescriptor(t, t.Name(), amdManifest, amdPlatformSpec),
createOciManifestDescriptor(t, t.Name(), armManifest, armPlatformSpec),
createOciManifestDescriptor(t, t.Name(), atariManifest, atariPlatformSpec),
@@ -616,11 +616,11 @@ func createRandomImage(t *testing.T, testname string, imageMediaType string, blo
t.Fatalf("%s: unexpected error copying to upload: %v", testname, err)
}
if _, err := wr.Commit(ctx, distribution.Descriptor{Digest: dgst}); err != nil {
if _, err := wr.Commit(ctx, v1.Descriptor{Digest: dgst}); err != nil {
t.Fatalf("%s: unexpected error finishing upload: %v", testname, err)
}
if err := builder.AppendReference(distribution.Descriptor{Digest: dgst, MediaType: v1.MediaTypeImageLayer}); err != nil {
if err := builder.AppendReference(v1.Descriptor{Digest: dgst, MediaType: v1.MediaTypeImageLayer}); err != nil {
t.Fatalf("%s unexpected error appending references: %v", testname, err)
}
}
@@ -629,14 +629,14 @@ func createRandomImage(t *testing.T, testname string, imageMediaType string, blo
}
// createOciManifestDescriptor builds a manifest descriptor from a manifest and a platform descriptor
func createOciManifestDescriptor(t *testing.T, testname string, manifest distribution.Manifest, platformSpec *v1.Platform) distribution.Descriptor {
func createOciManifestDescriptor(t *testing.T, testname string, manifest distribution.Manifest, platformSpec *v1.Platform) v1.Descriptor {
manifestMediaType, manifestPayload, err := manifest.Payload()
if err != nil {
t.Fatalf("%s: unexpected error getting manifest payload: %v", testname, err)
}
manifestDigest := digest.FromBytes(manifestPayload)
return distribution.Descriptor{
return v1.Descriptor{
Digest: manifestDigest,
Size: int64(len(manifestPayload)),
MediaType: manifestMediaType,
@@ -656,7 +656,7 @@ func createManifestListDescriptor(t *testing.T, testname string, manifest distri
manifestDigest := digest.FromBytes(manifestPayload)
return manifestlist.ManifestDescriptor{
Descriptor: distribution.Descriptor{
Descriptor: v1.Descriptor{
Digest: manifestDigest,
Size: int64(len(manifestPayload)),
MediaType: manifestMediaType,
@@ -701,7 +701,7 @@ func TestLinkPathFuncs(t *testing.T) {
}
}
func ociIndexFromDesriptorsWithMediaType(descriptors []distribution.Descriptor, mediaType string) (*ocischema.DeserializedImageIndex, error) {
func ociIndexFromDesriptorsWithMediaType(descriptors []v1.Descriptor, mediaType string) (*ocischema.DeserializedImageIndex, error) {
manifest, err := ocischema.FromDescriptors(descriptors, nil)
if err != nil {
return nil, err

View File

@@ -33,17 +33,17 @@ func TestVerifyOCIManifestNonDistributableLayer(t *testing.T) {
t.Fatal(err)
}
nonDistributableLayer := distribution.Descriptor{
nonDistributableLayer := v1.Descriptor{
Digest: "sha256:463435349086340864309863409683460843608348608934092322395278926a",
Size: 6323,
MediaType: v1.MediaTypeImageLayerNonDistributableGzip, //nolint:staticcheck // ignore A1019: v1.MediaTypeImageLayerNonDistributableGzip is deprecated: Non-distributable layers are deprecated, and not recommended for future use
}
emptyLayer := distribution.Descriptor{
emptyLayer := v1.Descriptor{
Digest: "",
}
emptyGzipLayer := distribution.Descriptor{
emptyGzipLayer := v1.Descriptor{
Digest: "",
MediaType: v1.MediaTypeImageLayerGzip,
}
@@ -55,7 +55,7 @@ func TestVerifyOCIManifestNonDistributableLayer(t *testing.T) {
}
type testcase struct {
BaseLayer distribution.Descriptor
BaseLayer v1.Descriptor
URLs []string
Err error
}
@@ -142,7 +142,7 @@ func TestVerifyOCIManifestNonDistributableLayer(t *testing.T) {
m := template
l := c.BaseLayer
l.URLs = c.URLs
m.Layers = []distribution.Descriptor{l}
m.Layers = []v1.Descriptor{l}
dm, err := ocischema.FromStruct(m)
if err != nil {
t.Error(err)
@@ -215,7 +215,7 @@ func TestVerifyOCIManifestBlobLayerAndConfig(t *testing.T) {
}
type testcase struct {
Desc distribution.Descriptor
Desc v1.Descriptor
URLs []string
Err error
}
@@ -223,25 +223,25 @@ func TestVerifyOCIManifestBlobLayerAndConfig(t *testing.T) {
layercases := []testcase{
// empty media type
{
distribution.Descriptor{},
v1.Descriptor{},
[]string{"http://foo/bar"},
digest.ErrDigestInvalidFormat,
},
{
distribution.Descriptor{},
v1.Descriptor{},
nil,
digest.ErrDigestInvalidFormat,
},
// unknown media type, but blob is present
{
distribution.Descriptor{
v1.Descriptor{
Digest: layer.Digest,
},
nil,
nil,
},
{
distribution.Descriptor{
v1.Descriptor{
Digest: layer.Digest,
},
[]string{"http://foo/bar"},
@@ -249,21 +249,21 @@ func TestVerifyOCIManifestBlobLayerAndConfig(t *testing.T) {
},
// gzip layer, but invalid digest
{
distribution.Descriptor{
v1.Descriptor{
MediaType: v1.MediaTypeImageLayerGzip,
},
nil,
digest.ErrDigestInvalidFormat,
},
{
distribution.Descriptor{
v1.Descriptor{
MediaType: v1.MediaTypeImageLayerGzip,
},
[]string{"https://foo/bar"},
digest.ErrDigestInvalidFormat,
},
{
distribution.Descriptor{
v1.Descriptor{
MediaType: v1.MediaTypeImageLayerGzip,
Digest: digest.Digest("invalid"),
},
@@ -290,7 +290,7 @@ func TestVerifyOCIManifestBlobLayerAndConfig(t *testing.T) {
l := c.Desc
l.URLs = c.URLs
m.Layers = []distribution.Descriptor{l}
m.Layers = []v1.Descriptor{l}
checkFn(m, c.Err)
}
@@ -304,14 +304,14 @@ func TestVerifyOCIManifestBlobLayerAndConfig(t *testing.T) {
},
// invalid digest
{
distribution.Descriptor{
v1.Descriptor{
MediaType: v1.MediaTypeImageConfig,
},
[]string{"https://foo/bar"},
digest.ErrDigestInvalidFormat,
},
{
distribution.Descriptor{
v1.Descriptor{
MediaType: v1.MediaTypeImageConfig,
Digest: digest.Digest("invalid"),
},

View File

@@ -11,6 +11,7 @@ import (
"github.com/distribution/distribution/v3/registry/storage/driver/inmemory"
"github.com/opencontainers/go-digest"
"github.com/opencontainers/image-spec/specs-go"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
)
func TestVerifyManifestForeignLayer(t *testing.T) {
@@ -34,13 +35,13 @@ func TestVerifyManifestForeignLayer(t *testing.T) {
t.Fatal(err)
}
foreignLayer := distribution.Descriptor{
foreignLayer := v1.Descriptor{
Digest: "sha256:463435349086340864309863409683460843608348608934092322395278926a",
Size: 6323,
MediaType: schema2.MediaTypeForeignLayer,
}
emptyLayer := distribution.Descriptor{
emptyLayer := v1.Descriptor{
Digest: "",
}
@@ -51,7 +52,7 @@ func TestVerifyManifestForeignLayer(t *testing.T) {
}
type testcase struct {
BaseLayer distribution.Descriptor
BaseLayer v1.Descriptor
URLs []string
Err error
}
@@ -129,7 +130,7 @@ func TestVerifyManifestForeignLayer(t *testing.T) {
m := template
l := c.BaseLayer
l.URLs = c.URLs
m.Layers = []distribution.Descriptor{l}
m.Layers = []v1.Descriptor{l}
dm, err := schema2.FromStruct(m)
if err != nil {
t.Error(err)
@@ -202,7 +203,7 @@ func TestVerifyManifestBlobLayerAndConfig(t *testing.T) {
}
type testcase struct {
Desc distribution.Descriptor
Desc v1.Descriptor
URLs []string
Err error
}
@@ -210,25 +211,25 @@ func TestVerifyManifestBlobLayerAndConfig(t *testing.T) {
layercases := []testcase{
// empty media type
{
distribution.Descriptor{},
v1.Descriptor{},
[]string{"http://foo/bar"},
digest.ErrDigestInvalidFormat,
},
{
distribution.Descriptor{},
v1.Descriptor{},
nil,
digest.ErrDigestInvalidFormat,
},
// unknown media type, but blob is present
{
distribution.Descriptor{
v1.Descriptor{
Digest: layer.Digest,
},
nil,
nil,
},
{
distribution.Descriptor{
v1.Descriptor{
Digest: layer.Digest,
},
[]string{"http://foo/bar"},
@@ -236,21 +237,21 @@ func TestVerifyManifestBlobLayerAndConfig(t *testing.T) {
},
// gzip layer, but invalid digest
{
distribution.Descriptor{
v1.Descriptor{
MediaType: schema2.MediaTypeLayer,
},
nil,
digest.ErrDigestInvalidFormat,
},
{
distribution.Descriptor{
v1.Descriptor{
MediaType: schema2.MediaTypeLayer,
},
[]string{"https://foo/bar"},
digest.ErrDigestInvalidFormat,
},
{
distribution.Descriptor{
v1.Descriptor{
MediaType: schema2.MediaTypeLayer,
Digest: digest.Digest("invalid"),
},
@@ -277,7 +278,7 @@ func TestVerifyManifestBlobLayerAndConfig(t *testing.T) {
l := c.Desc
l.URLs = c.URLs
m.Layers = []distribution.Descriptor{l}
m.Layers = []v1.Descriptor{l}
checkFn(m, c.Err)
}
@@ -291,14 +292,14 @@ func TestVerifyManifestBlobLayerAndConfig(t *testing.T) {
},
// invalid digest
{
distribution.Descriptor{
v1.Descriptor{
MediaType: schema2.MediaTypeImageConfig,
},
[]string{"https://foo/bar"},
digest.ErrDigestInvalidFormat,
},
{
distribution.Descriptor{
v1.Descriptor{
MediaType: schema2.MediaTypeImageConfig,
Digest: digest.Digest("invalid"),
},

View File

@@ -7,6 +7,7 @@ import (
"sync"
"github.com/opencontainers/go-digest"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
"golang.org/x/sync/errgroup"
"github.com/distribution/distribution/v3"
@@ -18,7 +19,7 @@ var _ distribution.TagService = &tagStore{}
// tagStore provides methods to manage manifest tags in a backend storage driver.
// This implementation uses the same on-disk layout as the (now deleted) tag
// store. This provides backward compatibility with current registry deployments
// which only makes use of the Digest field of the returned distribution.Descriptor
// which only makes use of the Digest field of the returned v1.Descriptor
// but does not enable full roundtripping of Descriptor objects
type tagStore struct {
repository *repository
@@ -60,7 +61,7 @@ func (ts *tagStore) All(ctx context.Context) ([]string, error) {
// Tag tags the digest with the given tag, updating the store to point at
// the current tag. The digest must point to a manifest.
func (ts *tagStore) Tag(ctx context.Context, tag string, desc distribution.Descriptor) error {
func (ts *tagStore) Tag(ctx context.Context, tag string, desc v1.Descriptor) error {
currentPath, err := pathFor(manifestTagCurrentPathSpec{
name: ts.repository.Named().Name(),
tag: tag,
@@ -81,26 +82,26 @@ func (ts *tagStore) Tag(ctx context.Context, tag string, desc distribution.Descr
}
// resolve the current revision for name and tag.
func (ts *tagStore) Get(ctx context.Context, tag string) (distribution.Descriptor, error) {
func (ts *tagStore) Get(ctx context.Context, tag string) (v1.Descriptor, error) {
currentPath, err := pathFor(manifestTagCurrentPathSpec{
name: ts.repository.Named().Name(),
tag: tag,
})
if err != nil {
return distribution.Descriptor{}, err
return v1.Descriptor{}, err
}
revision, err := ts.blobStore.readlink(ctx, currentPath)
if err != nil {
switch err.(type) {
case storagedriver.PathNotFoundError:
return distribution.Descriptor{}, distribution.ErrTagUnknown{Tag: tag}
return v1.Descriptor{}, distribution.ErrTagUnknown{Tag: tag}
}
return distribution.Descriptor{}, err
return v1.Descriptor{}, err
}
return distribution.Descriptor{Digest: revision}, nil
return v1.Descriptor{Digest: revision}, nil
}
// Untag removes the tag association
@@ -137,7 +138,7 @@ func (ts *tagStore) linkedBlobStore(ctx context.Context, tag string) *linkedBlob
// Lookup recovers a list of tags which refer to this digest. When a manifest is deleted by
// digest, tag entries which point to it need to be recovered to avoid dangling tags.
func (ts *tagStore) Lookup(ctx context.Context, desc distribution.Descriptor) ([]string, error) {
func (ts *tagStore) Lookup(ctx context.Context, desc v1.Descriptor) ([]string, error) {
allTags, err := ts.All(ctx)
switch err.(type) {
case distribution.ErrRepositoryUnknown:

View File

@@ -11,6 +11,7 @@ import (
"github.com/distribution/reference"
digest "github.com/opencontainers/go-digest"
"github.com/opencontainers/image-spec/specs-go"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
)
type tagsTestEnv struct {
@@ -53,7 +54,7 @@ func TestTagStoreTag(t *testing.T) {
tags := env.ts
ctx := env.ctx
d := distribution.Descriptor{}
d := v1.Descriptor{}
err := tags.Tag(ctx, "latest", d)
if err == nil {
t.Errorf("unexpected error putting malformed descriptor : %s", err)
@@ -95,7 +96,7 @@ func TestTagStoreUnTag(t *testing.T) {
env := testTagStore(t)
tags := env.ts
ctx := env.ctx
desc := distribution.Descriptor{Digest: "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"}
desc := v1.Descriptor{Digest: "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"}
err := tags.Untag(ctx, "latest")
if err == nil {
@@ -127,7 +128,7 @@ func TestTagStoreAll(t *testing.T) {
alpha := "abcdefghijklmnopqrstuvwxyz"
for i := 0; i < len(alpha); i++ {
tag := alpha[i]
desc := distribution.Descriptor{Digest: "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"}
desc := v1.Descriptor{Digest: "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"}
err := tagStore.Tag(ctx, string(tag), desc)
if err != nil {
t.Error(err)
@@ -170,8 +171,8 @@ func TestTagLookup(t *testing.T) {
tagStore := env.ts
ctx := env.ctx
descA := distribution.Descriptor{Digest: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}
desc0 := distribution.Descriptor{Digest: "sha256:0000000000000000000000000000000000000000000000000000000000000000"}
descA := v1.Descriptor{Digest: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}
desc0 := v1.Descriptor{Digest: "sha256:0000000000000000000000000000000000000000000000000000000000000000"}
tags, err := tagStore.Lookup(ctx, descA)
if err != nil {
@@ -245,12 +246,12 @@ func TestTagIndexes(t *testing.T) {
m := schema2.Manifest{
Versioned: specs.Versioned{SchemaVersion: 2},
MediaType: schema2.MediaTypeManifest,
Config: distribution.Descriptor{
Config: v1.Descriptor{
Digest: conf.Digest,
Size: 1,
MediaType: schema2.MediaTypeImageConfig,
},
Layers: []distribution.Descriptor{
Layers: []v1.Descriptor{
{
Digest: layer.Digest,
Size: 1,