cue-labs / oci

Go modules related to OCI (Open Container Initiative) registries
Apache License 2.0
22 stars 3 forks source link

ociregistry: reference support #7

Closed rogpeppe closed 1 year ago

rogpeppe commented 1 year ago

Currently ociregistry provides intra-registry operations but there's nothing that knows how to parse the usual someregistry.com/foo/bar:tag-style references.

Here's an idea for a possible package to allow this. This allows references to be resolved to local registry implementations that aren't necessarily available via HTTP.

// Package ociref implements cross-registry OCI operations.
package ociref

// Resolver implements a mapping between host names and
// registry implementations. See ociclient.Resolver for
// the standard implementation that simply maps DNS hostnames
// to ociclient registry implementations.
type Resolver interface {
    // Registry returns a registry implementation to use
    // for the given host name.
    Resolve(host string) (ociregistry.Interface, error)
}

// ParseReference parses a reference string.
func ParseReference(ref string) (Reference, error)

// Reference represents an entry in an OCI repository.
// It is often represented as HOST/NAME[:TAG|@DIGEST]
// form: the same syntax accepted by "docker pull".
// Unlike "docker pull" however, there is no default registry.
type Reference struct {
    // Registry holds the host name of the registry
    // within which the repository is stored.
    Registry string

    // Repository holds the repository name.
    Repository string

    // Tag holds the TAG part of a :TAG or :TAG@DIGEST reference.
    // When Digest is set as well as Tag, the tag will be verified
    // to exist and have the expected digest.
    Tag string

    // Digest holds the DIGEST part of an @DIGEST reference
    // or of a :TAG@DIGEST reference.
    Digest digest.Digest
}

// String returns the string form of a reference in the form
//  HOST/NAME[:TAG|@DIGEST]
//
func (ref Reference) String() string

// Namespace represents an entire OCI container namespace
// and all the registries available in it.
//
// Its methods take reference strings as arguments, which are
// interpreted with ParseReference before being
// resolved to individual registries with the Resolver.
type Namespace struct {
    // Resolver holds the resolver used to map
    // host names to registry implementations.
    // If it's nil, [ociclient.Resolver] will be used.
    Resolver Resolver
}

// CopyOptions holds options for [Namespace.CopyManifest].
type CopyOptions struct {
    // By default, CopyManifest will copy manifests that refer
    // to the source manifest as well as that manifest itself.
    // If WithoutReferrers is set, referrers will not be copied.
    WithoutReferrers bool

    // ManifestDigests returns the digests of all the objects referred to
    // by the manifest with the given media type and contents.
    // The blobs return parameter holds the digests of data blobs;
    // the manifests return parameter holds the digests of other manifests,
    // which will be copied recursively.
    //
    // If this is nil, the [ManifestDigests] function will be used, which
    // knows how to parse the usual well known manifest and manifest index types.
    ManifestDigests func(mediaType string, manifestData []byte) (blobs, manifests []Digest, err error)
}
// CopyManifest makes the contents of the manifest referred to by
// src and all the blobs that it refers to available inside dst.
//
// It will use mount operations when possible to reduce the
// amount of copying that takes place.
func (ns Namespace) CopyManifest(ctx context.Context, dstRef, srcRef string, opts *CopyOptions) error

// CopyBlob copies a single data blob from src to dst. It will use
// mount operations if possible.
// It returns an error if either argument refers to a tag.
func (ns Namespace) CopyBlob(ctx context.Context, dstRef, srcRef string) error

// GetBlob returns the contents of the blob referred to by ref.
// It returns an error if ref refers to a tag.
func (ns Namespace) GetBlob(ctx context.Context, ref string) (BlobReader, error)

// GetManifest returns the contents of the manifest referred to by ref.
func (ns Namespace) GetManifest(ctx context.Context, ref string) (BlobReader, error)

// ResolveBlob returns the descriptor for the given blob reference.
// It returns an error if it refers to a tag.
func (ns Namespace) ResolveBlob(ctx context.Context, ref string) (Descriptor, error)

// ResolveBlob returns the descriptor for the given manifest reference.
func (ns Namespace) ResolveManifest(ctx context.Context, ref string) (Descriptor, error)

// ManifestDigests knows how to parse the commonly known set of
// manifest and manifest index types to return the entities
// that they refer to. This can be used in [CopyOptions.ManifestDigests].
func ManifestDigests(mediaType string, manifestData []byte) (blobs, manifests []Digest, err error)