1
0
mirror of https://github.com/regclient/regclient.git synced 2025-04-18 22:44:00 +03:00
regclient/referrer.go
Brandon Mitchell 763599514d
Feat: Include source in referrers response
This simplifies handling external sources.

Signed-off-by: Brandon Mitchell <git@bmitch.net>
2024-12-03 17:12:10 -05:00

58 lines
1.9 KiB
Go

package regclient
import (
"context"
"fmt"
"github.com/regclient/regclient/scheme"
"github.com/regclient/regclient/types/errs"
"github.com/regclient/regclient/types/platform"
"github.com/regclient/regclient/types/ref"
"github.com/regclient/regclient/types/referrer"
"github.com/regclient/regclient/types/warning"
)
// ReferrerList retrieves a list of referrers to a manifest.
// The descriptor list should contain manifests that each have a subject field matching the requested ref.
func (rc *RegClient) ReferrerList(ctx context.Context, rSubject ref.Ref, opts ...scheme.ReferrerOpts) (referrer.ReferrerList, error) {
if !rSubject.IsSet() {
return referrer.ReferrerList{}, fmt.Errorf("ref is not set: %s%.0w", rSubject.CommonName(), errs.ErrInvalidReference)
}
// dedup warnings
if w := warning.FromContext(ctx); w == nil {
ctx = warning.NewContext(ctx, &warning.Warning{Hook: warning.DefaultHook()})
}
// set the digest on the subject reference
config := scheme.ReferrerConfig{}
for _, opt := range opts {
opt(&config)
}
if rSubject.Digest == "" || config.Platform != "" {
mo := []ManifestOpts{WithManifestRequireDigest()}
if config.Platform != "" {
p, err := platform.Parse(config.Platform)
if err != nil {
return referrer.ReferrerList{}, fmt.Errorf("failed to lookup referrer platform: %w", err)
}
mo = append(mo, WithManifestPlatform(p))
}
m, err := rc.ManifestHead(ctx, rSubject, mo...)
if err != nil {
return referrer.ReferrerList{}, fmt.Errorf("failed to get digest for subject: %w", err)
}
rSubject = rSubject.SetDigest(m.GetDescriptor().Digest.String())
}
// lookup the scheme for the appropriate ref
var r ref.Ref
if config.SrcRepo.IsSet() {
r = config.SrcRepo
} else {
r = rSubject
}
schemeAPI, err := rc.schemeGet(r.Scheme)
if err != nil {
return referrer.ReferrerList{}, err
}
return schemeAPI.ReferrerList(ctx, rSubject, opts...)
}