importer

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: May 1, 2026 License: Apache-2.0 Imports: 27 Imported by: 0

Documentation

Overview

Package importer reconstructs full container images by applying a diffah delta archive on top of one or more baseline images.

The high-level entry points are Import and DryRun. Both consume an Options value carrying the per-invocation configuration:

  • DeltaPath — filesystem path to the delta archive.
  • Baselines — name → transport-prefixed baseline reference.
  • Outputs — name → transport-prefixed destination reference.
  • Strict — when true, every image in the bundle must have a matching baseline; otherwise unmatched images are skipped with a warning.
  • SystemContext, RetryTimes, RetryDelay — registry / transport configuration threaded into every go.podman.io/image/v5 call.
  • AllowConvert — opt in to manifest media-type conversion when the source and destination disagree (changes every digest).
  • VerifyPubKeyPath, VerifyRekorURL — when VerifyPubKeyPath is non-empty, Import reads .sig (and optionally .rekor.json) sidecars next to DeltaPath and rejects archives whose signature does not match the supplied PEM-encoded ECDSA-P256 public key.

When a baseline reference uses the docker:// transport, only the blobs referenced by patch-encoded entries in the delta cross the wire (lazy fetch). All other baseline blobs are reused from the baseline image source as-is.

Library users typically prefer this package's high-level entry points to invoking the diffah binary; the CLI is a thin wrapper around Import and DryRun.

Package importer error types for apply-side correctness and resilience. These types sit alongside pkg/diff sentinels but are scoped to importer concerns (baseline incompleteness, end-to-end invariant). All implement errs.Categorized → CategoryContent so cmd.Execute renders them with exit code 4.

Package importer — inspect_data derives a per-image detail summary from a parsed sidecar plus the image's target manifest bytes. The output is a pure data structure consumed by cmd/inspect's text and JSON renderers.

Index

Constants

View Source
const (
	FormatDockerArchive = "docker-archive"
	FormatOCIArchive    = "oci-archive"
	FormatDir           = "dir"
)

Variables

This section is empty.

Functions

func Import

func Import(ctx context.Context, opts Options) error

Types

type ApplyImageResult added in v0.2.0

type ApplyImageResult struct {
	ImageName string
	Status    ApplyImageStatus
	Err       error
}

ApplyImageResult is the per-image record in the final ApplyReport. Err is non-nil for every non-OK status and carries the underlying sentinel (ErrMissingPatchSource, ErrMissingBaselineReuseLayer, ErrApplyInvariantFailed, or a transport error) so cmd.Execute can classify it for exit-code mapping.

type ApplyImageStatus added in v0.2.0

type ApplyImageStatus int

ApplyImageStatus is the per-image outcome categorization for the final import summary. Values are mutually exclusive; one is recorded per image in the bundle.

const (
	// ApplyImageOK means composeImage succeeded and verifyApplyInvariant
	// passed.
	ApplyImageOK ApplyImageStatus = iota
	// ApplyImageFailedCompose means composeImage returned an error
	// before producing a complete dest manifest. The dest may be
	// partially populated.
	ApplyImageFailedCompose
	// ApplyImageFailedInvariant means composeImage produced a dest
	// manifest but the post-apply invariant check rejected it. The
	// dest is fully written but does not match the sidecar's
	// expectation.
	ApplyImageFailedInvariant
	// ApplyImageSkippedPreflight means RunPreflight rejected the
	// image upfront (PreflightMissingPatchSource,
	// PreflightMissingReuseLayer, or PreflightError) and partial
	// mode skipped it. The dest was not touched.
	ApplyImageSkippedPreflight
)

type ApplyReport added in v0.2.0

type ApplyReport struct {
	Total   int
	Results []ApplyImageResult
}

ApplyReport is the aggregated outcome of one Import() call. Total counts every image in the bundle (including skipped ones). Results is appended in bundle.sidecar.Images iteration order.

func (ApplyReport) Successful added in v0.2.0

func (r ApplyReport) Successful() int

Successful returns the number of ApplyImageOK results in the report.

type BlobStats added in v0.2.0

type BlobStats struct {
	FullCount  int
	PatchCount int
	FullBytes  int64
	PatchBytes int64
}

type DryRunReport

type DryRunReport struct {
	Feature       string
	Version       string
	Tool          string
	ToolVersion   string
	CreatedAt     time.Time
	Platform      string
	Images        []ImageDryRun
	Blobs         BlobStats
	ArchiveBytes  int64
	RequiresZstd  bool
	ZstdAvailable bool
}

func DryRun

func DryRun(ctx context.Context, opts Options) (DryRunReport, error)

type ErrApplyInvariantFailed added in v0.2.0

type ErrApplyInvariantFailed struct {
	ImageName  string
	Missing    []digest.Digest
	Unexpected []digest.Digest
	Reason     string
}

ErrApplyInvariantFailed — Stage 3 end-to-end check rejected the dest's reconstructed manifest. Populated by Phase 2; declared here so all importer correctness errors live in one file.

func (*ErrApplyInvariantFailed) Category added in v0.2.0

func (e *ErrApplyInvariantFailed) Category() errs.Category

func (*ErrApplyInvariantFailed) Error added in v0.2.0

func (e *ErrApplyInvariantFailed) Error() string

func (*ErrApplyInvariantFailed) NextAction added in v0.2.0

func (*ErrApplyInvariantFailed) NextAction() string

type ErrMissingBaselineReuseLayer added in v0.2.0

type ErrMissingBaselineReuseLayer struct {
	ImageName   string
	LayerDigest digest.Digest
}

ErrMissingBaselineReuseLayer (B2) — baseline lacks a layer that the target manifest references but the delta did not ship.

func (*ErrMissingBaselineReuseLayer) Category added in v0.2.0

func (*ErrMissingBaselineReuseLayer) Error added in v0.2.0

func (*ErrMissingBaselineReuseLayer) NextAction added in v0.2.0

func (*ErrMissingBaselineReuseLayer) NextAction() string

type ErrMissingPatchSource added in v0.2.0

type ErrMissingPatchSource struct {
	ImageName       string
	ShippedDigest   digest.Digest
	PatchFromDigest digest.Digest
}

ErrMissingPatchSource (B1) — baseline lacks the patch source layer that a shipped patch blob requires for zstd --patch-from reconstruction.

func (*ErrMissingPatchSource) Category added in v0.2.0

func (e *ErrMissingPatchSource) Category() errs.Category

func (*ErrMissingPatchSource) Error added in v0.2.0

func (e *ErrMissingPatchSource) Error() string

func (*ErrMissingPatchSource) NextAction added in v0.2.0

func (*ErrMissingPatchSource) NextAction() string

type ImageDryRun added in v0.2.0

type ImageDryRun struct {
	Name                   string
	BaselineManifestDigest digest.Digest
	TargetManifestDigest   digest.Digest
	BaselineProvided       bool
	WouldImport            bool
	SkipReason             string
	LayerCount             int
	ArchiveLayerCount      int
	BaselineLayerCount     int // layers not present in the archive (sourced from baseline)
	PatchLayerCount        int
}

type InspectImageDetail added in v0.2.0

type InspectImageDetail struct {
	Name              string
	ManifestDigest    digest.Digest
	LayerCount        int // total layers in target manifest
	ArchiveLayerCount int // layers shipped (Full + Patch); LayerCount − len(BaselineOnly)
	Layers            []LayerRow
	Waste             []WasteEntry
	TopSavings        []TopSaving
	Histogram         SizeHistogram
}

InspectImageDetail is the full per-image enrichment produced by BuildInspectImageDetail.

func BuildInspectImageDetail added in v0.2.0

func BuildInspectImageDetail(sc *diff.Sidecar, img diff.ImageEntry, manifestBytes []byte) (InspectImageDetail, error)

BuildInspectImageDetail derives the per-image detail block from a parsed sidecar, the image's entry within it, and that image's target manifest bytes (the canonical bytes whose digest matches img.Target.ManifestDigest).

Pure: no I/O. Returns a wrapped error if the manifest cannot be parsed (e.g., manifest list / index, malformed JSON, unsupported media type).

type LayerRef added in v0.2.0

type LayerRef struct {
	Digest digest.Digest
	Size   int64
}

LayerRef is a (digest, size) pair extracted from a manifest's layers list.

type LayerRow added in v0.2.0

type LayerRow struct {
	Digest      digest.Digest
	Kind        LayerRowKind
	TargetSize  int64
	ArchiveSize int64         // 0 for baseline_only
	PatchFrom   digest.Digest // empty unless Kind == Patch
}

LayerRow describes one row of the per-image layer table.

func (LayerRow) Ratio added in v0.2.0

func (r LayerRow) Ratio() float64

Ratio is archive_size / target_size. Returns 0 when TargetSize is 0 or for baseline-only rows. Used for the "(0.06× — patch …)" column.

func (LayerRow) SavedBytes added in v0.2.0

func (r LayerRow) SavedBytes() int64

SavedBytes is target_size − archive_size. Baseline-only layers count as full savings (target_size).

func (LayerRow) SavedRatio added in v0.2.0

func (r LayerRow) SavedRatio() float64

SavedRatio is SavedBytes / TargetSize. Returns 0 when TargetSize is 0.

type LayerRowKind added in v0.2.0

type LayerRowKind string

LayerRowKind classifies a target-manifest layer by how it was shipped.

const (
	LayerKindFull         LayerRowKind = "full"          // shipped as Full encoding
	LayerKindPatch        LayerRowKind = "patch"         // shipped as Patch encoding (intra-layer)
	LayerKindBaselineOnly LayerRowKind = "baseline_only" // not shipped; reused from baseline
)

type Options

type Options struct {
	DeltaPath        string
	Baselines        map[string]string // transport-prefixed refs
	Outputs          map[string]string // transport-prefixed dest refs
	Strict           bool
	SystemContext    *types.SystemContext
	AllowConvert     bool
	RetryTimes       int           // default 0 = no retry; applied to baseline manifest+source open
	RetryDelay       time.Duration // zero means exponential backoff (capped by withRetry)
	ProgressReporter progress.Reporter
	// Deprecated: use ProgressReporter. Will be removed in v0.4.
	Progress io.Writer
	Probe    func(context.Context) (bool, string)
	// VerifyPubKeyPath enables signature verification when non-empty.
	// The file at this path must hold a PEM-encoded ECDSA-P256 PKIX
	// public key. When empty, Import does not read any .sig / .cert /
	// .rekor.json sidecar files — signed archives are processed
	// byte-identically to unsigned ones.
	VerifyPubKeyPath string
	// VerifyRekorURL is the Rekor transparency-log URL against which
	// an accompanying .rekor.json inclusion proof is checked. Only
	// consulted when .rekor.json is present; missing bundle does not
	// fail the verify.
	VerifyRekorURL string
}

type PreflightResult added in v0.2.0

type PreflightResult struct {
	ImageName           string
	Status              PreflightStatus
	MissingPatchSources []digest.Digest
	MissingReuseLayers  []digest.Digest
	Err                 error
}

PreflightResult is the per-image outcome of a preflight scan. The MissingPatchSources and MissingReuseLayers slices are populated independently so a single image may report both classes of missing digests; Status records the dominant category for routing.

func RunPreflight added in v0.2.0

func RunPreflight(
	ctx context.Context,
	bundle *extractedBundle,
	resolved []resolvedBaseline,
	reporter progress.Reporter,
) ([]PreflightResult, bool, error)

RunPreflight scans every image in the bundle against its resolved baseline and returns per-image results plus an aggregate failure flag. A PreflightSchemaError on any image is fatal and surfaces via the err return value (regardless of strict/partial mode), because an unparseable target manifest indicates a corrupt or unsupported delta. Other non-OK statuses are recorded in the result slice for the caller (Import) to route on.

type PreflightStatus added in v0.2.0

type PreflightStatus int

PreflightStatus classifies the outcome of scanning a single image's baseline against what its delta requires. PreflightOK means every baseline-only-reuse layer and every patch source layer the delta references is present in the baseline manifest. The other statuses are mutually exclusive failure categories suitable for a final summary report.

const (
	// PreflightOK indicates the baseline contains every required digest
	// and the delta can be applied without further fetches beyond the
	// archive's own blobs.
	PreflightOK PreflightStatus = iota
	// PreflightMissingPatchSource (B1) — the delta ships at least one
	// patch blob whose patch_from_digest is absent from the baseline.
	// Apply cannot reconstruct the patched layer.
	PreflightMissingPatchSource
	// PreflightMissingReuseLayer (B2) — the target manifest references
	// a layer the delta did not ship and the baseline does not contain.
	// Apply cannot satisfy that layer from any source.
	PreflightMissingReuseLayer
	// PreflightError covers transport / I/O failures encountered during
	// the scan itself (baseline manifest fetch failure, etc.). Not a
	// content classification — partial mode treats it the same as a
	// missing-baseline skip; strict mode aborts.
	PreflightError
	// PreflightSchemaError is a fatal classification: the bundle's own
	// target manifest could not be parsed. Returned to the caller as a
	// hard error regardless of strict/partial mode.
	PreflightSchemaError
)

func (PreflightStatus) String added in v0.2.0

func (s PreflightStatus) String() string

String returns a human-readable label for the status. Used by slog structured logging and the final summary renderer.

type SizeHistogram added in v0.2.0

type SizeHistogram struct {
	Buckets []string
	Counts  []int
}

SizeHistogram is the five-bucket log-scale distribution of LayerRow target sizes. Buckets and Counts have identical length and bucket order.

type TopSaving added in v0.2.0

type TopSaving struct {
	Digest     digest.Digest
	SavedBytes int64
	SavedRatio float64 // [0.0, 1.0]
}

TopSaving is one ranked saving in the top-10 list.

type WasteEntry added in v0.2.0

type WasteEntry struct {
	Kind        WasteKind
	Digest      digest.Digest
	ArchiveSize int64
	TargetSize  int64
}

WasteEntry is one detected waste row.

type WasteKind added in v0.2.0

type WasteKind string

WasteKind tags a single waste-detection category. v1 has only patch_oversized.

const WasteKindPatchOversized WasteKind = "patch_oversized"

Jump to

Keyboard shortcuts

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