bottle

package module
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Aug 1, 2026 License: BSD-3-Clause Imports: 29 Imported by: 0

README

bottle

pkg.go.dev Go License

The pure-Go pkgx bottle client — the shared backend of the pure-Go pkgx family. It resolves a package's dependency closure from the pkgx pantry, downloads the bottles from dist.pkgx.dev, completes the implicit libc/gcc closure a FROM scratch image needs, and execs through the pkgx glibc loader. CGO_ENABLED=0, no runtime dependencies of its own.

Consumed by:

so both tools share one source of truth for the bottle protocol.

Highlights

  • Reads package.yml + versions.txt from the pantry, BFS the runtime dependency closure, streams gzip/xz + tar into PKGX_DIR.
  • Soname-exact FROM-scratch completion: walks each bottle's ELF DT_NEEDED and pulls the provider version that ships the exact soname an ABI needs (not merely the latest), so drifted sonames resolve.
  • Embedded Mozilla CA bundle (net/http with no system trust store), pure-Go DNS. Cross-compiles to six 64-bit targets.

BSD-3-Clause.

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

View Source
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.

Variables

View Source
var (
	DistBase   = "https://dist.pkgx.dev"
	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.

View Source
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.

View Source
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.

Functions

func BinNames

func BinNames(project string, provides []string) []string

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 Dir

func Dir() string

Dir resolves the bottle store (PKGX_DIR, default ~/.pkgx).

func DownloadBottle added in v0.2.0

func DownloadBottle(project, ver, osn, arch string) ([]byte, string, error)

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 FetchMeta

func FetchMeta(project string) (deps map[string]string, provides []string, err error)

FetchMeta returns the host-relevant runtime dependencies (project -> constraint) and the list of provided paths for a project's package.yml.

func FindClosureBin

func FindClosureBin(closure []Resolved, dir, project, name string) string

FindClosureBin returns the path to <project>/…/bin/<name> if that project is in the installed closure, else "".

func FindLoader

func FindLoader(dir string) string

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 HostSlug

func HostSlug() (string, string)

HostSlug returns the pkgx (os, arch) slug for the running machine.

func Install

func Install(r Resolved, pkgxDir string) (bool, error)

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 IsELF

func IsELF(p string) bool

IsELF reports whether the file at p starts with the ELF magic.

func IsOCI added in v0.4.0

func IsOCI(base string) bool

IsOCI reports whether a dist base selects the OCI transport.

func LibDirs added in v0.3.0

func LibDirs(closure []Resolved, dir string) []string

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

func LibPath(closure []Resolved, dir string) string

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

func NewHTTPClient() *http.Client

NewHTTPClient builds an *http.Client that trusts the embedded CA bundle in addition to the host's system trust store.

func PrefixOf

func PrefixOf(project string, closure []Resolved, dir string) string

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

func PrimaryBin(project string, provides []string) string

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

func ResolveBinPath(bin string) string

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

func StubBins(closure []Resolved, dir, prefix string) (int, error)

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.

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

func NewOCIClient(base string) (*OCIClient, error)

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

func (c *OCIClient) ListTags(project string) ([]string, error)

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

func (c *OCIClient) Pull(project, ver, osn, arch string) ([]byte, string, error)

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

func (c *OCIClient) Push(project, ver, osn, arch string, tarball []byte, ext string) error

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").

type Resolved

type Resolved struct {
	Project string
	Version Ver
}

Resolved is a project pinned to a concrete version.

func CompleteClosure

func CompleteClosure(roots map[string]string, dir string) ([]Resolved, error)

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

func MergeClosures(a, b []Resolved) []Resolved

MergeClosures appends the packages of b not already in a (dedup by project).

func ResolveClosure

func ResolveClosure(roots map[string]string) ([]Resolved, error)

ResolveClosure walks the runtime dependency graph breadth-first.

type Ver

type Ver struct {
	Raw  string
	Nums []int
}

Ver is a parsed pkgx version: its numeric components plus the raw string.

func FetchVersions

func FetchVersions(project string) ([]Ver, error)

FetchVersions returns the available versions of a project for the host os/arch, ascending.

func ParseVer

func ParseVer(s string) Ver

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

func PickVersion(project, constraint string) (Ver, error)

PickVersion returns the highest available version satisfying constraint.

func VersionsFor added in v0.2.0

func VersionsFor(project, osn, arch string) ([]Ver, error)

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.

func (Ver) Satisfies added in v0.2.0

func (v Ver) Satisfies(constraint string) bool

Satisfies reports whether the version meets a pkgx constraint ("^1.2", "~2", ">=1.0", "=1.2.3", "*", or "").

Jump to

Keyboard shortcuts

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