packaging

package
v0.19.0 Latest Latest
Warning

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

Go to latest
Published: Aug 21, 2026 License: Apache-2.0 Imports: 5 Imported by: 0

Documentation

Overview

Package packaging provides bin classification, base image selection, and Dockerfile generation for container packaging of Forge agents.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type BaseImage

type BaseImage struct {
	Image    string // e.g. "debian:bookworm-slim", "alpine:3.20"
	IsAlpine bool
}

BaseImage holds the selected base image information.

func SelectBaseImage

func SelectBaseImage(resolutions []BinResolution, baseImage string, alpine bool) BaseImage

SelectBaseImage chooses the appropriate base image based on resolved binaries and config. Priority: cfg.BaseImage → alpine flag → RequiresUbuntu detection → default debian:bookworm-slim.

type BinClassifier

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

BinClassifier resolves binary requirements into install plans.

func NewBinClassifier

func NewBinClassifier(cfg types.PackageConfig, slim, alpine bool) (*BinClassifier, error)

NewBinClassifier creates a classifier with the given config.

func (*BinClassifier) Classify

func (c *BinClassifier) Classify(manifest *BinManifest) ([]BinResolution, []string, error)

Classify resolves all bin requirements into install plans. Returns (resolutions, warnings, error).

type BinManifest

type BinManifest struct {
	Requirements []contract.BinRequirement
	SkillOrigin  map[string]string // bin name → skill that declared it
}

BinManifest aggregates all binary requirements from skills.

type BinResolution

type BinResolution struct {
	Name           string
	Method         InstallMethod
	Package        string   // apt/apk package name
	URL            string   // expanded URL for direct download
	Dest           string   // install destination path
	Chmod          string   // permission bits
	RunLines       []string // custom RUN commands
	Image          string   // companion image for image-copy
	LocalPath      string   // host file path for local-file method
	Version        string   // resolved version
	Optional       bool
	RequiresUbuntu bool
	RequiresFirst  []string // dependencies
}

BinResolution is the resolved install plan for a single binary.

type DockerfileFragments

type DockerfileFragments struct {
	// PreAppStages is the Dockerfile chunk preceding the application
	// stage. May contain companion `FROM <upstream> AS bin-<name>`
	// stages for image-copy binaries plus a shared `bins` stage for
	// direct-URL / custom-RUN / local-file installs. Empty when no
	// binary needs a pre-app stage (e.g. an agent declaring only
	// apt-installable bins).
	PreAppStages string

	// RuntimeAptPackages are runtime apt packages the application
	// stage must install. Debian-only; nil on Alpine.
	RuntimeAptPackages []string

	// RuntimeApkPackages are runtime apk packages the application
	// stage must install. Alpine-only; nil on Debian.
	RuntimeApkPackages []string

	// BinCopies are formatted "COPY --from=<stage> <path> <path>"
	// lines emitted by the application stage. One per binary —
	// intent-explicit, no wholesale-directory copies. Empty when no
	// pre-app stage produced any binary.
	BinCopies []string

	// PathExtensions are PATH directories the application stage
	// exports for binaries installed at non-standard locations.
	PathExtensions []string
}

DockerfileFragments is the structured output of GenerateDockerfile. It separates the multi-stage pre-application chunks (companion image-copy stages + a shared bins stage for direct-URL / custom-RUN downloads) from the per-binary plumbing the application stage needs.

Pre-issue #149 the generator returned a single string for "everything before the application stage" and the template emitted one blunt `COPY --from=bins /usr/local/bin/ /usr/local/bin/`. apt-installed binaries land at /usr/bin/ on Debian (not /usr/local/bin/) and have transitive lib/etc deps, so they could never survive the per-stage COPY — and the wholesale directory copy hid the issue from review.

Post-fix:

  • Apt/apk binaries are installed in the application stage directly, so the package manager's dependency resolution pulls in the right shared libs and config.
  • Direct-URL / custom-RUN / local-file binaries still flow through a shared `bins` stage (they need curl + a writable filesystem) and are forwarded via per-binary explicit COPYs.
  • Image-copy binaries skip the bins stage entirely and copy straight from their dedicated `bin-<name>` companion stage to the app stage.

func GenerateDockerfile

func GenerateDockerfile(manifest *BinManifest, cfg types.PackageConfig, alpine, slim bool) (DockerfileFragments, []string, error)

GenerateDockerfile classifies the agent's binary requirements and returns the per-stage Dockerfile fragments. Callers compose the final Dockerfile by emitting PreAppStages, then the application stage with the BinCopies / RuntimeAptPackages / RuntimeApkPackages hooks honored.

Returns (fragments, warnings, error). A nil/empty manifest returns zero-value fragments and no error.

func (DockerfileFragments) HasPreAppStages

func (f DockerfileFragments) HasPreAppStages() bool

HasPreAppStages reports whether any pre-application multi-stage content exists. Used by the template to decide whether to emit the "# --- Binary installation stages ---" header.

type InstallMethod

type InstallMethod string

InstallMethod describes how a binary will be installed.

const (
	MethodApt       InstallMethod = "apt"
	MethodApk       InstallMethod = "apk"
	MethodDirectURL InstallMethod = "direct-url"
	MethodCustomRun InstallMethod = "custom-run"
	MethodImageCopy InstallMethod = "image-copy"
	MethodLocalFile InstallMethod = "local-file" // local binary copied into build context
	MethodSkip      InstallMethod = "skip"       // dependency already provided by another binary
)

Jump to

Keyboard shortcuts

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