acr

package
v0.1.26 Latest Latest
Warning

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

Go to latest
Published: Sep 8, 2026 License: MIT Imports: 42 Imported by: 0

Documentation

Overview

Package acr provides access to OCI artifacts stored in an Azure Container Registry (or any registry implementing the OCI distribution spec).

Paths use the form:

acr://<registry>/<repository>:<tag>[/<file>]
acr://<registry>/<repository>@<digest>[/<file>]
acr://<registry>                         (lists the registry's repositories)
acr://<registry>/<repository>            (lists the repository's tags)

Files inside an artifact are its layers; a layer's name is taken from the standard "org.opencontainers.image.title" annotation.

The registry protocol itself is handled by go-containerregistry: manifest resolution, blob transfer, digest verification, auth challenges and token caching all live there rather than being reimplemented here.

Index

Constants

View Source
const Scheme = "acr://"

Scheme is the URI scheme prefix handled by this package.

View Source
const TitleAnnotation = "org.opencontainers.image.title"

TitleAnnotation is the OCI annotation carrying a layer's file name.

Variables

View Source
var ErrArtifactExists = errors.New("acr: destination artifact already exists")

ErrArtifactExists indicates that a tag already exists and overwrite was not requested.

Functions

func DownloadStream

func DownloadStream(ctx context.Context, p Path) (io.ReadCloser, error)

DownloadStream streams the contents of the file referenced by p.

go-containerregistry verifies the blob against its descriptor digest as the stream is read, so a corrupt registry or proxy cannot silently yield different bytes.

func IsDir

func IsDir(ctx context.Context, p Path) (bool, error)

IsDir reports whether p.File addresses a directory within the artifact: either the artifact root, one of the virtual directories synthesised from file names, or a platform of a multi-platform image.

A name that matches a file exactly is decided by an O(1) map lookup, and only an unmatched name falls back to scanning. Downloading an N-file artifact stats every file through here, so a linear scan per file would make the whole transfer quadratic.

func ListRepositories

func ListRepositories(ctx context.Context, p Path) ([]string, error)

ListRepositories returns the repositories a registry holds, from the distribution catalog endpoint.

The result is what the registry reports, including any slashes: ACR namespaces repositories, so "models/llama" is one repository rather than a directory holding another. Each name can be addressed directly as acr://registry/<name>.

func ListTags

func ListTags(ctx context.Context, p Path) ([]string, error)

ListTags returns the tags a repository holds.

func ManifestExists

func ManifestExists(ctx context.Context, p Path) (bool, error)

ManifestExists reports whether p.Reference currently resolves to a manifest.

func Push

func Push(ctx context.Context, p Path, files []UploadFile, opts PushOptions) error

Push publishes files as the layers of a single OCI artifact at p.Reference.

go-containerregistry uploads every blob and only then writes the manifest, so the tag is never left pointing at a partial artifact.

An empty file set publishes an artifact with no layers. That keeps mirror semantics honest: syncing an empty directory, or one whose files are all excluded, must replace the tag rather than leave the previous contents.

func SetHTTPClient

func SetHTTPClient(c *http.Client)

SetHTTPClient installs a process-wide HTTP client used for all requests issued by this package. Passing nil clears the override.

This must be called before any request is issued, e.g. from main's Before: hook, so that all callers observe the override.

func ValidateLocalNames

func ValidateLocalNames(names []string) error

ValidateLocalNames checks that relative file names are portable and can coexist in one local destination tree. It does not contact the registry.

func ValidatePushTarget

func ValidatePushTarget(p Path) error

ValidatePushTarget reports whether p names something that can be published to. Exported so callers such as a dry run can reject an impossible destination without performing the push.

func ValidateUploadNames

func ValidateUploadNames(files []UploadFile) error

ValidateUploadNames checks the names of an artifact's files without contacting the registry, so a dry run rejects exactly what a real push would.

Types

type Entry

type Entry struct {
	Name  string
	Size  int64
	IsDir bool
}

Entry is one child in a directory listing.

func ListDir

func ListDir(ctx context.Context, p Path) ([]Entry, error)

ListDir returns the immediate children of p.File without expanding layers it does not have to.

The root of a multi-platform image is answered from the index alone, so listing it costs one manifest fetch rather than a copy of every layer.

type File

type File struct {
	Name   string
	Size   int64
	Digest string
	// TarPath, when set, is the entry's path inside the tar layer identified
	// by Digest. Empty means the layer is the file.
	TarPath string
	// TarIndex is which occurrence of TarPath this is, since a tar may carry
	// the same path more than once and the last one is the live entry.
	TarIndex int
}

File describes a single file inside an artifact.

A plain artifact stores one file per layer, so Digest identifies the blob to read. For a container image the file lives inside a tar layer instead, and TarPath names it within that layer's archive.

func ListFiles

func ListFiles(ctx context.Context, p Path) ([]File, error)

ListFiles returns the files contained in the artifact referenced by p, including everything inside p.File when it names a directory.

Files inside a container image's tar layers require transferring those layers, so only the ones covering p.File are expanded: listing a single platform of a multi-platform image reads that platform alone.

func Stat

func Stat(ctx context.Context, p Path) (File, error)

Stat returns metadata for the file referenced by p.File.

type HTTPStatusError

type HTTPStatusError struct {
	StatusCode int
	Status     string
	// Codes are the registry's own error codes for the failure. A status on
	// its own does not say what failed: a 404 is final for a manifest that
	// does not exist, but not for a blob upload whose session the registry
	// forgot, which is recovered by starting the upload again.
	Codes []string
}

HTTPStatusError is returned when a registry request fails with a non-2xx status code.

func (*HTTPStatusError) Error

func (e *HTTPStatusError) Error() string

func (*HTTPStatusError) Is

func (e *HTTPStatusError) Is(target error) bool

Is lets a 404 match os.ErrNotExist, so a missing artifact behaves like a missing file inside one.

func (*HTTPStatusError) NotFound

func (e *HTTPStatusError) NotFound() bool

NotFound reports whether the registry answered 404, so callers treating a missing artifact as absent rather than as a failure can recognise it. A lost upload session is excluded: nothing is missing, and the write can be redone.

func (*HTTPStatusError) Recoverable

func (e *HTTPStatusError) Recoverable() bool

Recoverable reports whether the registry named a condition a fresh attempt can get past, despite a status that would otherwise be final.

type Path

type Path struct {
	Registry   string // e.g. myregistry.azurecr.io
	Repository string // e.g. models/llama
	Reference  string // tag (e.g. v1) or digest (e.g. sha256:...)
	File       string // optional file (layer) path within the artifact
}

Path represents an artifact, or a file inside an artifact, in a registry.

func Parse

func Parse(raw string) (Path, error)

Parse parses an acr:// path.

func (Path) ArtifactKey

func (p Path) ArtifactKey() string

ArtifactKey identifies the artifact a path addresses, ignoring any file within it. Equivalent spellings of one endpoint share a key, so callers can detect that two paths target the same artifact.

func (Path) DefaultFilename

func (p Path) DefaultFilename() string

DefaultFilename returns the filename to use when writing this path to a directory.

func (Path) IsRegistry

func (p Path) IsRegistry() bool

IsRegistry reports whether p addresses a whole registry rather than an artifact within it.

func (Path) IsRepository

func (p Path) IsRepository() bool

IsRepository reports whether p addresses a repository without naming a tag or digest, so its children are the repository's tags.

func (Path) String

func (p Path) String() string

type PushOptions

type PushOptions struct {
	Concurrency int
	Overwrite   bool
	// OnProgress receives a layer's file name and how many of its bytes have
	// been uploaded so far in the current attempt. The value is cumulative per
	// layer and can restart at zero, so callers must keep a high-water mark
	// per name rather than summing what they are given.
	OnProgress func(name string, uploaded int64)
}

PushOptions controls publishing an OCI artifact.

type UploadFile

type UploadFile struct {
	Name string
	Size int64
	Open func() (io.ReadCloser, error)
}

UploadFile describes one layer to publish in an OCI artifact. Open must return a fresh reader on every call, because the layer is read more than once (digest calculation, then upload) and to allow retries.

Jump to

Keyboard shortcuts

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