origin

package
v0.19.0 Latest Latest
Warning

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

Go to latest
Published: Nov 3, 2026 License: Apache-2.0 Imports: 28 Imported by: 0

Documentation

Overview

Package origin pulls bytes from upstream OCI registries.

scope:

- Multi-registry: one *Client serves every UpstreamRegistry configured by the operator. - Endpoints: GET /v2/, GET /v2/<repo>/blobs/<digest>, GET /v2/<repo>/manifests/<digest>. - Auth: request-scoped delegated Basic/Bearer authorization takes precedence and is used without caching or identity fallback. Without configured shared credentials, the client discovers the upstream /v2/ challenge for containerd. An optional "username:password" file retains the legacy shared-identity flow. - Failure classification: maps HTTP status and network errors to ifaces.FailureClass for the design doc propagation. Tag-resolution requests are not handled here (the mirror returns 503 on tag manifests so containerd falls through to origin directly - the design doc / the design doc).

Out of scope for (lands later):

- the design doc negative-cache cooldown integration . - Per-pull retries with backoff (caller's responsibility for now).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

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

Client is the concrete OriginPuller. It fans out to one *registry per configured upstream and routes calls by OriginRef.Registry.

func New

func New(cfg *config.Config, opts ...Option) (*Client, error)

New builds a Client from the operator config. Unless shared credentials are disabled, it returns an error if an upstream credentials file cannot be read.

func (*Client) AuthenticationChallenge added in v0.1.22

func (c *Client) AuthenticationChallenge(ctx context.Context, registry string) (challenge string, required bool, err error)

AuthenticationChallenge returns the configured registry's current Basic/Bearer challenge. required is false when the registry's /v2/ endpoint permits anonymous access. Results are cached per registry so ordinary mirror requests do not add an upstream round trip.

func (*Client) Head

func (c *Client) Head(ctx context.Context, ref ifaces.OriginRef) (int64, string, error)

Head implements ifaces.OriginPuller.

HEAD is a deliberately separate code path from Pull. Two design points matter:

1. HEAD does NOT fire onPullStart. p2p_origin_pull_total counts byte-pull attempts; mixing HEAD in inflated the counter against an operation that produces no bytes, never commits to cache, and therefore can fire neither p2p_origin_pull_success_total (because mirror+puller-pump bump success after Commit, and HEAD never writes a cache entry) nor a downstream-failure counter (HEAD doesn't io.Copy a body, so it can't fail at the body-copy boundary). Leaving HEAD out keeps the started == success + failure + in_flight identity intact for the pull arithmetic. This constraint ensures exactly this drift.

2. HEAD also does NOT fire onPullFailure. The pull-failure hook double-bumps p2p_origin_pull_failure_total{kind,class} + p2p_origin_failure_total{class} (see cmd/gantry/main.go's origin.WithMetrics closure); both belong to the pull family. A future batch can add a dedicated p2p_origin_head_total / _failure_total pair if operators need HEAD-specific signal, but for now HEAD failures surface to operators via the mirror's HTTP status and access log alone.

func (*Client) Pull

func (c *Client) Pull(ctx context.Context, ref ifaces.OriginRef) (io.ReadCloser, int64, error)

Pull implements ifaces.OriginPuller.

Returns the raw response-body ReadCloser; the caller is responsible for streaming the body and reporting per-operation success via their own metric hook (the mirror's serveDigest verifies stream completion; the puller pump's runOriginPull does the equivalent after commit, reopen, and advertiser mark-present). origin reports STARTED unconditionally on entry and FAILURE on its own error paths only; it does NOT wrap the response body in a success-on-Close counter because Close has no way to know whether the higher-level operation actually succeeded (HEAD never reads the body; io.Copy + cache.Commit failures both fire Close on a deferred path).

func (*Client) PullRange added in v0.13.0

func (c *Client) PullRange(ctx context.Context, ref ifaces.OriginRef, length int64) (io.ReadCloser, int64, string, error)

PullRange implements ifaces.OriginRangePuller without a metadata round trip.

func (*Client) RepositoryAuthenticationChallenge added in v0.13.0

func (c *Client) RepositoryAuthenticationChallenge(ctx context.Context, ref ifaces.OriginRef) (string, bool, error)

RepositoryAuthenticationChallenge recovers a challenge after a remote origin rejects a request. The registry root can be public, and another node's cached challenge is not available here. Probe the caller's resource anonymously, with one manifest HEAD fallback on a blob 404 for the same repository and digest. Never follow redirects, exchange tokens, fetch content, or cache the challenge.

type Option

type Option func(*Client)

Option configures a Client.

func WithByteMetrics added in v0.2.1

func WithByteMetrics(onBytesRead func(kind string, bytes int64)) Option

WithByteMetrics registers a callback for bytes actually read from upstream response bodies. It includes partial failed transfers and retries, and does not count HEAD requests. The callback fires once when the body reaches a terminal read result or is closed. Hooks must support concurrent calls.

func WithDelegatedCredentialsOnly added in v0.13.0

func WithDelegatedCredentialsOnly() Option

WithDelegatedCredentialsOnly disables configured shared credentials, including endpoint user information. Anonymous Bearer exchange remains available. Request-scoped credentials are never replaced with a shared identity.

func WithLogger

func WithLogger(l *slog.Logger) Option

WithLogger plumbs a structured logger.

func WithMetrics

func WithMetrics(start func(kind string), failure func(kind, class string)) Option

WithMetrics registers metric callbacks.

start fires once at the top of every Pull or PullRange invocation, before the registry lookup. failure fires once on any terminal error path (unknown registry, transport error, non-2xx response, auth failure). Success is NOT emitted here - see the metricsHooks doc for why and where it belongs.

func WithRequestMetrics added in v0.13.0

func WithRequestMetrics(onRequest func(method string, statusCode int)) Option

WithRequestMetrics observes each HTTP transport round trip, including HEAD, GET, redirects, manifest fallbacks, and authentication exchanges. statusCode is zero for transport failures. It does not expose URLs or credentials. Transport-internal retries are part of the same round trip. Hooks must be concurrency-safe. This is independent of the logical pull hooks in WithMetrics.

Jump to

Keyboard shortcuts

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