Documentation
¶
Overview ¶
Package plugin defines versioned contracts for built-in and executable operations.
Index ¶
- Constants
- func Detail(text string) slog.Attr
- func Logger(ctx context.Context) *slog.Logger
- func ProgressReader(ctx context.Context, reader io.Reader, total int64) io.Reader
- func Register[I, O any](registry *Registry, operation Operation, ...) error
- func SchemaFor[T any]() *jsonschema.Schema
- func Serve(ctx context.Context, in io.Reader, out io.Writer, registry *Registry) error
- func Stage(ctx context.Context, message string, attrs ...any) func(error, ...any)
- func ValidOperationName(name string) bool
- func ValidateDescriptor(descriptor Descriptor) error
- func ValidateOperation(operation Operation) error
- func ValidateSchema(schema, data json.RawMessage) error
- func WithLogger(ctx context.Context, logger *slog.Logger) context.Context
- type AppFacts
- type Artifact
- type Change
- type ContentContract
- type ContentRequest
- type Description
- type Descriptor
- type Download
- type Facts
- type Handler
- type Identity
- type Input
- type InstallerFacts
- type MSIFacts
- type MinimumOS
- type Notice
- type Operation
- type PackageFacts
- type ReconcileRequest
- type ReconcileResponse
- type Registry
- type Request
- type Requirement
- type ResolveRequest
- type ResolveResponse
- type ResolverKind
- type ResourceKind
- type ResourceOutputReference
- type ResourceReference
- type ResourceRequest
- type ResourceResult
- type Response
- type Retention
- type SourceContent
- type Subject
- type SubjectSelector
- type Unavailable
Constants ¶
const ( ResolveInterface = 3 ResourceInterface = 3 ReconcileInterface = 3 )
Interface versions of the operation kinds this SDK implements. A kind's version covers its requests and responses, the operation fields it uses and the framing both travel in; it changes whenever a plugin built against the previous version would misread a request or answer in a way the host misreads. Stemma uses a plugin's operations of a kind only while the plugin implements that kind at the host's version.
const FactsVersion = 1
FactsVersion identifies the model used for observed artifact evidence.
Variables ¶
This section is empty.
Functions ¶
func Detail ¶ added in v0.4.0
Detail is short text shown beside a stage: the file, repository or host it works on, or the version, size or count it found. It must not carry credentials, query strings or response bodies.
func Logger ¶ added in v0.2.0
Logger returns the operation logger, or a silent logger for library callers. Log only deliberate diagnostics; configuration, bindings and HTTP bodies may contain credentials and must never be logged.
func ProgressReader ¶ added in v0.2.0
ProgressReader reports bytes consumed without buffering or changing read errors. A non-positive total means the size is unknown. Counts describe transfer, not subsequent verification or acceptance by a remote service.
func Register ¶ added in v0.3.0
func Register[I, O any](registry *Registry, operation Operation, handle func(context.Context, I) (O, error)) error
Register derives an operation's input, configuration and output contracts from its handler. The framework applies defaults and validates configuration before calling the handler, including on locked requests. Destination validate requests carry no connection settings, so their configuration is not checked.
func SchemaFor ¶ added in v0.3.0
func SchemaFor[T any]() *jsonschema.Schema
SchemaFor derives a closed contract from Go's JSON fields. Optional fields use omitempty or omitzero; jsonschema tags add constraints, defaults and descriptions. Types can use invopop's JSONSchemaExtend hook for enums and semantic annotations.
func Serve ¶
Serve handles one bounded JSON request, streaming log records followed by one response. A request it cannot handle is answered with an error response and returned, so the host reads why; describe is answered whatever else its request carries. Handler errors retain partial output. Stdout belongs to the protocol.
func Stage ¶ added in v0.2.0
Stage starts an operation and returns its completion function. Attributes describe the operation; call the function with the operation error and optional attributes that describe its result. Progress displays show a Detail beside the operation: its subject while it runs, then its outcome. Nested stages finish independently of their enclosing operation. The first completion call wins; subsequent calls have no effect.
func ValidOperationName ¶ added in v0.2.0
ValidOperationName reports whether name uses lowercase operation namespaces separated by dots, underscores, slashes or hyphens.
func ValidateDescriptor ¶ added in v0.2.0
func ValidateDescriptor(descriptor Descriptor) error
ValidateDescriptor checks a provider's identity and operation contracts, and that it names the interface version of each kind its operations use.
func ValidateOperation ¶ added in v0.2.0
ValidateOperation checks a contract without registering or executing a handler.
func ValidateSchema ¶ added in v0.2.0
func ValidateSchema(schema, data json.RawMessage) error
ValidateSchema validates data against a self-contained JSON Schema. Schemas default to draft 2020-12. External network and filesystem resources are disabled.
Types ¶
type AppFacts ¶ added in v0.2.0
type AppFacts struct {
BundleID string `json:"bundle_id,omitempty"`
Name string `json:"name,omitempty"`
Version string `json:"version,omitempty"`
Build string `json:"build,omitempty"`
Executable string `json:"executable,omitempty"`
IconFile string `json:"icon_file,omitempty"`
IconName string `json:"icon_name,omitempty"`
MinimumOS string `json:"minimum_os,omitempty"`
// Architectures names the CPU architectures of the main executable, such
// as arm64 and x86_64. It is absent when they are unknown: the executable
// is missing, a link or not a Mach-O binary.
Architectures []string `json:"architectures,omitempty"`
}
AppFacts preserves an application's short version and build independently.
func (AppFacts) VersionKey ¶ added in v0.3.0
VersionKey selects the Info.plist key holding the application's comparable version when none is configured. Like Munki, it prefers CFBundleShortVersionString unless that value does not begin with a digit and CFBundleVersion is available.
type Artifact ¶
type Artifact struct {
// Encoding is "tar" for a tree leased as its canonical TAR bytes.
// Filename and Mode still describe the logical root directory.
Encoding string `json:"encoding,omitempty"`
ContentRoot string `json:"content_root,omitempty"`
Mode uint32 `json:"mode,omitempty"`
EntryPoint string `json:"entry_point,omitempty"`
Evidence map[string]json.RawMessage `json:"evidence,omitempty"`
Path string `json:"path,omitempty"`
SHA256 string `json:"sha256"`
Size int64 `json:"size"`
Filename string `json:"filename"`
Format string `json:"format,omitempty"`
Tree bool `json:"tree,omitempty"`
Version string `json:"version,omitempty"`
Facts Facts `json:"facts,omitzero"`
}
Artifact describes immutable content. Path is present only when the engine leases bytes to an invocation, never a writable cache object. Version is selected by a consumer; Facts retain observed versions.
type Change ¶
type Change struct {
// Review groups compound initial values using the destination's domain.
// Scalar creations and ordinary field differences need no extra review.
// Before and After retain the complete values for detailed review.
Review []string `json:"review,omitempty"`
// Filename identifies uploaded content separately from its before/after identity.
Filename string `json:"filename,omitempty"`
Kind string `json:"kind"`
Field string `json:"field"`
Action string `json:"action"`
Before json.RawMessage `json:"before,omitempty"`
After json.RawMessage `json:"after,omitempty"`
}
Change is a semantic destination change; an empty Changes list needs no write.
type ContentContract ¶ added in v0.2.0
type ContentContract struct {
Formats []string `json:"formats,omitempty"`
Trees bool `json:"trees,omitempty"`
SourceFree bool `json:"source_free,omitempty"`
}
ContentContract constrains delivered content independently of its originating kind.
func (ContentContract) Accepts ¶ added in v0.2.0
func (contract ContentContract) Accepts(artifact Artifact) error
type ContentRequest ¶ added in v0.11.0
type ContentRequest struct {
Artifact bool `json:"artifact,omitempty"`
Inputs []string `json:"inputs,omitempty"`
}
ContentRequest selects the primary artifact and named inputs to materialize.
type Description ¶ added in v0.4.0
type Description struct {
Descriptor
}
Description is a plugin's answer to describe as this SDK reads it. The embedded Descriptor holds the plugin's identity and the operations this SDK can use; Unavailable holds the ones whose kind the plugin implements at another interface version.
func Describe ¶ added in v0.4.0
func Describe(ctx context.Context, executable string) (Description, error)
Describe runs an executable's describe method and reads its descriptor: first the identity every interface version shares, then, strictly, the operations of each kind the plugin implements at this SDK's version. Other operations are returned as unavailable rather than failing the plugin.
type Descriptor ¶
type Descriptor struct {
Name string `json:"name"`
Version string `json:"version"`
Revision string `json:"revision,omitempty"`
Interfaces map[string]int `json:"interfaces,omitempty"`
Operations []Operation `json:"operations"`
}
Descriptor is a provider's answer to describe. Name, Version, Revision and Interfaces, and each operation's name, kind and resource, keep their meaning across interface versions, so any host can tell what a plugin offers; the rest of an operation belongs to its kind's interface. Revision is the VCS revision recorded in the executable's build information.
type Download ¶ added in v0.9.0
type Download struct {
URL string `json:"url"`
Headers map[string]string `json:"headers,omitempty"`
Filename string `json:"filename,omitempty"`
SHA256 string `json:"sha256,omitempty"`
}
Download is a transient HTTP acquisition request returned by run. It may contain credentials or expiring URLs; the host never persists it in a lock. Credentials and custom headers are confined to the request origin. The host never executes content.
type Facts ¶ added in v0.2.0
Facts retains separately identified subjects instead of collapsing their versions.
type Identity ¶
type Identity struct {
Project string `json:"project"`
Resource ResourceReference `json:"resource"`
Destination string `json:"destination"`
}
Identity identifies a logical destination independently of its display metadata.
type Input ¶ added in v0.2.0
type Input struct {
Base string
Resolver string
Config map[string]any
Resource *ResourceOutputReference
}
Input selects a resolver or a resource output. Every field beside resolver is the resolver's configuration, which stays opaque to the resource scheduler. A url or path alone selects the HTTP or filesystem resolver.
func (Input) JSONSchema ¶ added in v0.2.0
func (Input) JSONSchema() *jsonschema.Schema
JSONSchema distinguishes resource references from dynamic resolver declarations. The catalog composer binds the latter to the loaded registry.
func (Input) MarshalJSON ¶ added in v0.3.0
func (*Input) UnmarshalJSON ¶ added in v0.2.0
type InstallerFacts ¶ added in v0.3.0
type InstallerFacts struct {
Version string `json:"version,omitempty"`
MinimumOS string `json:"minimum_os,omitempty"`
RestartAction string `json:"restart_action,omitempty"`
}
InstallerFacts records an installer's static declarations without evaluating its scripts. Version is a Distribution's product version.
type MSIFacts ¶ added in v0.2.0
type MSIFacts struct {
ProductCode string `json:"product_code,omitempty"`
ProductVersion string `json:"product_version,omitempty"`
ProductName string `json:"product_name,omitempty"`
Manufacturer string `json:"manufacturer,omitempty"`
UpgradeCode string `json:"upgrade_code,omitempty"`
PackageCode string `json:"package_code,omitempty"`
Properties map[string]string `json:"properties,omitempty"`
}
MSIFacts preserves MSI database identity and its native property names.
type MinimumOS ¶ added in v0.3.0
MinimumOS is the software's declared minimum_os, or else the latest of the installer's requirement and the primary application's. Origin names the one that set Version: software.minimum_os, installer.minimum_os or app.minimum_os.
type Notice ¶ added in v0.10.1
type Notice struct {
Level string `json:"level"`
Code string `json:"code"`
Message string `json:"message"`
Hint string `json:"hint,omitempty"`
}
Notice is advice about a resource, independent of progress and success. Level is "warning" or "info"; Code identifies the rule for machine consumers. Hint adds a next step, or what in the resource the notice concerns.
type Operation ¶ added in v0.2.0
type Operation struct {
// TarInputs accepts tree inputs as canonical TAR files instead of directories.
TarInputs bool `json:"tar_inputs,omitempty"`
Resolver *ResolverKind `json:"resolver,omitempty"`
Resource *ResourceKind `json:"resource,omitempty"`
Content *ContentContract `json:"content,omitempty"`
Requirements []Requirement `json:"requirements,omitempty"`
Name string `json:"name"`
Kind string `json:"kind"`
ConfigSchema json.RawMessage `json:"config_schema,omitempty"`
MetadataSchema json.RawMessage `json:"metadata_schema,omitempty"`
RequiresInspection bool `json:"requires_inspection,omitempty"`
InputSchema json.RawMessage `json:"input_schema"`
OutputSchema json.RawMessage `json:"output_schema"`
Platforms []string `json:"platforms,omitempty"`
SideEffects string `json:"side_effects"`
Methods []string `json:"methods"`
}
Operation advertises a capability. Kind is resolve, resource or reconcile. Empty Platforms means portable; otherwise entries are GOOS/GOARCH pairs. SideEffects is none, workspace, or remote. Methods contains discover, validate, run, plan, or apply; describe is implicit. ConfigSchema constrains declared configuration independently of runtime inputs; providers must supply it when configuration is constrained. RequiresInspection requests facts for the primary reconciliation artifact.
func (Operation) SupportsMethod ¶ added in v0.2.0
SupportsMethod reports whether the operation declares this invocation method.
func (Operation) SupportsPlatform ¶ added in v0.2.0
SupportsPlatform reports whether the operation supports this runner.
type PackageFacts ¶ added in v0.2.0
type PackageFacts struct {
Identifier string `json:"identifier,omitempty"`
Version string `json:"version,omitempty"`
InstallLocation string `json:"install_location,omitempty"`
InstalledSize int64 `json:"installed_size,omitempty"`
HasPayload bool `json:"has_payload"`
}
PackageFacts describes a package component without asserting installer-script effects.
type ReconcileRequest ¶ added in v0.2.0
type ReconcileRequest[C any] struct { Method string `json:"-"` Identity Identity `json:"identity"` Config C `json:"config,omitempty"` Metadata json.RawMessage `json:"metadata,omitempty"` Artifact Artifact `json:"artifact"` Inputs map[string]Artifact `json:"inputs,omitempty"` MinimumOS *MinimumOS `json:"minimum_os,omitempty"` Peers map[string]json.RawMessage `json:"peers,omitempty"` Prepared bool `json:"prepared,omitempty"` Root string `json:"root,omitempty"` }
ReconcileRequest carries native desired state. Raw JSON retains absent, null, false and empty collections; Config contains provider-owned connection settings. Validate requests omit Config: they check desired state without connecting, and plan and apply check the settings they connect with.
A destination keeps no state between runs: it identifies what it manages from Identity and the destination itself. Peers holds declared metadata for each resource referenced on this connection, keyed by ResourceReference.Key(). MinimumOS is the effective macOS requirement of the software, when known.
type ReconcileResponse ¶ added in v0.2.0
type ReconcileResponse struct {
Content *ContentRequest `json:"content,omitempty"`
Changes []Change `json:"changes,omitempty"`
Origins map[string]string `json:"origins,omitempty"`
Metadata json.RawMessage `json:"metadata,omitempty"`
}
ReconcileResponse carries the changes a run planned or made.
Content requests bytes needed to complete this method. Return it before any writes. The engine retries the method once with verified private copies of all requested artifacts; paths expire when that invocation returns. Apply must observe remote state again and request content if it now needs an upload. Apply always holds the icon input, so it is never requested. Consumers verify the bytes they publish against the artifact identity and the destination's transfer integrity contract.
Validate may return Metadata in the declaration's shape, including derived values and nulls for cleared fields. It excludes destination-assigned values and preserved remote state. Origins names each managed field's source.
type Registry ¶ added in v0.2.0
type Registry struct {
// contains filtered or unexported fields
}
Registry owns a collision-safe set of operation handlers. Registration and dispatch may run concurrently; handlers own their own concurrency requirements.
func New ¶ added in v0.2.0
New creates a provider registry. Register and Handle reject invalid identities.
func (*Registry) Descriptor ¶ added in v0.2.0
func (registry *Registry) Descriptor() Descriptor
Descriptor returns an independent copy with operations sorted by name, naming this SDK's interface version for each kind they use.
type Request ¶
type Request struct {
Operation string `json:"operation,omitempty"`
Method string `json:"method"`
Input json.RawMessage `json:"input,omitempty"`
LogLevel slog.Level `json:"log_level,omitempty"`
}
Request invokes one advertised operation. Describe requests carry only the method.
type Requirement ¶ added in v0.2.0
type Requirement struct {
Command string `json:"command"`
Platforms []string `json:"platforms,omitempty"`
Purpose string `json:"purpose"`
Setup string `json:"setup"`
}
Requirement describes a concrete runner prerequisite, independent of target OS.
type ResolveRequest ¶ added in v0.2.0
type ResolveRequest[C any] struct { Method string `json:"-"` Config C `json:"config,omitempty"` Base string `json:"base,omitempty"` Root string `json:"root,omitempty"` Workspace string `json:"workspace,omitempty"` Observation json.RawMessage `json:"observation,omitempty"` }
ResolveRequest asks discover for the declaration's current observation, without downloading it, and run for the artifact Observation names, reproducing that observation rather than looking up the latest release.
type ResolveResponse ¶ added in v0.2.0
type ResolveResponse struct {
Content *SourceContent `json:"content,omitempty"`
Version string `json:"version,omitempty"`
ContentRoot string `json:"content_root,omitempty"`
Download *Download `json:"download,omitempty"`
Evidence map[string]json.RawMessage `json:"evidence,omitzero"`
Observation json.RawMessage `json:"observation,omitempty"`
Immutable bool `json:"immutable,omitempty"`
Artifact Artifact `json:"artifact,omitzero"`
}
ResolveResponse answers discover with Observation and optional expected Content. Run returns exactly one Download or Artifact for that observation. Immutable promises that the observation always fetches the same bytes, so the host reuses content it fetched for it before instead of calling run.
type ResolverKind ¶ added in v0.2.0
ResolverKind versions an observation contract: within one version, an observation keeps its meaning and an immutable one always fetches the same bytes. Local resolvers also validate the current checkout when consuming a lock, rather than trusting cached bytes.
type ResourceKind ¶ added in v0.2.0
ResourceKind associates a document schema with its preparing operation.
type ResourceOutputReference ¶ added in v0.3.0
type ResourceOutputReference struct {
ResourceReference `yaml:",inline"`
Output string `json:"output,omitempty" yaml:"output,omitempty" jsonschema:"default=installer"`
}
ResourceOutputReference selects an immutable output, defaulting to installer.
type ResourceReference ¶ added in v0.2.0
type ResourceReference struct {
APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty" jsonschema:"default=stemma/v1alpha1"`
Kind string `json:"kind" yaml:"kind" jsonschema:"required,minLength=1"`
Name string `json:"name" yaml:"name" jsonschema:"required,minLength=1"`
}
ResourceReference identifies a resource. An omitted API version means stemma/v1alpha1.
func (ResourceReference) Key ¶ added in v0.2.0
func (r ResourceReference) Key() string
Key returns the canonical apiVersion/kind/name identity.
func (ResourceReference) Validate ¶ added in v0.3.0
func (r ResourceReference) Validate() error
Validate requires an explicit kind and name; neither is inferred from a consumer.
type ResourceRequest ¶ added in v0.2.0
type ResourceRequest[C any] struct { Method string `json:"-"` Config C `json:"config,omitempty"` // Derive names a policy to observe from the inputs instead of enforcing // the configured value: "signature" reports signed or unsigned subjects as evidence. Derive string `json:"derive,omitempty"` Identity ResourceReference `json:"identity"` Inputs map[string]Artifact `json:"inputs,omitempty"` Workspace string `json:"workspace,omitempty"` // Environment contains the immutable process values referenced by delayed // preparation expressions. The host includes them in preparation identity. Environment map[string]string `json:"environment,omitempty"` }
ResourceRequest uses discover to return inputs and publication intentions; run receives only locked, leased inputs and produces immutable outputs.
type ResourceResult ¶ added in v0.2.0
type ResourceResult struct {
// Notices from discovery describe the current declaration, even on cache hits.
Notices []Notice `json:"notices,omitempty"`
Inputs map[string]Input `json:"inputs,omitempty"`
Config json.RawMessage `json:"config,omitempty"`
Destinations map[string]map[string]any `json:"destinations,omitempty"`
// Icon names the catalog asset icons/<name>.png that destinations receive
// as the icon input. Its bytes never take part in preparation.
Icon string `json:"icon,omitempty"`
// MinimumOS is the declared macOS floor. Destinations receive the later of
// it and the prepared software's own requirements, so it never takes part
// in preparation.
MinimumOS string `json:"minimum_os,omitempty"`
Artifacts map[string]Artifact `json:"artifacts,omitempty"`
Subjects map[string]SubjectSelector `json:"subjects,omitempty"`
Requirements []Requirement `json:"requirements,omitempty"`
}
ResourceResult separates preparation configuration from destination metadata, so changing native publication fields cannot invalidate build outputs.
type Response ¶
type Response struct {
Output json.RawMessage `json:"output,omitempty"`
Error string `json:"error,omitempty"`
}
Response retains partial Output when an operation fails, so callers can report the changes it completed.
type Retention ¶ added in v0.2.0
type Retention struct {
Keep int `` /* 230-byte string literal not displayed */
}
Retention keeps the current publication and the most recent others a destination holds for the same software. Providers order that family from the destination's own records and additionally protect native references.
type SourceContent ¶ added in v0.9.0
type SourceContent struct {
SHA256 string `json:"sha256"`
Filename string `json:"filename"`
Tree bool `json:"tree,omitempty"`
Mode uint32 `json:"mode"`
}
SourceContent identifies expected input bytes and their representation, without claiming they have been acquired or verified.
type Subject ¶ added in v0.2.0
type Subject struct {
ID string `json:"id"`
Parent string `json:"parent,omitempty"`
Kind string `json:"kind"`
Path string `json:"path,omitempty"`
InstalledPath string `json:"installed_path,omitempty"`
SHA256 string `json:"sha256,omitempty"`
App *AppFacts `json:"app,omitempty"`
Package *PackageFacts `json:"package,omitempty"`
Installer *InstallerFacts `json:"installer,omitempty"`
MSI *MSIFacts `json:"msi,omitempty"`
}
Subject records containment and path provenance. Path belongs to the inspected artifact; InstalledPath is an installation location, never a runner lookup path.
func SelectSubject ¶ added in v0.2.0
func SelectSubject(facts Facts, selector SubjectSelector) (Subject, error)
SelectSubject requires one match. Every supplied criterion applies to the same subject.
type SubjectSelector ¶ added in v0.2.0
type SubjectSelector struct {
Kind string `` /* 206-byte string literal not displayed */
Path string `` /* 143-byte string literal not displayed */
InstalledPath string `` /* 158-byte string literal not displayed */
BundleID string `` /* 152-byte string literal not displayed */
PackageID string `` /* 144-byte string literal not displayed */
}
SubjectSelector matches observed evidence; an installation path is not a copy instruction.
type Unavailable ¶ added in v0.4.0
type Unavailable struct {
}
Unavailable names an operation this SDK cannot use and why. Only the operation's identity is read, so a host can report it where it is used.