Documentation
¶
Overview ¶
Package bottle is the reusable pkgx "bottle backend": it resolves a package's runtime dependency closure from the pkgx pantry, downloads the bottles from dist.pkgx.dev, and installs them — with no runtime dependencies of its own (pure Go, CGO_ENABLED=0, runnable on a `FROM scratch` image). It is imported by the pkgm CLI and by sibling tools so there is one source of truth.
Index ¶
- Constants
- Variables
- func BinNames(project string, provides []string) []string
- func CanonicalLoaderExists() bool
- func ConfigError() error
- func Dir() string
- func DownloadBottle(project, ver, osn, arch string) ([]byte, string, error)
- func Env(name string) string
- func FetchMeta(project string) (deps map[string]string, provides []string, err error)
- func FindClosureBin(closure []Resolved, dir, project, name string) string
- func FindLoader(dir string) string
- func GOARCH() string
- func GOOS() string
- func HostSlug() (string, string)
- func Install(r Resolved, pkgxDir string) (bool, error)
- func IsELF(p string) bool
- func IsOCI(base string) bool
- func LibDirs(closure []Resolved, dir string) []string
- func LibPath(closure []Resolved, dir string) string
- func LoaderName() string
- func NewHTTPClient() *http.Client
- func PrefixOf(project string, closure []Resolved, dir string) string
- func PrimaryBin(project string, provides []string) string
- func ResolveBinPath(bin string) string
- func SetupScratchRootfs(loader, shellPath string)
- func StubBins(closure []Resolved, dir, prefix string) (int, error)
- func VerifyRequired() bool
- func VerifySignature(tarball, payload []byte, b64sig, pubkey string) error
- type OCIClient
- func (c *OCIClient) ListTags(project string) ([]string, error)
- func (c *OCIClient) Pull(project, ver, osn, arch string) ([]byte, string, error)
- func (c *OCIClient) Push(project, ver, osn, arch string, tarball []byte, ext string) error
- func (c *OCIClient) PushWithReferrers(project, ver, osn, arch string, tarball []byte, ext string, refs []Referrer) (ocispec.Descriptor, error)
- func (c *OCIClient) Referrers(project string, subject ocispec.Descriptor) ([]ocispec.Descriptor, error)
- func (c *OCIClient) VerifyBottle(project, ver, osn, arch string, tarball []byte) error
- type Referrer
- type Resolved
- type Ver
Constants ¶
const ( MediaBottleLayerGz = "application/vnd.pkgx.bottle.layer.v1.tar+gzip" MediaBottleLayerXz = "application/vnd.pkgx.bottle.layer.v1.tar+xz" // ArtifactTypeBottle marks a pkgx-bottle image manifest (its manifest.config // carries this via ORAS PackManifest v1.1's artifactType). ArtifactTypeBottle = "application/vnd.pkgx.bottle" )
OCI / pkgx media types.
const ( // ArtifactTypeSignature marks a cosign signature referrer manifest. ArtifactTypeSignature = "application/vnd.dev.cosign.artifact.sig.v1+json" // MediaSimpleSigning is the media type of the simple-signing payload blob. MediaSimpleSigning = "application/vnd.dev.cosign.simplesigning.v1+json" // CosignSignatureAnnotation carries the base64 signature on the referrer // manifest (cosign's convention). CosignSignatureAnnotation = "dev.cosignproject.cosign/signature" )
Signature referrer conventions.
Variables ¶
var ( DistBase = "oci://ghcr.io/go-pkgx/packages" PantryBase = "https://raw.githubusercontent.com/pkgxdev/pantry/main/projects" )
Base URLs for the pkgx distribution + pantry; overridable in tests, and at runtime via $PKGX_DIST / $PKGX_PANTRY so a consumer can point pkgm/pkgx at a local mirror produced by the `mirror` tool.
DistBase defaults to the **signed** go-pkgx OCI registry so the default install path is verifiable end-to-end (pairs with VerifyRequired defaulting on). That registry is a growing subset of the pantry; for the full upstream catalogue set PKGX_DIST=https://dist.pkgx.dev (unsigned → also set PKGX_VERIFY=0).
var Exec func(argv0 string, argv []string, env []string) error
Exec runs (or, on UNIX, replaces the current process image with) the target binary; overridable in tests. Its concrete value is platform-specific:
- UNIX (exec_unix.go): syscall.Exec — replaces the process, never returns on success.
- Windows (exec_windows.go): spawns the child with inherited stdio, waits, and exits the parent with the child's exit code (Windows has no execve).
The signature is identical on every platform, so callers are unchanged.
var HTTPClient = NewHTTPClient()
HTTPClient is an HTTP client that trusts the embedded CA bundle (falling back to the system pool if, somehow, the embed is empty). It is overridable.
var SigningPublicKey = "RWQ+rmH+fXy2iYr+gReQAOQtYWtH0A7UlxcAa2hpr+txNBwGqtpFsR6L"
SigningPublicKey is the go-pkgx bottle signing key (minisign format). A signed bottle carries a cosign-style signature referrer whose signature verifies against this key; verification is fail-closed. It is a var (not const) only so tests can substitute a throwaway key.
Functions ¶
func BinNames ¶
BinNames returns the base names of the binaries a package provides, falling back to the project's leaf name when it declares no `provides:`.
func CanonicalLoaderExists ¶
func CanonicalLoaderExists() bool
CanonicalLoaderExists reports whether /lib{,64}/ld-linux-* is present.
func ConfigError ¶ added in v0.5.0
func ConfigError() error
ConfigError returns the error, if any, from loading ~/.pkgx/config.hcl2. It is nil when the file parsed cleanly or is simply absent, and non-nil only on a real path or parse failure (in which case reads fall back to the environment).
func DownloadBottle ¶ added in v0.2.0
DownloadBottle fetches the raw compressed bottle tarball for a specific project/version/os/arch, trying .tar.gz then .tar.xz. It returns the bytes and the extension that succeeded (".tar.gz" or ".tar.xz") — for mirror tooling that copies bottles verbatim without extracting them.
func Env ¶ added in v0.5.0
Env resolves a variable for the go-pkgx tools. A real process environment variable that is set AND non-empty wins; otherwise the value from ~/.pkgx/config.hcl2 is returned; otherwise the empty string.
func FetchMeta ¶
FetchMeta returns the host-relevant runtime dependencies (project -> constraint) and the list of provided paths for a project's package.yml.
func FindClosureBin ¶
FindClosureBin returns the path to <project>/…/bin/<name> if that project is in the installed closure, else "".
func FindLoader ¶
FindLoader locates the pkgx glibc dynamic loader in an installed closure.
func GOARCH ¶
func GOARCH() string
GOARCH returns the pkgx architecture slug (e.g. "x86-64", "aarch64") for the running machine.
func GOOS ¶
func GOOS() string
GOOS returns the pkgx OS slug ("linux", "darwin", or "windows") for the running machine.
func Install ¶
Install downloads and extracts one bottle into pkgxDir (skips if the versioned prefix already exists), then writes major/minor convenience links. Extraction is atomic — the bottle is unpacked into a temp dir and the versioned prefix is renamed into place — so concurrent installs sharing one PKGX_DIR never observe a half-extracted prefix.
func LibDirs ¶ added in v0.3.0
LibDirs returns every library directory in an installed closure (including glibc's versioned sub-libdir on linux). It is the list form of LibPath, used where an OS-native path separator is required (Windows joins with ";" and resolves DLLs from these dirs via PATH, so a ":"-joined string is wrong).
func LibPath ¶
LibPath returns a ":"-joined library path covering every lib dir in an installed closure (including glibc's versioned sub-libdir). It is the value of $LD_LIBRARY_PATH used on linux; on Windows use LibDirs with the native separator instead.
func LoaderName ¶
func LoaderName() string
LoaderName is the dynamic-loader soname for the current architecture.
func NewHTTPClient ¶
NewHTTPClient builds an *http.Client that trusts the embedded CA bundle in addition to the host's system trust store.
func PrefixOf ¶
PrefixOf returns the installed prefix directory <dir>/<project>/v<version> for the Resolved whose Project equals project in the closure, or "" if the project is not part of the closure.
func PrimaryBin ¶
PrimaryBin picks the binary to run for a project: the one whose name matches the project's path leaf (gnu.org/wget -> wget) or its domain's second-level label (perl.org -> perl, not the first-listed corelist), else the first provided binary.
func ResolveBinPath ¶ added in v0.3.0
ResolveBinPath maps a logical bin path (…/bin/foo) to the file that actually exists on disk. On Windows it prefers "foo.exe" (the PE image the toolchain produces), falling back to the bare name; on UNIX it is the identity. This keeps BinNames/PrimaryBin returning logical, extension-free names while the run/stub sites resolve to the real executable.
func SetupScratchRootfs ¶
func SetupScratchRootfs(loader, shellPath string)
SetupScratchRootfs makes the pkgx loader and a shell available at their canonical absolute paths (best-effort). On a FROM-scratch image this lets every bottle ELF — the one we exec AND any child processes it spawns — resolve its PT_INTERP=/lib/ld-linux natively, and (when shellPath is set) lets "#!/bin/sh" wrapper scripts resolve to the pkgx bash we installed. On a normal system these paths already exist, so os.Symlink fails and is ignored (no clobbering).
func StubBins ¶
StubBins writes a small env-setting shell stub into <prefix>/bin for every binary in the closure, mirroring the reference pkgm: the stub exports the closure's LD_LIBRARY_PATH and exec's the real bottle binary.
func VerifyRequired ¶ added in v0.5.0
func VerifyRequired() bool
VerifyRequired reports whether fail-closed signature verification is demanded when installing. It is **on by default** (secure by default): only an explicit PKGX_VERIFY=0/false/no/off opts out. Anything else — unset, 1/true/yes/on, or an unrecognised value — keeps verification on. The value is read through Env, so it may come from a real environment variable or from ~/.pkgx/config.hcl2.
func VerifySignature ¶ added in v0.5.0
VerifySignature checks a cosign simple-signing signature over a bottle tarball: the base64 sig must verify over payload against pubkey (defaulting to the pinned SigningPublicKey), and payload must commit to this exact tarball (docker-manifest-digest == sha256(tarball)). Every failure returns an error — callers treat that as fail-closed.
Types ¶
type OCIClient ¶ added in v0.4.0
type OCIClient struct {
// contains filtered or unexported fields
}
OCIClient talks to an OCI distribution (registry v2) endpoint via ORAS. It is used by the bottle pull path and by the mirror push tool, so the OCI protocol lives in one place (ORAS).
func NewOCIClient ¶ added in v0.4.0
NewOCIClient parses an oci:// dist base into a client. Localhost/loopback hosts default to plain HTTP (for a local zot/registry on a port); every other host uses HTTPS. Credentials are read from the environment: OCI_TOKEN (a pre-issued bearer), else OCI_USERNAME / OCI_PASSWORD for token exchange / basic auth. Public repositories work anonymously.
func (*OCIClient) ListTags ¶ added in v0.4.0
ListTags returns the tags (versions) published for a project, or an error if the repository does not exist.
func (*OCIClient) Pull ¶ added in v0.4.0
Pull downloads the bottle tarball for a project/version/os/arch: fetch the version-tag manifest (an index, or a single-platform image manifest), pick the platform-matching image manifest, take its single non-config layer, fetch the layer blob. Returns the tarball bytes and the extension (".tar.gz"/".tar.xz") derived from the layer mediaType.
func (*OCIClient) Push ¶ added in v0.4.0
Push publishes one bottle for a project/version/os/arch: it pushes the tarball as a layer blob, packs a per-platform image manifest (ORAS PackManifest, which also pushes a scratch config blob), then merges the platform into the version-tag image index (fetching any existing index first) and tags it. ext selects the layer mediaType (".tar.gz" or ".tar.xz").
func (*OCIClient) PushWithReferrers ¶ added in v0.5.0
func (c *OCIClient) PushWithReferrers(project, ver, osn, arch string, tarball []byte, ext string, refs []Referrer) (ocispec.Descriptor, error)
PushWithReferrers is Push plus a set of attestations attached to the pushed per-platform manifest as OCI referrers. It returns that manifest's descriptor so callers can list/verify the referrers. Referrers are pushed before the version index is tagged, so a reader that resolves the index always finds a manifest whose attestations are already present.
func (*OCIClient) Referrers ¶ added in v0.5.0
func (c *OCIClient) Referrers(project string, subject ocispec.Descriptor) ([]ocispec.Descriptor, error)
Referrers lists the attestations attached to a manifest (its OCI referrers), each descriptor carrying the referrer's ArtifactType.
func (*OCIClient) VerifyBottle ¶ added in v0.5.0
VerifyBottle checks the cosign-style signature attached to a pulled bottle as an OCI referrer, against the pinned SigningPublicKey. It is fail-closed: a missing signature referrer, a malformed one, or a signature that does not verify (or does not commit to this tarball) all return an error.
type Referrer ¶ added in v0.5.0
type Referrer struct {
ArtifactType string
MediaType string
Blob []byte
// Annotations are merged into the referrer manifest — used to carry a cosign
// signature (dev.cosignproject.cosign/signature) alongside its payload blob.
Annotations map[string]string
}
Referrer is an attestation to attach to a bottle's per-platform manifest as an OCI referrer (subject-linked artifact): a CycloneDX/SPDX SBOM, an in-toto SLSA provenance statement, or (later) a cosign signature. ArtifactType classifies the referrer manifest; MediaType is the layer blob's media type (usually the same); Blob is the attestation bytes.
type Resolved ¶
Resolved is a project pinned to a concrete version.
func CompleteClosure ¶
CompleteClosure resolves a package's declared closure, installs it, then iteratively reads the bottles' ELF DT_NEEDED and pulls whatever bottle provides each unsatisfied soname — the implicit glibc/gcc system libraries and the common undeclared libraries (libz, libbz2, ncurses…) that package.yml graphs omit — until every NEEDED soname is satisfied. This makes the closure complete enough to run on a `FROM scratch` image.
func MergeClosures ¶
MergeClosures appends the packages of b not already in a (dedup by project).
type Ver ¶
Ver is a parsed pkgx version: its numeric components plus the raw string.
func FetchVersions ¶
FetchVersions returns the available versions of a project for the host os/arch, ascending.
func ParseVer ¶
ParseVer parses a pkgx version string into a Ver, stopping each component at the first non-numeric character (e.g. "1w" in openssl 1.1.1w).
func PickVersion ¶
PickVersion returns the highest available version satisfying constraint.
func VersionsFor ¶ added in v0.2.0
VersionsFor returns the available versions of a project for an explicit pkgx os/arch slug (e.g. "linux"/"aarch64"), ascending. Used by mirror tooling that spans arches other than the host's.