provision

package
v0.5.0 Latest Latest
Warning

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

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

Documentation

Overview

Package provision reconciles a declarative "what should be installed" manifest (`patchcord provision`, ADR-0073) against the agent's plugin, app and bundle catalogs. It exists to turn a custom plugin/app/bundle's dev→prod transition into one reproducible step, usable either inside a Docker multi-stage build (no server running — every install primitive here already works straight against a --data-dir, see internal/cli.openDataStore's own doc comment) or against a live deployment's data directory before a restart.

Apply never runs implicitly. Nothing in internal/runtime calls it, and `patchcord serve`/`dev` never read a manifest on their own — every install path that can reach the network (a configured registry, internal/registry; a GitHub Releases reference, internal/ghrelease) stays an explicit, user-triggered action, exactly as it already is for `plugin install`/`bundle install`. Apply only ever runs when `patchcord provision <file>` is invoked directly.

Index

Constants

View Source
const ManifestFileName = "provision.yaml"

ManifestFileName is the conventional name for a provisioning manifest — a plain declarative file, not a package: nothing about it needs archiving, signing, or extracting, unlike a .patchcord-plugin/-app/ -bundle. `patchcord provision` accepts any path; this is a naming convention only, the same role bundle.yaml/patchcord-app.yaml play elsewhere in this codebase.

Variables

View Source
var ErrInvalidManifest = errors.New("invalid provisioning manifest")

ErrInvalidManifest is returned by ParseManifest and LoadManifest when the manifest is malformed.

Functions

This section is empty.

Types

type AppOutcome

type AppOutcome struct {
	Ref string
	App apps.App
	// Policy is nil when Ref resolved to a local directory — nothing was
	// verified.
	Policy *trust.PolicyResult
}

AppOutcome is one apps[] entry Apply resolved and installed.

type BundleOutcome

type BundleOutcome struct {
	Ref    string
	Bundle bundles.Bundle
	// Policy is nil when Ref resolved to a local directory — nothing was
	// verified.
	Policy *trust.PolicyResult
}

BundleOutcome is one bundles[] entry Apply resolved and installed.

type Manifest

type Manifest struct {
	Plugins []string
	Apps    []string
	Bundles []string
}

Manifest is the parsed content of a provisioning file: three lists of bare reference strings, one per package kind. Each entry is resolved exactly as the equivalent `<kind> install <ref>` command would resolve it:

  • plugins: a local file (raw executable or .patchcord-plugin package), or a github.com/<owner>/<repo>[@<tag>] reference (ADR-0067);
  • bundles: a local file (.patchcord-bundle package) or directory (unpacked source, dev-style), or an "id[@version]" reference resolved against configured registries (ADR-0044);
  • apps: a local file (.patchcord-app package) or directory (unpacked source, dev-style) only — registry/GitHub resolution for a standalone app is not wired up yet, matching `app install`'s own current scope.

There is no separate version field: a reference already pins an exact version (a local file, a "@version"/"@tag" suffix) or names a specific local directory, so nothing here can silently float to a newer release the manifest's author did not intend.

func LoadManifest

func LoadManifest(path string) (*Manifest, error)

LoadManifest reads and parses a provisioning manifest from path.

func ParseManifest

func ParseManifest(source []byte) (*Manifest, error)

ParseManifest parses a provisioning manifest from its YAML source, returning ErrInvalidManifest if any entry is empty. An empty or all-absent manifest is valid — Apply then has nothing to do.

type Options

type Options struct {
	// RequireSignature rejects any resolved package that is unsigned or
	// signed by a key not trusted for its id — the same flag `plugin
	// install`/`app install`/`bundle install` already expose, applied
	// uniformly to every entry in the manifest. It has no effect on a raw
	// executable or a local directory: there is nothing to verify, and
	// giving it alongside such an entry is an error (mirroring `plugin
	// install`'s own behavior for a raw executable path).
	RequireSignature bool
	// GitHubToken raises GitHub's unauthenticated API rate limit for a
	// github.com/<owner>/<repo> plugin reference. Optional.
	GitHubToken string
}

Options configures Apply.

type PluginOutcome

type PluginOutcome struct {
	Ref   string
	Entry plugins.CatalogEntry
	// Policy is nil when Ref resolved to a raw executable — nothing was
	// verified.
	Policy *trust.PolicyResult
}

PluginOutcome is one plugins[] entry Apply resolved and installed.

type Result

type Result struct {
	Plugins []PluginOutcome
	Bundles []BundleOutcome
	Apps    []AppOutcome
}

Result summarizes everything Apply installed, in manifest order.

func Apply

func Apply(ctx context.Context, db *sql.DB, dataDir string, m *Manifest, opts Options) (Result, error)

Apply reconciles m against db/dataDir's catalogs: every plugins[] entry first (a bundle's requires_plugins dependency must already be installed, ADR-0042), then every bundles[] entry, then every apps[] entry. Each install goes through exactly the primitive its `<kind> install` CLI command already uses — plugins.Install/InstallPackage (already an upsert), bundles.InstallDir/InstallPackage (idempotent on unchanged content, ADR-0053/0044), apps.InstallOrUpdate/InstallOrUpdatePackage (upsert, ADR-0073 for the packaged half) — so re-running Apply against an already-satisfied manifest is a clean no-op. That property is what makes it safe to call from every container build and every restart: baking a deployment's custom plugins/apps/bundles into an image, or reconciling a bind-mounted deployment before a restart, is the same call either way.

A failure stops at the first failing entry — there is no rollback across entries or across kinds, mirroring bundles.InstallPackage's own documented limitation. The returned error names the failing reference; the partial Result still describes whatever was already installed before the failure.

Jump to

Keyboard shortcuts

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