Documentation
¶
Overview ¶
Package cloudimg streams OCI-packaged cloud images out of an Epoch registry and into `cocoon image import`.
A cloud image in epoch is an OCI 1.1 image manifest with artifactType `application/vnd.cocoonstack.os-image.v1+json`. Layers carry one or more disk parts (mediaType vnd.cocoonstack.disk.qcow2 or .raw, including the `.part` split variants the windows builder uses). Non-disk layers like `text/plain` SHA256SUMS are skipped on stream.
Pushing cloud images to epoch is the upstream publisher's job — `oras push` / `crane copy` from cocoonstack/windows or cocoonstack/cocoon CI workflows. epoch only handles the read side: streaming the assembled disk to cocoon (or to stdout for `epoch get`).
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Stream ¶
Stream concatenates the disk layers of a cloud image manifest to w in the order required for reassembly: layers with disk mediaType are sorted by their `org.opencontainers.image.title` annotation lexicographically (which is what `split -d --additional-suffix` already produces). Layers with non-disk mediaTypes (e.g. text/plain SHA256SUMS) are skipped.
Stream writes directly to w with no buffering, so a destination that supports splice (raw os.File, exec stdin pipe, http.ResponseWriter) gets the zero-copy fast path. Cloud image disks can be tens of GiB; the buffer avoidance is intentional.
Stream returns an error if the manifest is not classified as a cloud image or contains zero disk layers.
func StreamParsed ¶
func StreamParsed(ctx context.Context, m *manifest.OCIManifest, blobs BlobReader, w io.Writer) error
StreamParsed is the same as Stream but accepts an already-parsed manifest. Callers that have already classified and parsed (e.g. the /dl/ handler) use this to avoid a redundant JSON unmarshal on multi-GiB download hot paths.
Types ¶
type BlobReader ¶
type BlobReader interface {
// ReadBlob fetches a blob by its OCI digest (with sha256: prefix).
ReadBlob(ctx context.Context, digest string) (io.ReadCloser, error)
}
BlobReader is the minimal blob-fetch interface needed by Stream. Both the in-process registry and an HTTP registry client implement it via adapter types defined by their respective callers.
type CocoonRunner ¶
type CocoonRunner interface {
ImageImport(ctx context.Context, name string) (io.WriteCloser, func() error, error)
}
CocoonRunner abstracts how Puller invokes the cocoon CLI for image import. `*snapshot.ExecCocoon` satisfies this interface via its ImageImport method (via the ExecCocoonAdapter helper below).
type Downloader ¶
type Downloader interface {
GetManifest(ctx context.Context, name, tag string) ([]byte, string, error)
GetBlob(ctx context.Context, name, digest string) (io.ReadCloser, error)
}
Downloader fetches manifests and blobs from an OCI registry. Defined locally (not borrowed from another package) so cloudimg has no sibling-package dependency.
type PullOptions ¶
type PullOptions struct {
// Name is the OCI repository name. Required.
Name string
// Tag is the OCI tag. Defaults to "latest".
Tag string
// LocalName overrides the cocoon-side image name on import. Empty
// means reuse Name.
LocalName string
}
PullOptions configures a cloud-image pull.
type Puller ¶
type Puller struct {
Downloader Downloader
Cocoon CocoonRunner
}
Puller fetches an OCI cloud-image artifact and pipes the assembled disk into `cocoon image import`.
func (*Puller) Pull ¶
func (p *Puller) Pull(ctx context.Context, opts PullOptions) error
Pull downloads a cloud-image artifact and pipes its concatenated disk layers into `cocoon image import`.
Streaming errors close the cocoon stdin pipe so the import process exits cleanly; the original streaming error wins over the downstream wait error.