docker

package
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: Apr 4, 2026 License: AGPL-3.0, AGPL-3.0-only Imports: 32 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BuildCacheFlags added in v0.5.0

func BuildCacheFlags(cfg config.BuildCacheConfig, repoID, branch string, targets []config.TargetConfig) (cacheFrom, cacheTo []build.CacheRef)

BuildCacheFlags computes --cache-from and --cache-to flags from config. Does NOT determine hits/misses — that's the executor's job after probing.

Invariants enforced here:

  • Fallback never in cache-to (read-only)
  • Ref canonicalization: normalized prefix + hash suffix
  • Precedence ordering: local before external in cache-from list

func BuilderName added in v0.5.0

func BuilderName(repoID string) string

BuilderName returns a deterministic, repo-scoped builder name. Prevents cross-repo cache pollution on shared DinD.

func CanonicalizeRef added in v0.5.0

func CanonicalizeRef(s string) string

CanonicalizeRef normalizes a repo or branch name for registry ref construction. Uses a normalized prefix (lowercase, safe chars) plus a hash suffix to prevent collisions. "feature/a-b" and "feature-a/b" produce different refs because the hash includes the original.

func CleanupCrucibleImages

func CleanupCrucibleImages(ctx context.Context, tags ...string) error

CleanupCrucibleImages removes temporary crucible images. Best-effort; errors are returned but should never downgrade a successful crucible result. Does not use --force to avoid removing images that a user may have manually tagged from the crucible output.

func CosignAttest

func CosignAttest(ctx context.Context, digestRef, predicatePath, keyPath string) error

CosignAttest attests a predicate against an image digest ref using cosign. The digestRef must be in the form repo@sha256:... — tags are never used.

func CosignAvailable

func CosignAvailable() bool

CosignAvailable returns true if cosign is on PATH.

func CosignSign

func CosignSign(ctx context.Context, digestRef, keyPath string, multiArch bool) error

CosignSign signs an image digest ref using cosign. The digestRef must be in the form repo@sha256:... — tags are never used.

func CrucibleTag

func CrucibleTag(purpose, runID string) string

CrucibleTag returns a namespaced temporary image tag for crucible. Uses stagefreight/crucible-* namespace to prevent accidental pushes.

func ImageBinaryHash

func ImageBinaryHash(ctx context.Context, image string) (string, error)

ImageBinaryHash extracts the sha256 hash of /usr/local/bin/stagefreight from a local docker image.

func ImageDigest

func ImageDigest(ctx context.Context, image string) (string, error)

ImageDigest returns the local image ID (config digest) via docker inspect.

func ImageEnvFingerprint

func ImageEnvFingerprint(ctx context.Context, image string) (string, error)

ImageEnvFingerprint returns an informational hash of the execution environment inside a docker image. Non-authoritative.

func ImageLabel

func ImageLabel(ctx context.Context, image, label string) (string, error)

ImageLabel reads a specific OCI label from a local image via docker inspect.

func ImageVersion

func ImageVersion(ctx context.Context, image string) (string, error)

ImageVersion extracts the stagefreight version string from a local docker image.

func IsMultiPlatform

func IsMultiPlatform(step build.BuildStep) bool

IsMultiPlatform returns true if the step targets more than one platform. Multi-platform builds cannot use --load (buildx limitation).

func IsSFCacheTag added in v0.5.0

func IsSFCacheTag(tag, scopePrefix string) bool

IsSFCacheTag validates that a tag string matches StageFreight's deterministic cache naming pattern for the given scope prefix. Uses ParseCacheTag internally.

func LocalCacheAvailable added in v0.5.0

func LocalCacheAvailable(repoID string, cfg config.LocalCacheConfig) bool

LocalCacheAvailable checks if the local cache path is writable. Creates the full directory tree if it doesn't exist. The volume mount shadows the image's directory, so we can't assume any structure exists.

func LocalCacheDir added in v0.5.0

func LocalCacheDir(repoID string, cfg config.LocalCacheConfig) string

LocalCacheDir resolves the local cache directory. Default: /stagefreight/cache/buildkit/<repo-hash> (persistent runtime root). Falls back to config override if set. Never uses /tmp.

func ParseBuildxOutput

func ParseBuildxOutput(output string) []build.LayerEvent

ParseBuildxOutput parses captured buildx --progress=plain output into layer events. Only meaningful build layers are returned (FROM, COPY, RUN, etc.). Internal steps (load build definition, load .dockerignore, metadata) are filtered out.

func ParseBuildxPublished added in v0.5.0

func ParseBuildxPublished(metadataFile string, registries []build.RegistryTarget) ([]artifact.PublishedImage, error)

ParseBuildxPublished extracts structured publish records from a buildx metadata file. This is the authoritative source: buildx writes the actual pushed refs + digest to the metadata file after a successful push. Works for both docker-container and remote (buildkitd) drivers.

Metadata JSON format:

{"containerimage.digest": "sha256:...", "image.name": "host/path:tag,host2/path:tag,..."}

func ParseMetadataDigest

func ParseMetadataDigest(metadataFile string) (string, error)

ParseMetadataDigest parses the digest from a buildx --metadata-file JSON output.

func RenderBuildError added in v0.5.0

func RenderBuildError(sec *output.Section, stderr string)

RenderBuildError extracts and renders structured error entries from Docker build stderr. Shared between execute.go and crucible.go — one failure rendering contract.

Three-layer guarantee:

  1. Structured parse (best) — file, line, tool, message
  2. Generic parse (ok) — error line with partial metadata
  3. Raw fallback (always works) — last N lines, never empty

The fallback MUST NEVER be removed. It is the guarantee that errors are always visible.

func RenderBuilderInfo added in v0.5.0

func RenderBuilderInfo(w io.Writer, color bool, info BuilderInfo)

RenderBuilderInfo prints structured builder state. Falls back to raw output if parsing failed.

func RenderCacheInfo added in v0.5.0

func RenderCacheInfo(w io.Writer, color bool, info CacheInfo)

RenderCacheInfo prints structured cache resolution output. Called from execute.go — cache.go only resolves, execute.go renders.

func ResolveCosignKey

func ResolveCosignKey() string

ResolveCosignKey finds the cosign signing key path. Checks COSIGN_KEY env var first, then .stagefreight/cosign.key.

func ResolveDigest

func ResolveDigest(ctx context.Context, ref string) (string, error)

ResolveDigest queries the registry for the manifest digest of a pushed image.

func ResolveLocalDigest

func ResolveLocalDigest(ctx context.Context, ref string) (string, error)

ResolveLocalDigest extracts the pushed digest from a locally loaded image via docker inspect RepoDigests. This is a fallback for when buildx imagetools inspect can't reach the registry. Only returns a digest that matches the requested ref's registry/path to prevent cross-ref confusion.

func Run

func Run(req Request) error

Run is the entry point for docker build orchestration. It replaces the former runDockerBuild cobra handler body.

Types

type ArgDecl

type ArgDecl struct {
	Name    string
	Default string
	Line    string // original instruction text
}

ArgDecl holds a parsed Dockerfile ARG with its default value.

type Backend added in v0.5.0

type Backend struct {
	Kind     string // "buildkitd" or "dind"
	Endpoint string // e.g., "tcp://buildkitd:1234" or "tcp://dind:2376"
	CertPath string // TLS cert directory
	Healthy  bool
}

Backend represents a resolved build execution backend.

func ResolveBackend added in v0.5.0

func ResolveBackend(caps BackendCapabilities) (*Backend, error)

ResolveBackend selects the best backend for the given operation. Default: prefer buildkitd (persistent cache) → fall back to DinD. Config override: "buildkitd" forces buildkitd (fail if unavailable), "dind" forces DinD (ignore buildkitd even if available).

Returns the resolved backend. Callers should not mix backends within a single operation — use the returned backend for everything.

func ResolveBackendWithConfig added in v0.5.0

func ResolveBackendWithConfig(caps BackendCapabilities, configBackend string) (*Backend, error)

ResolveBackendWithConfig selects backend with explicit config override.

func (*Backend) IsBuildkit added in v0.5.0

func (b *Backend) IsBuildkit() bool

IsBuildkit returns true if this backend is a persistent buildkitd.

type BackendCapabilities added in v0.5.0

type BackendCapabilities struct {
	Build      bool // needs image build
	Run        bool // needs container execution (docker run)
	Push       bool // needs registry push
	Filesystem bool // needs shared filesystem with job container
}

BackendCapabilities describes what an operation requires.

type BuildErrorEntry added in v0.5.0

type BuildErrorEntry struct {
	File    string // source file (e.g. "src/k8s/discovery.go")
	Line    int    // line number (0 if unknown)
	Col     int    // column (0 if unknown)
	Tool    string // go, docker, process, generic
	Message string // the error message
	Raw     string // original unparsed line (for fallback rendering)
}

BuildErrorEntry is a structured, parsed build error. Parsed once, rendered from metadata — no string guessing at render time.

func ParseBuildErrors added in v0.5.0

func ParseBuildErrors(stderr string) ([]BuildErrorEntry, []string)

ParseBuildErrors extracts structured error entries from Docker build stderr. Early exit once maxErrorEntries found — Docker builds can hit 1k+ lines.

type BuilderInfo added in v0.5.0

type BuilderInfo struct {
	Name              string
	Driver            string
	Status            string // "running", "stopped", "not found"
	Action            string // "reused", "created"
	BuildKit          string // version
	Platforms         string
	Endpoint          string
	BootstrapOK       bool
	BootstrapDuration time.Duration
	GCRules           []GCRule
	RawOutput         string // fallback if parsing fails
	ParseFailed       bool
}

BuilderInfo holds structured builder state for narration.

func EnsureBuilder added in v0.5.0

func EnsureBuilder(cfg config.BuilderConfig) BuilderInfo

EnsureBuilder creates the Docker context and buildx builder from config, bootstraps it, and writes builder.json. This is the single authority for builder lifecycle — the skeleton is transport only (env vars + DinD service).

func EnsureBuilderWithBackend added in v0.5.0

func EnsureBuilderWithBackend(cfg config.BuilderConfig, backend *Backend) BuilderInfo

EnsureBuilderWithBackend creates a builder using the given backend. If backend is nil, resolves one automatically.

func ResolveBuilderInfo added in v0.5.0

func ResolveBuilderInfo(info BuilderInfo) BuilderInfo

ResolveBuilderInfo inspects the active builder and returns structured facts. Read-only — does NOT create or bootstrap. Call EnsureBuilder first.

type BuildkitPruneResult added in v0.5.0

type BuildkitPruneResult struct {
	Builder     string
	MaxAge      string // filter applied (human, e.g. "168h")
	KeepBytes   int64  // --keep-storage value in bytes
	Command     string // exact command executed
	Output      string // raw buildx output
	Reclaimed   string // parsed reclaimed amount, or "0 B"
	UsageBefore string // from buildx du before prune
	UsageAfter  string // from buildx du after prune
	Duration    time.Duration
	Error       error
	Skipped     bool
	SkipReason  string
}

BuildkitPruneResult records what buildx prune did.

type Buildx

type Buildx struct {
	Verbose bool
	Stdout  io.Writer
	Stderr  io.Writer
}

Buildx wraps docker buildx commands.

func NewBuildx

func NewBuildx(verbose bool) *Buildx

NewBuildx creates a Buildx runner with default output writers.

func (*Buildx) Build

func (bx *Buildx) Build(ctx context.Context, step build.BuildStep) (*build.StepResult, error)

Build executes a single build step via docker buildx. When ParseLayers is true, buildx runs with --progress=plain and the output is parsed into layer events for structured display.

func (*Buildx) BuildWithLayers

func (bx *Buildx) BuildWithLayers(ctx context.Context, step build.BuildStep) (*build.StepResult, []build.LayerEvent, error)

BuildWithLayers executes a build step and parses the output for layer events. Uses --progress=plain to get parseable output. The original Stdout/Stderr writers receive the raw output; layer events are parsed from the stderr copy.

func (*Buildx) EnsureBuilder

func (bx *Buildx) EnsureBuilder(ctx context.Context) error

EnsureBuilder checks that a buildx builder is available and creates one if needed.

func (*Buildx) Login

func (bx *Buildx) Login(ctx context.Context, registries []build.RegistryTarget) error

Login authenticates to registries that have a credentials label configured. The Credentials field on each RegistryTarget is a user-chosen env var prefix:

credentials: DOCKERHUB_PRPLANIT  →  DOCKERHUB_PRPLANIT_USER / DOCKERHUB_PRPLANIT_PASS
credentials: GHCR_ORG            →  GHCR_ORG_USER / GHCR_ORG_PASS

No credentials field → no login attempted (public or pre-authenticated). If credentials are configured but the env vars are missing, Login returns an error.

func (*Buildx) PushTags

func (bx *Buildx) PushTags(ctx context.Context, tags []string) (int, error)

PushTags pushes already-loaded local images to their remote registries. Used in single-platform load-then-push strategy where buildx builds with --load first, then we push each remote tag explicitly.

Returns the count of successfully pushed tags and the first error encountered. On full success: (len(tags), nil). On failure: (N, *PushError) where tags[:N] succeeded and tags[N] failed. Callers can retry with tags[pushed:].

func (*Buildx) Save

func (bx *Buildx) Save(ctx context.Context, imageRef string, outputPath string) error

Save exports a loaded image as a tarball for downstream scanning and attestation. The image must be loaded into the daemon first (--load or docker load).

type CacheInfo added in v0.5.0

type CacheInfo struct {
	Mode     string
	Branch   string
	Fallback string
	Imports  []string // deduped, ordered
	Exports  []string // deduped, ordered
}

CacheInfo holds resolved cache state for rendering. Computed once, rendered by execute.go — cache.go does not render.

func ResolveCacheInfo added in v0.5.0

func ResolveCacheInfo(pc *pipeline.PipelineContext) CacheInfo

ResolveCacheInfo computes the cache rendering info from the pipeline context.

type CacheResolution added in v0.5.0

type CacheResolution struct {
	Mode     string // off | local | shared | hybrid
	Local    string // hit | miss | skipped
	External string // hit | miss | skipped
	Fallback string // hit | miss | skipped
	Result   string // "using local" | "using external (branch)" | "cold build"
	Builder  string // "reused (sf-abc123)" | "created (sf-abc123)"
}

CacheResolution records what was checked during cache setup. Populated by the executor after probing, not by flag building.

type CacheTag added in v0.5.0

type CacheTag struct {
	Prefix    string // e.g., "cache"
	RepoHash  string // 8-char repo scope hash
	BranchRef string // canonicalized branch (from CanonicalizeRef)
}

CacheTag is a deterministic, repo-scoped cache tag. Format: <prefix>-<repo-hash-8>-<branch-canonical> where branch-canonical = <normalized-branch>-<branch-hash-8>

This is the ONLY way to construct or validate cache tags. Both the writer (BuildCacheFlags) and retention matcher must use this. Changing this format is a compatibility boundary.

func BuildCacheTag added in v0.5.0

func BuildCacheTag(prefix, repoID, branch string) CacheTag

BuildCacheTag constructs a cache tag from repo + branch identifiers. This is the single constructor — no other code should build cache tag strings.

func ParseCacheTag added in v0.5.0

func ParseCacheTag(tag string) *CacheTag

ParseCacheTag parses a tag string into a CacheTag. Returns nil if the tag doesn't match StageFreight's deterministic naming. This is the inverse of BuildCacheTag — constructor + parser pair.

func (CacheTag) MatchesScope added in v0.5.0

func (t CacheTag) MatchesScope(scopePrefix string) bool

MatchesScope returns true if this tag belongs to the given repo scope.

func (CacheTag) ScopePrefix added in v0.5.0

func (t CacheTag) ScopePrefix() string

ScopePrefix returns the repo-scoped prefix for retention matching. All tags for this repo start with this prefix.

func (CacheTag) String added in v0.5.0

func (t CacheTag) String() string

String renders the full tag string for registry use.

type CleanupCommand added in v0.5.0

type CleanupCommand struct {
	Class   string // "images.dangling", "build_cache", "containers.exited", etc.
	Command string // raw docker command (no error suppression — executor handles that)
}

CleanupCommand is a single cleanup operation with its class context.

func BuildCleanupCommands added in v0.5.0

func BuildCleanupCommands(cleanup config.HostCleanupConfig) []CleanupCommand

BuildCleanupCommands generates Docker cleanup commands from the prune policy. Commands are returned raw — no error suppression. The executor decides behavior based on enforcement mode (best_effort: continue + warn, required: fail immediately).

Image protection uses a two-phase approach:

  1. Resolve protected image IDs from ref patterns (docker images --filter=reference=...)
  2. Prune with exclusion of resolved IDs

This is because docker prune does not support ref-based exclusion natively.

type CleanupCommandResult added in v0.5.0

type CleanupCommandResult struct {
	Class   string
	Command string
	Output  string
	Error   error
}

CleanupCommandResult records the outcome of one cleanup command.

type CleanupResult added in v0.5.0

type CleanupResult struct {
	Executed bool
	Results  []CleanupCommandResult
}

CleanupResult records what happened during host hygiene.

type CrucibleCheck

type CrucibleCheck struct {
	Name   string // e.g. "binary hash", "version", "image digest"
	Status string // "match", "differs", "unavailable"
	Detail string // e.g. "sha256:abc123..."
}

CrucibleCheck is a single verification data point.

func (CrucibleCheck) IsHardFailure

func (c CrucibleCheck) IsHardFailure() bool

IsHardFailure returns true if this check's failure should fail the crucible.

type CrucibleOpts

type CrucibleOpts struct {
	Image      string   // pass-1 candidate image ref
	FinalTag   string   // tag for the verification artifact
	RepoDir    string   // absolute path to repo root (mounted into container)
	ExtraFlags []string // original user flags minus --build-mode
	EnvVars    []string // credential and CI env vars to forward (KEY=VALUE)
	RunID      string   // correlates passes in logs
	Verbose    bool
	Backend    *Backend // resolved backend — determines execution strategy
}

CrucibleOpts configures the pass-2 container invocation.

type CrucibleResult

type CrucibleResult struct {
	Passed        bool
	ExitCode      int
	FinalImageRef string
}

CrucibleResult captures the outcome of a pass-2 invocation.

func RunCrucible

func RunCrucible(ctx context.Context, opts CrucibleOpts) (*CrucibleResult, error)

RunCrucible executes pass 2 using the resolved backend. Buildkitd: extracts candidate binary, runs natively (same filesystem + buildkitd). DinD: runs candidate via docker run (traditional container execution).

type CrucibleVerification

type CrucibleVerification struct {
	ArtifactChecks  []CrucibleCheck
	ExecutionChecks []CrucibleCheck
	TrustLevel      string
}

CrucibleVerification holds the complete verification result.

func VerifyCrucible

func VerifyCrucible(ctx context.Context, pass1Image, pass2Image string) (*CrucibleVerification, error)

VerifyCrucible compares pass-1 and pass-2 images to determine trust level. Uses promoted identity helpers from image_inspect.go for all inspections.

func (*CrucibleVerification) HasHardFailure

func (cv *CrucibleVerification) HasHardFailure() bool

HasHardFailure returns true if any check is a hard failure.

type ExternalRetentionResult added in v0.5.0

type ExternalRetentionResult struct {
	Registry string
	Path     string
	Prefix   string
	Total    int
	Pruned   int
	Kept     int
	Errors   []string
}

ExternalRetentionResult records what the external cache retention executor did.

type GCRule added in v0.5.0

type GCRule struct {
	Scope        string // "source/cachemount/git", "general cache", etc.
	All          bool
	KeepDuration string
	MaxUsed      string
	Reserved     string
	MinFree      string
}

GCRule is a parsed BuildKit garbage collection policy rule.

type InventoryResult

type InventoryResult struct {
	BaseImages []PackageInfo // normalized primary base image versions from FROM refs
	Lineage    []PackageInfo // inferred distro lineage from tag suffixes
	Packages   []PackageInfo // all discovered packages
	Args       []ArgDecl     // ARG declarations with defaults
}

InventoryResult holds all extracted packages grouped by manager.

func ExtractInventory

func ExtractInventory(dockerfilePath string) (*InventoryResult, error)

ExtractInventory parses a Dockerfile and extracts package inventory. This is the main entry point for inventory extraction.

type LocalRetentionResult added in v0.5.0

type LocalRetentionResult struct {
	Dir           string
	EntriesBefore int
	Pruned        int
	PrunedBytes   int64
	Reason        string // "" if nothing to do
}

LocalRetentionResult records what the local cache retention executor did.

type PackageInfo

type PackageInfo struct {
	Name       string // package name
	Version    string // version if known, empty otherwise
	Pinned     bool   // true if version is explicitly pinned
	Source     string // broad category: "dockerfile", "dockerfile_arg", "base_image"
	SourceRef  string // narrow origin: the actual instruction or ARG declaration
	Manager    string // package manager name: "apk", "pip", "npm", "go", "galaxy", "binary", "base", "apt"
	Confidence string // "inferred" for heuristic-derived items, empty for authoritative
	URL        string // download URL for binary installs
	Stage      string // stage name from "AS <name>", empty for unnamed stages
	Final      bool   // true if this is from the last FROM stage (the shipped image)
}

PackageInfo represents a discovered package/dependency from Dockerfile analysis. This is the build package's internal model — manifest generation converts these to schema types. Keeps the build package reusable without circular coupling.

type PushError

type PushError struct {
	Tag      string // fully qualified ref that failed
	ExitCode int    // process exit code (1 if not determinable)
	Stderr   string // stderr from the failed push only
	Cause    error  // underlying exec error
}

PushError is the structured error from a failed docker push. Implements error — PushTags return type stays (int, error).

func (*PushError) Error

func (e *PushError) Error() string

func (*PushError) Unwrap

func (e *PushError) Unwrap() error

type Request

type Request struct {
	Context    context.Context
	RootDir    string
	Config     *config.Config
	Verbose    bool
	Local      bool
	Platforms  []string
	Tags       []string
	Target     string
	BuildID    string
	SkipLint   bool
	DryRun     bool
	BuildMode  string
	ConfigFile string // forwarded by crucible to inner build
	Stdout     io.Writer
	Stderr     io.Writer
}

Request holds all inputs for a docker build pipeline run. Every field that previously came from a package-global variable is explicitly passed here, eliminating hidden coupling to cobra flag state.

type VerificationArtifact

type VerificationArtifact struct {
	Tag string // e.g. "stagefreight/crucible-verify:<run-id>"
}

VerificationArtifact encapsulates the extra --tag + --local added to pass 2 for post-build verification. Centralizes the concept so it isn't ad-hoc flag munging scattered across call sites.

func (VerificationArtifact) AppendFlags

func (va VerificationArtifact) AppendFlags() []string

AppendFlags returns the flags needed to produce the verification artifact.

Jump to

Keyboard shortcuts

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