oci

package
v1.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 22, 2026 License: Apache-2.0 Imports: 23 Imported by: 0

Documentation

Overview

Package oci implements the OCI Distribution Specification v2 protocol as a read-through cache for container registries.

Index

Constants

View Source
const (
	MediaTypeDockerManifestV2      = "application/vnd.docker.distribution.manifest.v2+json"
	MediaTypeDockerManifestList    = "application/vnd.docker.distribution.manifest.list.v2+json"
	MediaTypeOCIManifest           = "application/vnd.oci.image.manifest.v1+json"
	MediaTypeOCIIndex              = "application/vnd.oci.image.index.v1+json"
	MediaTypeDockerContainerConfig = "application/vnd.docker.container.image.v1+json"
	MediaTypeOCIConfig             = "application/vnd.oci.image.config.v1+json"
)

Media types for OCI and Docker manifests.

View Source
const (
	// DefaultRegistryURL is the default Docker Hub registry.
	DefaultRegistryURL = "https://registry-1.docker.io"

	// DefaultTimeout is the default timeout for upstream requests.
	DefaultTimeout = 30 * time.Second

	// DockerContentDigestHeader is the header containing the manifest digest.
	DockerContentDigestHeader = "Docker-Content-Digest"
)
View Source
const (

	// DefaultTagTTL is the default TTL for tag->digest mappings.
	DefaultTagTTL = 5 * time.Minute
)

Variables

View Source
var (
	ErrInvalidDigest   = errors.New("invalid digest format")
	ErrDigestMismatch  = errors.New("digest mismatch")
	ErrUnsupportedAlgo = errors.New("unsupported digest algorithm")
)

Common errors for digest operations.

DefaultAcceptHeader is the Accept header sent when fetching manifests.

View Source
var ErrNoMatchingRegistry = errors.New("no matching registry for path")

ErrNoMatchingRegistry is returned when no registry prefix matches the request path.

View Source
var ErrNotFound = errors.New("not found")

ErrNotFound is returned when a resource is not found in the index.

View Source
var ErrUnauthorized = errors.New("unauthorized")

ErrUnauthorized indicates authentication is required but failed.

Functions

func BuildScope

func BuildScope(imageName, action string) string

BuildScope constructs an OCI registry scope string for the given image and action.

func ComputeSHA256

func ComputeSHA256(content []byte) string

ComputeSHA256 computes the SHA256 digest of content.

func ComputeSHA256Reader

func ComputeSHA256Reader(r io.Reader) (string, error)

ComputeSHA256Reader computes the SHA256 digest from a reader.

func IsDigestReference

func IsDigestReference(reference string) bool

IsDigestReference returns true if the reference is a digest (contains @sha256:).

Types

type AuthCache

type AuthCache struct {
	// contains filtered or unexported fields
}

AuthCache caches authentication tokens per scope.

func NewAuthCache

func NewAuthCache() *AuthCache

NewAuthCache creates a new authentication token cache.

func (*AuthCache) Clear

func (ac *AuthCache) Clear()

Clear removes all cached tokens.

func (*AuthCache) GetToken

func (ac *AuthCache) GetToken(scope string) string

GetToken returns a valid token for the scope, or empty string if none cached.

func (*AuthCache) SetToken

func (ac *AuthCache) SetToken(scope, token string, expiresIn int)

SetToken caches a token for the scope with expiration.

type AuthChallenge

type AuthChallenge struct {
	Realm   string
	Service string
	Scope   string
}

AuthChallenge represents a parsed WWW-Authenticate Bearer challenge.

func ParseWWWAuthenticate

func ParseWWWAuthenticate(header string) (*AuthChallenge, error)

ParseWWWAuthenticate parses the WWW-Authenticate header from a 401 response. Example: Bearer realm="https://auth.docker.io/token",service="registry.docker.io",scope="repository:library/nginx:pull"

type CachedBlob

type CachedBlob struct {
	Digest      string            `json:"digest"`       // sha256:...
	ContentHash contentcache.Hash `json:"content_hash"` // BLAKE3 hash in CAFS
	Size        int64             `json:"size"`
	CachedAt    time.Time         `json:"cached_at"`
}

CachedBlob stores cached blob metadata.

type CachedImage

type CachedImage struct {
	Name      string                `json:"name"`
	Tags      map[string]*CachedTag `json:"tags"`
	CachedAt  time.Time             `json:"cached_at"`
	UpdatedAt time.Time             `json:"updated_at"`
}

CachedImage stores cached image metadata including tag mappings.

type CachedManifest

type CachedManifest struct {
	Digest      string            `json:"digest"`
	MediaType   string            `json:"media_type"`
	ContentHash contentcache.Hash `json:"content_hash"` // Hash in CAFS
	Size        int64             `json:"size"`
	CachedAt    time.Time         `json:"cached_at"`
}

CachedManifest stores a cached manifest's metadata.

type CachedTag

type CachedTag struct {
	Tag         string    `json:"tag"`
	Digest      string    `json:"digest"` // Current digest for this tag
	CachedAt    time.Time `json:"cached_at"`
	RefreshedAt time.Time `json:"refreshed_at"` // Last upstream check
}

CachedTag tracks a tag->digest mapping with TTL info.

type Descriptor

type Descriptor struct {
	MediaType   string            `json:"mediaType"`
	Digest      string            `json:"digest"` // sha256:...
	Size        int64             `json:"size"`
	URLs        []string          `json:"urls,omitempty"`
	Annotations map[string]string `json:"annotations,omitempty"`
}

Descriptor describes a blob in an OCI manifest.

type Digest

type Digest struct {
	Algorithm string // sha256, sha512
	Hex       string // hex-encoded hash
}

Digest represents an OCI content digest (algorithm:hex).

func ParseDigest

func ParseDigest(s string) (Digest, error)

ParseDigest parses a digest string like "sha256:abc123...".

func (Digest) IsZero

func (d Digest) IsZero() bool

IsZero returns true if the digest is uninitialized.

func (Digest) NewHasher

func (d Digest) NewHasher() (hash.Hash, error)

NewHasher returns a hash.Hash for the digest's algorithm.

func (Digest) String

func (d Digest) String() string

String returns the canonical digest string (algorithm:hex).

func (Digest) Verify

func (d Digest) Verify(content []byte) error

Verify checks if content matches the digest.

func (Digest) VerifyReader

func (d Digest) VerifyReader(r io.Reader) ([]byte, error)

VerifyReader reads all content and verifies the digest. Returns the content if verification succeeds.

type Handler

type Handler struct {
	// contains filtered or unexported fields
}

Handler implements the OCI Distribution v2 protocol as an HTTP handler.

func NewHandler

func NewHandler(index *Index, store store.Store, opts ...HandlerOption) *Handler

NewHandler creates a new OCI registry handler.

func (*Handler) Close

func (h *Handler) Close()

Close shuts down the handler and waits for background operations to complete.

func (*Handler) ServeHTTP

func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements http.Handler.

type HandlerOption

type HandlerOption func(*Handler)

HandlerOption configures a Handler.

func WithDownloader

func WithDownloader(dl *download.Downloader) HandlerOption

WithDownloader sets the singleflight downloader for deduplicating concurrent fetches.

func WithLogger

func WithLogger(logger *slog.Logger) HandlerOption

WithLogger sets the logger for the handler.

func WithRouter

func WithRouter(router *Router) HandlerOption

WithRouter sets the registry router for prefix-based upstream routing.

func WithTagTTL

func WithTagTTL(ttl time.Duration) HandlerOption

WithTagTTL sets the TTL for tag->digest cache entries.

type Index

type Index struct {
	// contains filtered or unexported fields
}

Index manages the OCI image cache index using metadb envelope storage.

func NewIndex

func NewIndex(imageIndex, manifestIndex, blobIndex *metadb.EnvelopeIndex) *Index

NewIndex creates a new OCI index using EnvelopeIndex instances. imageIndex: protocol="oci", kind="image" for tag-to-digest mappings (CachedImage) manifestIndex: protocol="oci", kind="manifest" for manifest metadata (CachedManifest) blobIndex: protocol="oci", kind="blob" for blob metadata (CachedBlob)

func (*Index) GetBlob

func (idx *Index) GetBlob(ctx context.Context, digest string) (*CachedBlob, error)

GetBlob returns the cached blob metadata by digest.

func (*Index) GetManifest

func (idx *Index) GetManifest(ctx context.Context, digest string) (*CachedManifest, error)

GetManifest returns the cached manifest metadata by digest.

func (*Index) GetTagDigest

func (idx *Index) GetTagDigest(ctx context.Context, name, tag string) (string, time.Time, error)

GetTagDigest returns the cached digest for a tag and when it was last refreshed.

func (*Index) ListImages

func (idx *Index) ListImages(ctx context.Context) ([]string, error)

ListImages returns a list of all cached image names.

func (*Index) PutBlob

func (idx *Index) PutBlob(ctx context.Context, digest string, hash contentcache.Hash, size int64) error

PutBlob stores blob metadata in the index.

func (*Index) PutManifest

func (idx *Index) PutManifest(ctx context.Context, digest, mediaType string, hash contentcache.Hash, size int64) error

PutManifest stores manifest metadata in the index.

func (*Index) RefreshTag

func (idx *Index) RefreshTag(ctx context.Context, name, tag string) error

RefreshTag updates the RefreshedAt timestamp for a tag without changing the digest.

func (*Index) SetTagDigest

func (idx *Index) SetTagDigest(ctx context.Context, name, tag, digest string) error

SetTagDigest updates the tag->digest mapping for an image.

type Manifest

type Manifest struct {
	SchemaVersion int               `json:"schemaVersion"`
	MediaType     string            `json:"mediaType,omitempty"`
	Config        Descriptor        `json:"config"`
	Layers        []Descriptor      `json:"layers"`
	Annotations   map[string]string `json:"annotations,omitempty"`
}

Manifest represents an OCI image manifest (v2).

type ManifestDescriptor

type ManifestDescriptor struct {
	Descriptor
	Platform *Platform `json:"platform,omitempty"`
}

ManifestDescriptor extends Descriptor with platform information for manifest lists/indexes.

type ManifestList

type ManifestList struct {
	SchemaVersion int                  `json:"schemaVersion"`
	MediaType     string               `json:"mediaType,omitempty"`
	Manifests     []ManifestDescriptor `json:"manifests"`
	Annotations   map[string]string    `json:"annotations,omitempty"`
}

ManifestList represents an OCI image index (for multi-arch images).

type Platform

type Platform struct {
	Architecture string   `json:"architecture"`
	OS           string   `json:"os"`
	OSVersion    string   `json:"os.version,omitempty"`
	OSFeatures   []string `json:"os.features,omitempty"`
	Variant      string   `json:"variant,omitempty"`
	Features     []string `json:"features,omitempty"`
}

Platform describes the OS and architecture of a manifest.

type Registry

type Registry struct {
	Prefix   string
	Upstream *Upstream
	TagTTL   time.Duration
}

Registry represents a configured upstream OCI registry with a routing prefix.

type Router

type Router struct {
	// contains filtered or unexported fields
}

Router routes OCI requests to the appropriate upstream registry based on prefix.

func NewRouter

func NewRouter(registries []Registry, opts ...RouterOption) (*Router, error)

NewRouter creates a new Router with the given registries. It validates that prefixes are non-empty, lowercase, contain no slashes, are unique, and that no prefix is a prefix of another.

func (*Router) Route

func (rt *Router) Route(path string) (*Registry, string, error)

Route matches a request path to a registry. The path should be the full path (e.g., "/v2/docker-hub/library/nginx/manifests/latest"). Returns the matched registry, the remainder path (e.g., "library/nginx/manifests/latest"), and any error.

type RouterOption

type RouterOption func(*Router)

RouterOption configures a Router.

func WithRouterLogger

func WithRouterLogger(logger *slog.Logger) RouterOption

WithRouterLogger sets the logger for the router.

type TokenResponse

type TokenResponse struct {
	Token       string `json:"token"`
	AccessToken string `json:"access_token"` // Some registries use this field
	ExpiresIn   int    `json:"expires_in"`
	IssuedAt    string `json:"issued_at"`
}

TokenResponse represents an authentication token response.

func FetchToken

func FetchToken(ctx context.Context, client *http.Client, challenge *AuthChallenge, username, password string) (*TokenResponse, error)

FetchToken requests a new token from the auth server.

type Upstream

type Upstream struct {
	// contains filtered or unexported fields
}

Upstream fetches content from an upstream OCI registry.

func NewUpstream

func NewUpstream(opts ...UpstreamOption) *Upstream

NewUpstream creates a new upstream registry client.

func (*Upstream) CheckVersion

func (u *Upstream) CheckVersion(ctx context.Context) error

CheckVersion verifies the registry supports the v2 API.

func (*Upstream) FetchBlob

func (u *Upstream) FetchBlob(ctx context.Context, name, digest string) (io.ReadCloser, int64, error)

FetchBlob retrieves a blob by digest. Returns a ReadCloser that must be closed by the caller.

func (*Upstream) FetchManifest

func (u *Upstream) FetchManifest(ctx context.Context, name, reference string) ([]byte, string, string, error)

FetchManifest retrieves a manifest by tag or digest. Returns the manifest content, media type, and digest.

func (*Upstream) HeadBlob

func (u *Upstream) HeadBlob(ctx context.Context, name, digest string) (int64, error)

HeadBlob checks blob existence and returns the size.

func (*Upstream) HeadManifest

func (u *Upstream) HeadManifest(ctx context.Context, name, reference string) (string, int64, string, error)

HeadManifest checks manifest existence and returns the digest, size, and media type.

type UpstreamOption

type UpstreamOption func(*Upstream)

UpstreamOption configures an Upstream.

func WithBasicAuth

func WithBasicAuth(username, password string) UpstreamOption

WithBasicAuth sets credentials for registry authentication.

func WithHTTPClient

func WithHTTPClient(client *http.Client) UpstreamOption

WithHTTPClient sets a custom HTTP client.

func WithRegistryURL

func WithRegistryURL(url string) UpstreamOption

WithRegistryURL sets the upstream registry URL.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL