oci

package
v0.18.0 Latest Latest
Warning

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

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

Documentation

Overview

Package oci provides functionality for packaging and pushing artifacts to OCI-compliant registries.

This package enables bundled artifacts to be pushed to any OCI-compliant registry (Docker Hub, GHCR, ECR, local registries, etc.) using the ORAS (OCI Registry As Storage) library. Artifacts are packaged as OCI Image Layout format and can be pushed to remote registries.

Overview

The package provides six main operations:

  • ParseOutputTarget: Parses output targets (file paths or OCI URIs) into Reference
  • Package: Creates a local OCI artifact in OCI Image Layout format
  • PushFromStore: Pushes one required immutable descriptor from a local layout
  • PackageAndPush: Retains layout ownership through remote publication
  • PackageAndPushHelmChart: Publishes an immutable Helm-compatible OCI chart
  • PushReferrer: Publishes a single-blob OCI 1.1 referrer

The Reference type encapsulates parsed output target information, making it easy to determine if output is destined for the local filesystem or an OCI registry.

Core Types

  • Reference: Parsed output target (file path or OCI URI with registry/repository/tag)
  • OutputConfig: Configuration for PackageAndPush workflow
  • HelmChartOptions: Configuration for PackageAndPushHelmChart
  • PackageAndPushResult: Combined result of package and push operations
  • PackageOptions: Configuration for local OCI packaging
  • PackageResult: Result of local packaging (digest, reference, store path)
  • PushOptions: Configuration for pushing to remote registries
  • PushResult: Result of a successful push (digest, reference)
  • ReferrerOptions: Configuration for referrer publication and optional trusted-root exclusions

URI Scheme

OCI output targets use the "oci://" URI scheme:

oci://registry/repository:tag
oci://ghcr.io/nvidia/bundles:v1.0.0
oci://localhost:5000/test/bundle:latest

Local file paths are detected by absence of the oci:// scheme.

Usage

Parse output target and use high-level workflow:

ref, err := oci.ParseOutputTarget("oci://ghcr.io/nvidia/bundle:v1.0.0")
if err != nil {
    return err
}

if ref.IsOCI {
    result, err := oci.PackageAndPush(ctx, oci.OutputConfig{
        Reference: ref,
        SourceDir: "/path/to/bundle",
        OutputDir: "/var/tmp/aicr-oci-layouts",
    })
    if err != nil {
        return err
    }
    defer func() {
        if cleanupErr := os.RemoveAll(result.StorePath); cleanupErr != nil {
            slog.Error("failed to remove OCI layout", "error", cleanupErr)
        }
    }()
}

OutputDir must be an existing real directory outside SourceDir. On success, the returned StorePath is transferred to the caller, which owns its cleanup.

Publish a Helm-compatible chart without modifying its source:

helmRef, err := oci.ParseOutputTarget(
    "oci://ghcr.io/nvidia/my-chart:1.2.3_build.5")
if err != nil {
    return err
}
// Chart.yaml must declare name: my-chart and version: 1.2.3+build.5.
result, err := oci.PackageAndPushHelmChart(ctx, oci.HelmChartOptions{
    Reference:   helmRef,
    SourceDir:   "/path/to/chart",
    OutputDir:   "/var/tmp/aicr-oci-layouts",
    SourceFiles: []string{"Chart.yaml", "values.yaml", "templates/app.yaml"},
    Version:     "v1.0.0", // AICR tool version annotation, not chart SemVer
})
if err != nil {
    return err
}
defer func() {
    if cleanupErr := os.RemoveAll(result.StorePath); cleanupErr != nil {
        slog.Error("failed to remove Helm OCI layout", "error", cleanupErr)
    }
}()

Or use low-level Package and PushFromStore separately:

pkgResult, err := oci.Package(ctx, oci.PackageOptions{
    SourceDir:  "/path/to/bundle",
    OutputDir:  "/path/to/output",
    Registry:   "ghcr.io",
    Repository: "nvidia/bundle",
    Tag:        "v1.0.0",
})
if err != nil {
    return err
}

pushResult, err := oci.PushFromStore(ctx, pkgResult.StorePath, pkgResult.Descriptor, oci.PushOptions{
    Registry:   "ghcr.io",
    Repository: "nvidia/bundle",
    Tag:        "v1.0.0",
})

A successful standalone Package transfers ownership of StorePath to the caller. PackageAndPush and PackageAndPushHelmChart each retain their unique local layout until graph copy, immutable remote-digest verification, and tag update have all succeeded; they remove the layout on failure and transfer StorePath only on success.

PushFromStore requires the exact manifest descriptor. It verifies that root in the local store before invoking any destination operation, copies by descriptor rather than by mutable local tag, verifies the remote digest descriptor, and only then updates the requested remote tag.

Every graph-copy attempt owns a capability-narrow source wrapper. Readers returned by Fetch are tracked, canceled by closing the underlying reader, and synchronously finalized before remote resolve or tag operations. A storage implementation can still block before Exists or Fetch returns, or inside an underlying Close. In particular, cancellation cannot interrupt a filesystem Open that blocks synchronously before returning a file handle. Callers must supply implementations whose own synchronous methods honor their contexts and avoid unresponsive filesystem mounts.

PushReferrer stages its local manifest in a unique private workspace. Callers with trusted local roots set ReferrerOptions.ExcludedRoots so staging fails closed when the configured temporary directory is equal to, below, or a resolved alias of any such root. Store closure and workspace removal are checked before a successful result is returned.

Reference Type

The Reference type represents a parsed output target:

  • IsOCI: True if target is an OCI registry (oci:// scheme)
  • Registry: OCI registry hostname (e.g., "ghcr.io")
  • Repository: Image repository path (e.g., "nvidia/bundle")
  • Tag: Raw Distribution tag (e.g., "1.2.3_build.5")
  • LocalPath: File system path for non-OCI targets

The Reference.WithTag() method returns a copy with the tag modified, useful for applying a default tag when none was specified.

PackageOptions

  • SourceDir: Directory containing artifacts to package
  • OutputDir: Where the OCI Image Layout will be created
  • Registry, Repository, Tag: Image reference components
  • SourceFiles: Nil recursively discovers files; non-nil empty is invalid; non-empty is the exact complete file set
  • SubDir: Valid only with nil SourceFiles; limits discovery while preserving its source-relative prefix

Generic and Helm publication copy the selected regular files into a private stage before packaging and never modify caller source bytes. Explicit paths are canonical slash-relative paths. Helm publication must discover Chart.yaml when SourceFiles is nil; when SourceFiles is non-nil, that exact set must explicitly include Chart.yaml. It also requires the OCI repository basename to equal the chart name, preserves the raw Distribution tag in the registry reference, and requires its strict SemVer form (for example, 1.2.3+build.5 for tag 1.2.3_build.5) in Helm metadata.

PushOptions

  • PlainHTTP: Use HTTP instead of HTTPS (for local development registries)
  • InsecureTLS: Skip TLS certificate verification

Authentication

The package automatically uses Docker credential helpers for authentication. Credentials are loaded from the standard Docker configuration (~/.docker/config.json) using the ORAS credentials package.

Artifact Type

Artifacts are pushed with the media type "application/vnd.nvidia.aicr.artifact". This custom media type identifies AICR bundles and distinguishes them from runnable container images. Consumers that don't understand this type should treat the artifact as a non-executable blob.

Package oci provides utilities for packaging and pushing OCI artifacts.

Index

Constants

View Source
const URIScheme = "oci://"

URIScheme is the URI scheme for OCI registry references (e.g., "oci://ghcr.io/org/repo:tag"). Exported so other packages can build references without re-declaring the literal.

Variables

This section is empty.

Functions

func EnsureScheme added in v0.13.0

func EnsureScheme(ref string) string

EnsureScheme returns ref with the oci:// prefix added when missing. Used by callers that accept user input in either form.

Refs that already carry a different URI scheme (e.g., "https://...") are returned unchanged so callers don't accidentally build "oci://https://..." when handed a non-oci URL by mistake.

func HelmChartVersionFromTag added in v0.18.0

func HelmChartVersionFromTag(tag string) (string, error)

HelmChartVersionFromTag converts a raw Distribution tag into the strict SemVer form Helm stores in Chart.yaml. A single underscore encodes the SemVer build-metadata separator because '+' is not valid in a Distribution tag.

func HelmTagFromChartVersion added in v0.18.0

func HelmTagFromChartVersion(version string) (string, error)

HelmTagFromChartVersion converts a strict Chart.yaml SemVer value into its raw Distribution-tag representation. The SemVer build-metadata separator is encoded as one underscore.

func TrimScheme added in v0.13.0

func TrimScheme(ref string) string

TrimScheme returns ref with any oci:// prefix removed. Useful when emitting a registry/repo:tag form for cosign or for human-readable pointers that don't carry the URI scheme.

Types

type HelmChartOptions added in v0.14.0

type HelmChartOptions struct {
	SourceDir   string
	OutputDir   string
	SourceFiles []string
	Reference   *Reference
	PlainHTTP   bool
	InsecureTLS bool
	Version     string
}

HelmChartOptions configures immutable Helm OCI publication.

type OutputConfig

type OutputConfig struct {
	// SourceDir is the directory containing artifacts to package.
	SourceDir string
	// OutputDir is where temporary OCI artifacts will be created.
	OutputDir string
	// SourceFiles is the complete file set to package. Nil requests recursive
	// discovery; a non-nil empty slice is invalid.
	SourceFiles []string
	// SubDir limits recursive discovery while preserving the path prefix.
	SubDir string
	// Reference contains the parsed OCI registry reference.
	Reference *Reference
	// Version is used for OCI annotations (org.opencontainers.image.version).
	Version string
	// PlainHTTP uses HTTP instead of HTTPS for the registry connection.
	PlainHTTP bool
	// InsecureTLS skips TLS certificate verification.
	InsecureTLS bool
	// Annotations are additional manifest annotations to include.
	// If nil, default AICR annotations will be used.
	Annotations map[string]string
}

OutputConfig configures the OCI package and push workflow.

type PackageAndPushResult

type PackageAndPushResult struct {
	// Digest is the SHA256 digest of the pushed artifact.
	Digest string
	// MediaType is the manifest media type.
	MediaType string
	// Size is the manifest's byte length. Surfaced for OCI Referrers
	// attachment, which needs a full subject descriptor.
	Size int64
	// Reference is the full image reference (registry/repository:tag).
	Reference string
	// StorePath is the path to the local OCI Image Layout directory.
	StorePath string
}

PackageAndPushResult contains the result of a successful package and push operation.

func PackageAndPush

func PackageAndPush(ctx context.Context, cfg OutputConfig) (*PackageAndPushResult, error)

PackageAndPush packages a directory as an OCI artifact and pushes it to a registry. This is a convenience function that combines Package and PushFromStore operations.

func PackageAndPushHelmChart added in v0.14.0

func PackageAndPushHelmChart(ctx context.Context, opts HelmChartOptions) (*PackageAndPushResult, error)

PackageAndPushHelmChart creates a Helm-compatible OCI artifact without modifying Chart.yaml or any other caller source byte.

type PackageOptions

type PackageOptions struct {
	// SourceDir is the directory containing artifacts to package.
	SourceDir string
	// OutputDir is where the OCI Image Layout will be created.
	OutputDir string
	// Registry is the OCI registry host for the reference (e.g., "ghcr.io").
	Registry string
	// Repository is the image repository path (e.g., "nvidia/aicr").
	Repository string
	// Tag is the image tag (e.g., "v1.0.0", "latest").
	Tag string
	// SubDir optionally limits packaging to a subdirectory within SourceDir.
	SubDir string
	// SourceFiles is the complete file set to package. Nil recursively
	// discovers files; a non-nil empty slice is invalid.
	SourceFiles []string
	// Annotations are additional manifest annotations to include.
	// Standard OCI annotations (org.opencontainers.image.*) are recommended.
	Annotations map[string]string
}

PackageOptions configures local OCI packaging.

type PackageResult

type PackageResult struct {
	// Descriptor is the exact immutable manifest descriptor produced locally.
	Descriptor ociv1.Descriptor
	// Digest is the SHA256 digest of the packaged artifact.
	Digest string
	// MediaType is the manifest media type
	// (typically application/vnd.oci.image.manifest.v1+json).
	MediaType string
	// Size is the manifest's byte length. Surfaced so callers can
	// construct an OCI subject descriptor for the Referrers API
	// without re-fetching the manifest from the registry.
	Size int64
	// Reference is the full image reference (registry/repository:tag).
	Reference string
	// StorePath is the path to the OCI Image Layout directory.
	StorePath string
}

PackageResult contains the result of local OCI packaging.

func Package

func Package(ctx context.Context, opts PackageOptions) (*PackageResult, error)

Package creates a local OCI artifact in OCI Image Layout format. This stores the artifact locally without pushing to a remote registry.

type PushOptions

type PushOptions struct {
	// SourceDir is the directory containing artifacts to push.
	SourceDir string
	// Registry is the OCI registry host (e.g., "ghcr.io", "localhost:5000").
	Registry string
	// Repository is the image repository path (e.g., "nvidia/aicr").
	Repository string
	// Tag is the image tag (e.g., "v1.0.0", "latest").
	Tag string
	// PlainHTTP uses HTTP instead of HTTPS for the registry connection.
	PlainHTTP bool
	// InsecureTLS skips TLS certificate verification.
	InsecureTLS bool
}

PushOptions configures the OCI push operation.

type PushResult

type PushResult struct {
	// Digest is the SHA256 digest of the pushed artifact.
	Digest string
	// MediaType is the manifest media type.
	MediaType string
	// Size is the manifest's byte length. Surfaced so the caller can
	// build a subject descriptor for OCI Referrers attachment without
	// re-fetching the manifest.
	Size int64
	// Reference is the full image reference (registry/repository:tag).
	Reference string
}

PushResult contains the result of a successful OCI push.

func PushFromStore

func PushFromStore(
	ctx context.Context,
	storePath string,
	expected ociv1.Descriptor,
	opts PushOptions,
) (*PushResult, error)

PushFromStore pushes an already-packaged OCI artifact from a local OCI store to a remote registry.

func PushReferrer added in v0.13.0

func PushReferrer(ctx context.Context, opts ReferrerOptions) (*PushResult, error)

PushReferrer pushes a single-layer OCI manifest with a Subject set, attaching it as a Referrer of the subject artifact. cosign discovers signatures attached this way via the OCI Distribution 1.1 Referrers API. The tag is derived from the referrer manifest digest so multiple referrers can coexist without colliding on a fixed tag.

type Reference

type Reference struct {
	// IsOCI indicates whether this is an OCI registry reference (true) or local path (false).
	IsOCI bool
	// Registry is the OCI registry host (e.g., "ghcr.io", "localhost:5000").
	// Only populated when IsOCI is true.
	Registry string
	// Repository is the image repository path (e.g., "nvidia/bundle").
	// Only populated when IsOCI is true.
	Repository string
	// Tag is the image tag (e.g., "v1.0.0").
	// Empty string means no tag was specified; caller should apply a default.
	// Only populated when IsOCI is true.
	Tag string
	// LocalPath is the local directory path for non-OCI output.
	// Only populated when IsOCI is false.
	LocalPath string
}

Reference represents a parsed output target, which can be either an OCI registry reference or a local directory path.

func ParseOutputTarget

func ParseOutputTarget(target string) (*Reference, error)

ParseOutputTarget parses an output target string to detect OCI URI or local directory. For OCI URIs (oci://registry/repository:tag), it extracts the components. For plain paths, it treats them as local directories.

If no tag is specified in an OCI URI, Tag will be empty; the caller is responsible for applying a default (e.g., CLI version).

func (*Reference) ChartName added in v0.14.0

func (r *Reference) ChartName() string

ChartName returns the last path segment of Repository, which is the chart name a Helm consumer (or ArgoCD's `source.chart`) sees when pulling the artifact at `registry/repository:tag`. For non-OCI references and references whose Repository is empty, the empty string is returned; callers should treat that as "no derived chart name available" and apply their own default.

Example: oci://ghcr.io/myorg/my-bundle-name:v1

  • Registry = "ghcr.io"
  • Repository = "myorg/my-bundle-name"
  • ChartName() = "my-bundle-name"

This is consumed by the argocd-helm bundler so the generated Chart.yaml and parent Application's `source.chart` match what `helm push` actually publishes — see issue #1019.

func (*Reference) ParentNamespace added in v0.17.0

func (r *Reference) ParentNamespace() string

ParentNamespace returns the OCI registry + repository path with the chart-name segment (last path element) stripped, prefixed with the oci:// scheme. Returns "" for non-OCI references. See #1342.

func (*Reference) String

func (r *Reference) String() string

String returns the full reference string. For OCI references: "oci://registry/repository:tag" (or without tag if empty). For local paths: the local path.

func (*Reference) WithTag

func (r *Reference) WithTag(tag string) *Reference

WithTag returns a copy of the reference with the specified tag. For non-OCI references, returns the same reference unchanged.

type ReferrerOptions added in v0.13.0

type ReferrerOptions struct {
	// Registry is the OCI registry host (e.g., "ghcr.io").
	Registry string
	// Repository is the same repository the subject artifact lives in.
	Repository string
	// PlainHTTP forces HTTP (used for local registry tests).
	PlainHTTP bool
	// InsecureTLS disables TLS verification for self-signed registries.
	InsecureTLS bool

	// ExcludedRoots optionally names existing real directories that referrer
	// staging must remain outside in both lexical and resolved filesystem
	// topology. Evidence publication requires at least one exclusion; generic
	// low-level callers may leave the slice nil when no local trust root exists.
	ExcludedRoots []string

	// ArtifactType identifies the referrer manifest's purpose, e.g.
	// "application/vnd.dev.sigstore.bundle.v0.3+json". The same value
	// is used as the layer media type so a referrer with one blob is
	// self-describing.
	ArtifactType string
	// LayerContent is the single blob the referrer wraps.
	LayerContent []byte

	// Subject is the descriptor of the artifact this referrer points
	// at. cosign's /v2/<name>/referrers/<digest> discovery uses
	// Subject.Digest to match.
	Subject ociv1.Descriptor

	// Annotations apply to the referrer manifest.
	Annotations map[string]string
}

ReferrerOptions configures a single-blob OCI manifest attached via the OCI 1.1 Referrers API. Used by Sigstore Bundle attachment and similar "annotation manifest" patterns where the *referring* manifest is the artifact and the subject points at what it refers to.

type Workspace added in v0.18.0

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

Workspace owns a unique private directory beneath the configured temporary root. Cleanup is anchored to the retained parent root and is checked.

func NewPrivateWorkspace added in v0.18.0

func NewPrivateWorkspace(ctx context.Context, prefix string, excludedRoots ...string) (*Workspace, error)

NewPrivateWorkspace creates a unique 0700 workspace outside excludedRoots.

func (*Workspace) Close added in v0.18.0

func (w *Workspace) Close() error

Close removes the unchanged workspace and returns a cached checked result.

func (*Workspace) Path added in v0.18.0

func (w *Workspace) Path() string

Path returns the workspace path.

Jump to

Keyboard shortcuts

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