oci

package
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Aug 17, 2026 License: MIT Imports: 19 Imported by: 0

Documentation

Overview

Package oci writes small, deterministic OCI image layouts without a daemon.

Index

Constants

View Source
const (
	CategoryToolchain    = "toolchain"
	CategoryDependencies = "dependencies"
	CategoryApplication  = "application"
	CategoryMetadata     = "metadata"
)

Semantic layer categories for Options.SemanticLayers, applied in this fixed order so layer order is deterministic regardless of input order.

Variables

This section is empty.

Functions

func Build

func Build(opts Options) (string, error)

Build writes an OCI Image Layout and returns the digest of its manifest.

func LabelsFromPairs

func LabelsFromPairs(pairs []string) (map[string]string, error)

LabelsFromPairs parses key=value labels and rejects ambiguous input.

Types

type BuildConfig

type BuildConfig struct {
	Entrypoint    string            `json:"entrypoint"`
	Profile       string            `json:"profile,omitempty"`
	Args          []string          `json:"args,omitempty"`
	WorkingDir    string            `json:"working_dir,omitempty"`
	Env           map[string]string `json:"env,omitempty"`
	User          string            `json:"user,omitempty"`
	Home          string            `json:"home,omitempty"`
	IdentityFiles bool              `json:"identity_files,omitempty"`
	SystemFiles   SystemFiles       `json:"system_files,omitempty"`
	Ports         []string          `json:"ports,omitempty"`
	Volumes       []string          `json:"volumes,omitempty"`
	WritablePaths []string          `json:"writable_paths,omitempty"`
	Healthcheck   *Healthcheck      `json:"healthcheck,omitempty"`
	// SemanticLayers requests one layer per semantic category (toolchain,
	// dependencies, application, metadata) instead of the default single
	// layer. It changes layer digests, never filesystem content.
	SemanticLayers bool `json:"semantic_layers,omitempty"`
}

BuildConfig is the strict declarative runtime contract accepted by oci-builder -config. Unknown JSON fields are rejected to prevent silent configuration drift.

func LoadBuildConfig

func LoadBuildConfig(filename string) (BuildConfig, error)

func (BuildConfig) Validate

func (c BuildConfig) Validate() error

type Event

type Event struct {
	Time      time.Time      `json:"time"`
	Level     string         `json:"level"`
	Component string         `json:"component"`
	Operation string         `json:"operation"`
	Phase     string         `json:"phase"`
	TraceID   string         `json:"trace_id,omitempty"`
	Message   string         `json:"message"`
	Duration  time.Duration  `json:"-"`
	Fields    map[string]any `json:"fields,omitempty"`
}

Event is a structured, non-secret observation of an OCI build phase.

type ExtraFile

type ExtraFile struct {
	// Dest is the absolute, clean container path this file is written to.
	Dest string
	// Source is the host path its content is read from at build time.
	Source string
	// Mode defaults to 0555 for executable ELF dependencies. Declarative
	// system data uses 0444.
	Mode int64
	// Category groups this file into a semantic layer when
	// Options.SemanticLayers is set; ignored otherwise. Empty defaults to
	// CategoryApplication.
	Category string
}

ExtraFile places an additional file in the layer at a fixed container path, alongside the entrypoint - how a dynamically-linked binary is packaged (its ELF interpreter and shared libraries, e.g. found via ldd, each as one ExtraFile). Every extra file is written 0555: the ELF interpreter specifically is loaded by the kernel's own execve(), which requires the execute bit, unlike an ordinary library dlopen'd via userspace mmap().

func ExtraFilesFromPairs

func ExtraFilesFromPairs(pairs []string) ([]ExtraFile, error)

ExtraFilesFromPairs parses "[CATEGORY@]/container/path=host/path" pairs (as passed via repeated -extra-file flags) into ExtraFiles, and rejects ambiguous or colliding input. The optional CATEGORY prefix assigns the file to a semantic layer (toolchain, dependencies, application or metadata) and only takes effect when Options.SemanticLayers is set. It only validates the pair's string shape, category name and destination-path syntax; Build validates that each Source actually exists and is a regular file, since that requires filesystem access.

type Healthcheck

type Healthcheck struct {
	Command  []string `json:"command"`
	Interval string   `json:"interval,omitempty"`
	Timeout  string   `json:"timeout,omitempty"`
	Retries  int      `json:"retries,omitempty"`
}

type Options

type Options struct {
	Binary        string
	Output        string
	Architecture  string
	OS            string
	Entrypoint    string
	Profile       string
	ImageName     string
	Tag           string
	Created       time.Time
	Labels        map[string]string
	ExtraFiles    []ExtraFile
	Args          []string
	WorkingDir    string
	Env           map[string]string
	User          string
	Home          string
	IdentityFiles bool
	Ports         []string
	Volumes       []string
	WritablePaths []string
	Healthcheck   *Healthcheck
	// Compression selects deterministic gzip compression: "best" preserves
	// the historical output, while "fast" is intended for very large images.
	Compression string
	// SemanticLayers splits the image into one layer per non-empty
	// ExtraFile.Category (in a fixed toolchain/dependencies/application/
	// metadata order) instead of the default single layer. Off by default:
	// every existing caller that leaves this unset gets byte-for-byte the
	// same single-layer output as before this field existed.
	SemanticLayers bool
	// TraceID correlates build events across the CLI and CI. It is metadata
	// only and is never written into the reproducible OCI layout.
	TraceID string
	// Observer receives structured lifecycle events. Callers must avoid
	// logging sensitive file contents; this package reports paths, sizes,
	// phases, durations, and digests only.
	Observer func(Event)
	// ExtraLayers are paths to pre-built, uncompressed tar files
	// contributed by external plugins (see plugins/lang-* and
	// docs/language-plugin-layers.md) - a Python interpreter and its
	// installed packages, for example. Each becomes its own manifest
	// layer, appended after every ExtraFiles-derived layer, in the given
	// order. See extralayers.go: every entry is independently validated
	// (clean relative paths, no traversal, no symlinks/hardlinks/devices,
	// bounded size) - a plugin's own claims about its content are never
	// trusted, only what Build itself parses and re-hashes.
	ExtraLayers []string
	// Budget, if non-zero, bounds this Build call's own wall-clock time,
	// CPU time, and heap memory - the whole-process resources
	// internal/budget.Tracker measures via RUSAGE_SELF/runtime.MemStats.
	// Build never spawns child processes, so unlike a sandboxed pipeline
	// stage (whose resources are already bounded by internal/executor's
	// per-process rlimits/cgroups and are invisible to this process's own
	// accounting), this budget correctly reflects the actual build work.
	// Checked once per streamed file; the zero value disables enforcement.
	Budget budget.Budget
}

Options describes the image to create. Binary must name a regular executable file. Output must not already exist; this prevents accidentally replacing an image layout with attacker-controlled contents.

type SystemFiles

type SystemFiles struct {
	CACertificates string `json:"ca_certificates,omitempty"`
	Timezone       string `json:"timezone,omitempty"`
	LocaleArchive  string `json:"locale_archive,omitempty"`
}

Jump to

Keyboard shortcuts

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