mirror of
https://github.com/regclient/regclient.git
synced 2025-04-18 22:44:00 +03:00
This simplifies handling external sources. Signed-off-by: Brandon Mitchell <git@bmitch.net>
235 lines
8.2 KiB
Go
235 lines
8.2 KiB
Go
// Package scheme defines the interface for various reference schemes.
|
|
package scheme
|
|
|
|
import (
|
|
"context"
|
|
"io"
|
|
|
|
"github.com/regclient/regclient/internal/pqueue"
|
|
"github.com/regclient/regclient/internal/reqmeta"
|
|
"github.com/regclient/regclient/types/blob"
|
|
"github.com/regclient/regclient/types/descriptor"
|
|
"github.com/regclient/regclient/types/manifest"
|
|
"github.com/regclient/regclient/types/ping"
|
|
"github.com/regclient/regclient/types/ref"
|
|
"github.com/regclient/regclient/types/referrer"
|
|
"github.com/regclient/regclient/types/tag"
|
|
)
|
|
|
|
// API is used to interface between different methods to store images.
|
|
type API interface {
|
|
// BlobDelete removes a blob from the repository.
|
|
BlobDelete(ctx context.Context, r ref.Ref, d descriptor.Descriptor) error
|
|
// BlobGet retrieves a blob, returning a reader.
|
|
BlobGet(ctx context.Context, r ref.Ref, d descriptor.Descriptor) (blob.Reader, error)
|
|
// BlobHead verifies the existence of a blob, the reader contains the headers but no body to read.
|
|
BlobHead(ctx context.Context, r ref.Ref, d descriptor.Descriptor) (blob.Reader, error)
|
|
// BlobMount attempts to perform a server side copy of the blob.
|
|
BlobMount(ctx context.Context, refSrc ref.Ref, refTgt ref.Ref, d descriptor.Descriptor) error
|
|
// BlobPut sends a blob to the repository, returns the digest and size when successful.
|
|
BlobPut(ctx context.Context, r ref.Ref, d descriptor.Descriptor, rdr io.Reader) (descriptor.Descriptor, error)
|
|
|
|
// ManifestDelete removes a manifest, including all tags that point to that manifest.
|
|
ManifestDelete(ctx context.Context, r ref.Ref, opts ...ManifestOpts) error
|
|
// ManifestGet retrieves a manifest from a repository.
|
|
ManifestGet(ctx context.Context, r ref.Ref) (manifest.Manifest, error)
|
|
// ManifestHead gets metadata about the manifest (existence, digest, mediatype, size).
|
|
ManifestHead(ctx context.Context, r ref.Ref) (manifest.Manifest, error)
|
|
// ManifestPut sends a manifest to the repository.
|
|
ManifestPut(ctx context.Context, r ref.Ref, m manifest.Manifest, opts ...ManifestOpts) error
|
|
|
|
// Ping verifies access to a registry or equivalent.
|
|
Ping(ctx context.Context, r ref.Ref) (ping.Result, error)
|
|
|
|
// ReferrerList returns a list of referrers to a given reference.
|
|
ReferrerList(ctx context.Context, r ref.Ref, opts ...ReferrerOpts) (referrer.ReferrerList, error)
|
|
|
|
// TagDelete removes a tag from the repository.
|
|
TagDelete(ctx context.Context, r ref.Ref) error
|
|
// TagList returns a list of tags from the repository.
|
|
TagList(ctx context.Context, r ref.Ref, opts ...TagOpts) (*tag.List, error)
|
|
}
|
|
|
|
// Closer is used to check if a scheme implements the Close API.
|
|
type Closer interface {
|
|
Close(ctx context.Context, r ref.Ref) error
|
|
}
|
|
|
|
// GCLocker is used to indicate locking is available for GC management.
|
|
type GCLocker interface {
|
|
// GCLock a reference to prevent GC from triggering during a put, locks are not exclusive.
|
|
GCLock(r ref.Ref)
|
|
// GCUnlock a reference to allow GC (once all locks are released).
|
|
// The reference should be closed after this step and unlock should only be called once per each Lock call.
|
|
GCUnlock(r ref.Ref)
|
|
}
|
|
|
|
// Throttler is used to indicate the scheme implements Throttle.
|
|
type Throttler interface {
|
|
Throttle(r ref.Ref, put bool) []*pqueue.Queue[reqmeta.Data]
|
|
}
|
|
|
|
// ManifestConfig is used by schemes to import [ManifestOpts].
|
|
type ManifestConfig struct {
|
|
CheckReferrers bool
|
|
Child bool // used when pushing a child of a manifest list, skips indexing in ocidir
|
|
Manifest manifest.Manifest
|
|
}
|
|
|
|
// ManifestOpts is used to set options on manifest APIs.
|
|
type ManifestOpts func(*ManifestConfig)
|
|
|
|
// WithManifestCheckReferrers is used when deleting a manifest.
|
|
// It indicates the manifest should be fetched and referrers should be deleted if defined.
|
|
func WithManifestCheckReferrers() ManifestOpts {
|
|
return func(config *ManifestConfig) {
|
|
config.CheckReferrers = true
|
|
}
|
|
}
|
|
|
|
// WithManifestChild indicates the API call is on a child manifest.
|
|
// This is used internally when copying multi-platform manifests.
|
|
// This bypasses tracking of an untagged digest in ocidir which is needed for garbage collection.
|
|
func WithManifestChild() ManifestOpts {
|
|
return func(config *ManifestConfig) {
|
|
config.Child = true
|
|
}
|
|
}
|
|
|
|
// WithManifest is used to pass the manifest to a method to avoid an extra GET request.
|
|
// This is used on a delete to check for referrers.
|
|
func WithManifest(m manifest.Manifest) ManifestOpts {
|
|
return func(mc *ManifestConfig) {
|
|
mc.Manifest = m
|
|
}
|
|
}
|
|
|
|
// ReferrerConfig is used by schemes to import [ReferrerOpts].
|
|
type ReferrerConfig struct {
|
|
MatchOpt descriptor.MatchOpt // filter/sort results
|
|
Platform string // get referrers for a specific platform
|
|
SrcRepo ref.Ref // repo used to query referrers
|
|
}
|
|
|
|
// ReferrerOpts is used to set options on referrer APIs.
|
|
type ReferrerOpts func(*ReferrerConfig)
|
|
|
|
// WithReferrerMatchOpt filters results using [descriptor.MatchOpt].
|
|
func WithReferrerMatchOpt(mo descriptor.MatchOpt) ReferrerOpts {
|
|
return func(config *ReferrerConfig) {
|
|
config.MatchOpt = mo
|
|
}
|
|
}
|
|
|
|
// WithReferrerPlatform gets referrers for a single platform from a multi-platform manifest.
|
|
// Note that this is implemented by [regclient.ReferrerList] and not the individual scheme implementations.
|
|
func WithReferrerPlatform(p string) ReferrerOpts {
|
|
return func(config *ReferrerConfig) {
|
|
config.Platform = p
|
|
}
|
|
}
|
|
|
|
// WithReferrerSource pulls referrers from a separate source.
|
|
// Note that this is implemented by [regclient.ReferrerList] and not the individual scheme implementations.
|
|
func WithReferrerSource(r ref.Ref) ReferrerOpts {
|
|
return func(config *ReferrerConfig) {
|
|
config.SrcRepo = r
|
|
}
|
|
}
|
|
|
|
// WithReferrerAT filters by a specific artifactType value.
|
|
//
|
|
// Deprecated: replace with [WithReferrerMatchOpt].
|
|
func WithReferrerAT(at string) ReferrerOpts {
|
|
return func(config *ReferrerConfig) {
|
|
config.MatchOpt.ArtifactType = at
|
|
}
|
|
}
|
|
|
|
// WithReferrerAnnotations filters by a list of annotations, all of which must match.
|
|
//
|
|
// Deprecated: replace with [WithReferrerMatchOpt].
|
|
func WithReferrerAnnotations(annotations map[string]string) ReferrerOpts {
|
|
return func(config *ReferrerConfig) {
|
|
if config.MatchOpt.Annotations == nil {
|
|
config.MatchOpt.Annotations = annotations
|
|
} else {
|
|
for k, v := range annotations {
|
|
config.MatchOpt.Annotations[k] = v
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// WithReferrerSort orders the resulting referrers listing according to a specified annotation.
|
|
//
|
|
// Deprecated: replace with [WithReferrerMatchOpt].
|
|
func WithReferrerSort(annotation string, desc bool) ReferrerOpts {
|
|
return func(config *ReferrerConfig) {
|
|
config.MatchOpt.SortAnnotation = annotation
|
|
config.MatchOpt.SortDesc = desc
|
|
}
|
|
}
|
|
|
|
// ReferrerFilter filters the referrer list according to the config.
|
|
func ReferrerFilter(config ReferrerConfig, rlIn referrer.ReferrerList) referrer.ReferrerList {
|
|
return referrer.ReferrerList{
|
|
Subject: rlIn.Subject,
|
|
Source: rlIn.Source,
|
|
Manifest: rlIn.Manifest,
|
|
Annotations: rlIn.Annotations,
|
|
Tags: rlIn.Tags,
|
|
Descriptors: descriptor.DescriptorListFilter(rlIn.Descriptors, config.MatchOpt),
|
|
}
|
|
}
|
|
|
|
// RepoConfig is used by schemes to import [RepoOpts].
|
|
type RepoConfig struct {
|
|
Limit int
|
|
Last string
|
|
}
|
|
|
|
// RepoOpts is used to set options on repo APIs.
|
|
type RepoOpts func(*RepoConfig)
|
|
|
|
// WithRepoLimit passes a maximum number of repositories to return to the repository list API.
|
|
// Registries may ignore this.
|
|
func WithRepoLimit(l int) RepoOpts {
|
|
return func(config *RepoConfig) {
|
|
config.Limit = l
|
|
}
|
|
}
|
|
|
|
// WithRepoLast passes the last received repository for requesting the next batch of repositories.
|
|
// Registries may ignore this.
|
|
func WithRepoLast(l string) RepoOpts {
|
|
return func(config *RepoConfig) {
|
|
config.Last = l
|
|
}
|
|
}
|
|
|
|
// TagConfig is used by schemes to import [TagOpts].
|
|
type TagConfig struct {
|
|
Limit int
|
|
Last string
|
|
}
|
|
|
|
// TagOpts is used to set options on tag APIs.
|
|
type TagOpts func(*TagConfig)
|
|
|
|
// WithTagLimit passes a maximum number of tags to return to the tag list API.
|
|
// Registries may ignore this.
|
|
func WithTagLimit(limit int) TagOpts {
|
|
return func(t *TagConfig) {
|
|
t.Limit = limit
|
|
}
|
|
}
|
|
|
|
// WithTagLast passes the last received tag for requesting the next batch of tags.
|
|
// Registries may ignore this.
|
|
func WithTagLast(last string) TagOpts {
|
|
return func(t *TagConfig) {
|
|
t.Last = last
|
|
}
|
|
}
|