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
- Variables
- func DownloadStream(ctx context.Context, p Path) (io.ReadCloser, error)
- func IsDir(ctx context.Context, p Path) (bool, error)
- func ListRepositories(ctx context.Context, p Path) ([]string, error)
- func ListTags(ctx context.Context, p Path) ([]string, error)
- func ManifestExists(ctx context.Context, p Path) (bool, error)
- func Push(ctx context.Context, p Path, files []UploadFile, opts PushOptions) error
- func SetHTTPClient(c *http.Client)
- func ValidateLocalNames(names []string) error
- func ValidatePushTarget(p Path) error
- func ValidateUploadNames(files []UploadFile) error
- type Entry
- type File
- type HTTPStatusError
- type Path
- type PushOptions
- type UploadFile
Constants ¶
const Scheme = "acr://"
Scheme is the URI scheme prefix handled by this package.
const TitleAnnotation = "org.opencontainers.image.title"
TitleAnnotation is the OCI annotation carrying a layer's file name.
Variables ¶
var ErrArtifactExists = errors.New("acr: destination artifact already exists")
ErrArtifactExists indicates that a tag already exists and overwrite was not requested.
Functions ¶
func DownloadStream ¶
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 ¶
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 ¶
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 ManifestExists ¶
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 ¶
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 ¶
ValidateLocalNames checks that relative file names are portable and can coexist in one local destination tree. It does not contact the registry.
func ValidatePushTarget ¶
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 ¶
Entry is one child in a directory listing.
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 ¶
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.
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 (Path) ArtifactKey ¶
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 ¶
DefaultFilename returns the filename to use when writing this path to a directory.
func (Path) IsRegistry ¶
IsRegistry reports whether p addresses a whole registry rather than an artifact within it.
func (Path) IsRepository ¶
IsRepository reports whether p addresses a repository without naming a tag or digest, so its children are the repository's tags.
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.