Skip to content
Open
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
4 changes: 4 additions & 0 deletions manifests.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ type ManifestService interface {
// Delete removes the manifest specified by the given digest. Deleting
// a manifest that doesn't exist will return ErrManifestNotFound
Delete(ctx context.Context, dgst digest.Digest) error

// Stat provides metadata about a manifest identified by the digest. If the
// manifest is unknown to the describer, ErrManifestUnknownRevision will be returned.
Stat(ctx context.Context, dgst digest.Digest) (Descriptor, error)
}

// ManifestEnumerator enables iterating over manifests
Expand Down
3 changes: 3 additions & 0 deletions registry/storage/driver/base/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ func (base *Base) setDriverName(e error) error {
case storagedriver.UserSuspendedError:
actual.DriverName = base.StorageDriver.Name()
return actual
case storagedriver.InvalidAccessKeyIdError:
actual.DriverName = base.StorageDriver.Name()
return actual
default:
storageError := storagedriver.Error{
DriverName: base.StorageDriver.Name(),
Expand Down
4 changes: 3 additions & 1 deletion registry/storage/driver/s3-aws/s3.go
Original file line number Diff line number Diff line change
Expand Up @@ -1207,7 +1207,7 @@ func (d *driver) Walk(ctx context.Context, from string, f storagedriver.WalkFn)

var objectCount int64
if err := d.doWalk(ctx, &objectCount, d.s3Path(path), prefix, f); err != nil {
return err
return parseError(from, err)
}

// S3 doesn't have the concept of empty directories, so it'll return path not found if there are no objects
Expand Down Expand Up @@ -1414,6 +1414,8 @@ func parseError(path string, err error) error {
return storagedriver.QuotaExceededError{}
case "UserSuspended":
return storagedriver.UserSuspendedError{}
case "InvalidAccessKeyId":
return storagedriver.InvalidAccessKeyIdError{}
}
}
return err
Expand Down
10 changes: 10 additions & 0 deletions registry/storage/driver/storagedriver.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,16 @@ func (err UserSuspendedError) Error() string {
return fmt.Sprintf("%s: user is suspended", err.DriverName)
}

// InvalidAccessKeyIdError is returned when an invalided access key and/or secret key
// is provided to the S3 api.
type InvalidAccessKeyIdError struct {
DriverName string
}

func (err InvalidAccessKeyIdError) Error() string {
return fmt.Sprintf("%s: access key and secret key is invalid", err.DriverName)
}

// Error is a catch-all error type which captures an error string and
// the driver type on which it occurred.
type Error struct {
Expand Down
18 changes: 18 additions & 0 deletions registry/storage/manifeststore.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,24 @@ func (ms *manifestStore) Exists(ctx context.Context, dgst digest.Digest) (bool,
return true, nil
}

func (ms *manifestStore) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) {
Copy link

@gane5hvarma gane5hvarma Jan 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think we can have stat method in our dataplane code instead of distribution repo.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can but I thought this would be an apt place to be since all other types have a Stat method but for some reason ManifestService does not.

dcontext.GetLogger(ms.ctx).Debug("(*manifestStore).Exists")

descriptor, err := ms.blobStore.Stat(ctx, dgst)
if err != nil {
if err == distribution.ErrBlobUnknown {
return distribution.Descriptor{}, distribution.ErrManifestUnknownRevision{

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add err too to have the stack trace on what happened.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we want stack trace, we can add it to data plane code instead of the distribution fork. Better to keep this fork lean and minimal diff with respect to open source's distribution.

Name: ms.repository.Named().Name(),
Revision: dgst,
}
}

return distribution.Descriptor{}, err
}

return descriptor, nil
}

func (ms *manifestStore) Get(ctx context.Context, dgst digest.Digest, options ...distribution.ManifestServiceOption) (distribution.Manifest, error) {
dcontext.GetLogger(ms.ctx).Debug("(*manifestStore).Get")

Expand Down