dependency

package
v0.1.2 Latest Latest
Warning

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

Go to latest
Published: Jul 7, 2026 License: MIT Imports: 19 Imported by: 0

Documentation

Overview

Package dependency manages the external command-line programs Flynn needs to operate but does not ship in its own binary (for example a hosting provider's CLI). It is the generic, spec-driven analogue of the model-runtime provisioner: a dependency is a typed resource whose spec is pure data (how to detect it on the host, the minimum version that is acceptable, and the pinned per-platform artifacts to install when it is missing), and one engine reads any such spec to satisfy it.

The policy is detect-installed-first: a program already present on the host that meets the version floor is used as-is, with no download. Only when none is present, or the present one is below the floor, does Flynn provision the pinned build, fetched and verified through the same hardened acquire path the model runtime uses. The program is data here; the engine never hard-codes a tool.

Index

Constants

View Source
const (
	// GroupVersion is the Dependency kind's API group and version.
	GroupVersion = "dependency.ionagent.io/v1alpha1"
	// Kind is the resource kind name dependencies are stored under.
	Kind = "Dependency"
)

Variables

View Source
var ErrNotFound = errors.New("dependency: not found")

ErrNotFound is returned when a dependency spec does not exist.

View Source
var KindDef = resource.Kind{
	APIVersion: GroupVersion,
	Name:       Kind,
	Schema:     specSchema,
	Singular:   "dependency",
	Plural:     "dependencies",
}

KindDef is the Dependency kind definition registered with a resource registry.

Functions

func RegisterKind

func RegisterKind(reg *resource.Registry) error

RegisterKind registers the Dependency kind so a store admits dependency specs. It is idempotent.

func Reserved

func Reserved(name string) bool

Reserved reports whether a name belongs to an official bundled dependency, so a runtime-authored spec cannot impersonate one by claiming its name.

func Sync

func Sync(ctx context.Context, store *Store) (int, error)

Sync writes every bundled dependency spec into the store. It is idempotent: the resource store dedups an unchanged spec by content, so re-syncing on each start is a no-op. It returns the number of specs written.

Types

type Dependency

type Dependency struct {
	Name string
	Spec Spec
}

Dependency is the typed view of a dependency resource.

type Entry

type Entry struct {
	Name string
	Spec Spec
	Raw  json.RawMessage
}

Entry is one official dependency from the embedded catalog.

func Entries

func Entries() ([]Entry, error)

Entries returns the official dependency catalog, parsed once and ordered by name. A malformed embedded spec is a programming error in this package, surfaced as an error here and caught by the build-time gate.

type Manager

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

Manager satisfies dependencies from their specs. It is detect-installed-first: a present build that meets the floor is used as-is; otherwise the pinned build is fetched and verified through the acquire layer and installed under the data directory. It holds no program knowledge: every program is a spec it reads.

func NewManager

func NewManager(store *Store, dl *fetch.Downloader, dataDir string, opts ...Option) *Manager

NewManager builds a dependency manager over store. dl is the verified downloader used to provision a missing build; dataDir is the root the install directory lives under.

func (*Manager) Check

func (m *Manager) Check(ctx context.Context, name string) (Report, error)

Check reports a dependency's observed state without provisioning anything.

func (*Manager) Resolve

func (m *Manager) Resolve(ctx context.Context, name string) (Resolved, error)

Resolve satisfies the named dependency and returns a runnable path. A present build that meets the floor is returned without a download; otherwise the pinned build for this platform is fetched, verified, and installed. It fails when the program is neither present nor shipped for this platform, with a message telling the operator how to proceed.

type Option

type Option func(*Manager)

Option configures a Manager.

func WithPlatform

func WithPlatform(goos, goarch string) Option

WithPlatform overrides the target platform (default the running GOOS/GOARCH). Tests use it to exercise provisioning for a specific platform.

func WithProber

func WithProber(p Prober) Option

WithProber sets the version-probe boundary. A nil prober means no system program can be verified, so every dependency is provisioned from its pinned build.

type Prober

type Prober interface {
	Probe(ctx context.Context, name string, args []string) (string, error)
}

Prober runs a present program's version command and returns its output. It is a narrow boundary so the engine can be tested without executing anything and so the host can confine the probe: the real implementation runs the program through the sandbox, never spawning a process directly. A probe error means the program is absent or would not run, which the engine treats as "not present" rather than trusting it blindly.

type Release

type Release struct {
	// GOOS and GOARCH are the platform this build targets (Go's runtime.GOOS/GOARCH).
	GOOS   string `json:"goos"`
	GOARCH string `json:"goarch"`
	// URL is the https source of the release archive.
	URL string `json:"url"`
	// SHA256 is the pinned digest the downloaded archive must match.
	SHA256 string `json:"sha256"`
	// SizeBytes is the archive's known size, used as the download cap.
	SizeBytes int64 `json:"sizeBytes"`
	// Archive is the container format: "zip" or "tar.gz".
	Archive string `json:"archive"`
	// BinName is the executable to locate inside the extracted archive (for example
	// "flyctl" or "flyctl.exe").
	BinName string `json:"binName"`
}

Release is one pinned artifact for a single platform: where to fetch it, the digest it must match, its archive format, and the executable inside it. It is the data the acquire layer needs to install a verified build, with the platform it targets.

type Report

type Report struct {
	Name         string
	Present      bool
	Path         string
	Version      string
	MeetsFloor   bool
	CanProvision bool
}

Report is the observed state of a dependency without changing anything: whether a usable build is present on the host, its version, whether it meets the floor, and whether Flynn could provision one for this platform if it is not.

type Resolved

type Resolved struct {
	Name    string
	Path    string
	Version string
	Source  Source
}

Resolved is a satisfied dependency: what to run, the version in effect, and where it came from. For a system program the path is the program name the sandbox resolves on PATH; for a provisioned build it is the absolute path of the installed binary.

type SandboxProber

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

SandboxProber reads a present program's version by running its version command through the sandbox boundary, so the detect-installed-first check never spawns a process directly: the program runs confined, governed, and bounded like any other command. The invocation is the program name plus the spec's literal version arguments, nothing model-authored, so there is no untrusted input in the command.

func NewSandboxProber

func NewSandboxProber(sb sandbox.Sandbox) SandboxProber

NewSandboxProber wraps a sandbox as a version prober.

func (SandboxProber) Probe

func (p SandboxProber) Probe(ctx context.Context, name string, args []string) (string, error)

Probe runs "name args..." through the sandbox and returns its output. A run error or a nonzero exit is returned as an error, which the manager reads as "not present or not usable" rather than trusting the program.

type Source

type Source string

Source is where a satisfied dependency came from.

const (
	// SourceSystem is a program already present on the host that met the floor.
	SourceSystem Source = "system"
	// SourceProvisioned is a pinned build Flynn fetched and installed.
	SourceProvisioned Source = "provisioned"
)

type Spec

type Spec struct {
	// Description is a short human summary of what the program is.
	Description string `json:"description,omitempty"`
	// Binaries are the executable names that satisfy this dependency, in preference order,
	// searched on PATH for the detect-installed-first check (for example ["flyctl", "fly"]).
	Binaries []string `json:"binaries"`
	// VersionArgs are the arguments that make the program print its version (for example
	// ["version"] or ["--version"]). Empty skips the version probe: any present binary is
	// accepted and no floor is enforced on a system install.
	VersionArgs []string `json:"versionArgs,omitempty"`
	// VersionRegex extracts the version token from the program's version output; capture
	// group one is parsed as the version. Empty parses the whole output.
	VersionRegex string `json:"versionRegex,omitempty"`
	// MinVersion is the floor: a present or provisioned build below it is refused. Empty
	// imposes no floor.
	MinVersion string `json:"minVersion,omitempty"`
	// Pin is the version Flynn provisions when the dependency is missing. It must be at or
	// above MinVersion; the build-time gate enforces this.
	Pin string `json:"pin,omitempty"`
	// Releases are the pinned per-platform artifacts to fetch when provisioning. At least
	// the current platform must be covered for provisioning to be possible there.
	Releases []Release `json:"releases,omitempty"`
}

Spec is the desired shape of an external dependency: pure data, no secret. It says how to recognize the program on the host, the floor below which a build is refused, the version to install when provisioning, and the pinned artifacts to install per platform.

func DecodeSpec

func DecodeSpec(r resource.Resource) (Spec, error)

DecodeSpec reads the typed spec from a resource.

func (Spec) ReleaseFor

func (s Spec) ReleaseFor(goos, goarch string) (Release, bool)

ReleaseFor returns the release in s targeting the given platform, or false when the spec ships no build for it.

type Store

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

Store is the typed dependency facade over a resource.Store. Dependency specs live in the instance-global scope, addressed by name.

func NewStore

func NewStore(rs resource.Store) *Store

NewStore returns a dependency facade over rs. The caller must have registered the Dependency kind with the registry rs admits against (see RegisterKind).

func (*Store) Get

func (s *Store) Get(ctx context.Context, name string) (Dependency, error)

Get returns the named dependency spec, or ErrNotFound.

func (*Store) List

func (s *Store) List(ctx context.Context) ([]Dependency, error)

List returns every dependency spec, ordered by name.

func (*Store) Put

func (s *Store) Put(ctx context.Context, name string, spec Spec) (Dependency, error)

Put creates or updates the named dependency spec.

Jump to

Keyboard shortcuts

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