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
- Variables
- func RegisterKind(reg *resource.Registry) error
- func Reserved(name string) bool
- func Sync(ctx context.Context, store *Store) (int, error)
- type Dependency
- type Entry
- type Manager
- type Option
- type Prober
- type Release
- type Report
- type Resolved
- type SandboxProber
- type Source
- type Spec
- type Store
Constants ¶
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 ¶
var ErrNotFound = errors.New("dependency: not found")
ErrNotFound is returned when a dependency spec does not exist.
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 ¶
RegisterKind registers the Dependency kind so a store admits dependency specs. It is idempotent.
Types ¶
type Dependency ¶
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.
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 ¶
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) Resolve ¶
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 ¶
WithPlatform overrides the target platform (default the running GOOS/GOARCH). Tests use it to exercise provisioning for a specific platform.
func WithProber ¶
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 ¶
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 ¶
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.
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 ¶
DecodeSpec reads the typed spec from a resource.
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 ¶
NewStore returns a dependency facade over rs. The caller must have registered the Dependency kind with the registry rs admits against (see RegisterKind).