synth

package
v1.0.0-beta.3 Latest Latest
Warning

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

Go to latest
Published: Oct 3, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

Documentation

Overview

Package synth builds an OPM #ModuleInstance CUE value from typed in-memory inputs: caller-supplied identity (name, namespace, values, labels, annotations) against a module the caller already acquired with its staged source.

It covers exactly one artifact. There is no platform synthesis: a platform is a CUE module on disk that imports its catalogs (0019:D5/D6), generated by the frontend and acquired with (*kernel.Kernel).AcquirePlatformFromDir.

It lives under opm/internal/ so it stays off the library's public SemVer surface: [Kernel.SynthesizeInstance] is the one synthesis entry point, and it hands this package the *cue.Context it created for the call, the core release its schema cache pins and the registry mapping. The dependency edge runs synth -> loader (synthesis builds THROUGH loader.LoadDir); loader never imports synth.

Single-build construction (ADR-006): Instance does NOT stitch an instance value together from separate CUE evaluations. It synthesizes a virtual CUE package inside the module's own staged tree — an instance.cue that IMPORTS the module and writes `#module: <import>` plus caller metadata, and a values.cue rendered from the caller's merged values via format.Node — and evaluates it in one build through the same build-and-shape-gate step a directory-acquired instance package runs. There is no cue.Scope/userModule trick and no Go-side FillPath(#config, Values) pre-merge: because the module enters the build by import (one #Image / #Secret closure), the schema's own `unifiedModule = #module & {#config: values}` performs the values merge in CUE. The synthesized and authored paths therefore share one mechanism, so a render bug surfaces in both or neither. See adr/006-single-build-artifact-construction.md.

Schema source of truth: this package never reimplements derivations the CUE schema already owns (instance UUID stamping, components fan-out from #components, auto-secrets injection, standard label stamping). Every derived field flows through unification with the artifact definition the module's own cue.mod/module.cue resolves; the caller supplies only the core version the synthesized import's major is derived from.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Instance

func Instance(cueCtx *cue.Context, coreVersion string, in Input) (cue.Value, *module.Source, error)

Instance builds a #ModuleInstance CUE value by synthesizing an in-memory CUE package INSIDE the acquired module's own staged source tree and evaluating it in a single build (ADR-006), through the same loader.LoadDir build-and-shape-gate path a directory-acquired instance package runs. The module's own (already-tidied at publish time) cue.mod/module.cue is the build's module file, so it — not a fabricated dep list — drives transitive dependency resolution. The synthesized package consists of an instance.cue overlaid under a reserved subdirectory of the module root (importing core and the module's own package, writing `#module: <import>` plus caller-supplied metadata) and — when Values is supplied — a values.cue rendered from it.

Because the module is the build's main module, its own package import resolves LOCALLY (no fabricated dependency, no registry round-trip for the module itself), and the module's transitive imports (core, catalog subpackages, …) resolve through the module's own cue.mod/module.cue. This is why a module that imports a catalog subpackage synthesizes correctly where the previous fabricated-{core, module}-deps approach failed (library#31). The module enters the build by import, so there is no closed-into-closed FillPath and no Go-side value pre-merge: the schema's own `let unifiedModule = #module & {#config: values}` performs the values merge in CUE.

coreVersion is the kernel's core release (its loader's pin, or the release its schema cache resolved); only its major selects the synthesized package's core import. The concrete core version the import resolves to comes from the module's own cue.mod/module.cue, never from this argument.

Instance REQUIRES the module to carry staged source (Module.HasSource()); acquire it via Kernel.AcquireModuleFromRegistry or Kernel.AcquireModuleFromDir. It never fetches from a registry itself.

The function does NOT enforce concreteness and does NOT decode instance metadata. Both live downstream in the kernel's instance processing, which Kernel.SynthesizeInstance chains onto this call (the values merge against #config happens inside the build).

The returned cue.Value carries every schema-derived field automatically: metadata.uuid is computed by uuid.SHA1, components is fanned from the unified module, opm-secrets is added when #Secret instances are present, and the standard module-instance.opmodel.dev/{name,uuid} labels are stamped. Instance stamps only the caller-supplied fields and lets CUE derive the rest.

Alongside the value, Instance returns the staged tree the build evaluated: Root is the module's staged root, Pkg the reserved instance subdirectory, Overlay the module's cloned overlay augmented with the synthesized files (instance.cue, plus values.cue when Values was supplied). The overlay is the clone the build used, never the module's own map, so the caller may retain it and the module may be synthesized again. Kernel.SynthesizeInstance stamps it onto the resulting Instance.Source. Every error path returns a nil tree.

Types

type Input

type Input struct {
	// Module is the source #Module the instance deploys. Required. Its
	// metadata.modulePath / metadata.version identify the published module
	// the synthesized package imports (Instance references the module by
	// import, not by inlining its value), and its staged source is the tree
	// the synthesized package is built inside.
	Module *module.Module

	// Name is the instance name (metadata.name). Required. Must satisfy the
	// schema's #NameType regex; violations surface as a CUE unification error
	// from Instance.
	Name string

	// Namespace is the target namespace (metadata.namespace). Required.
	Namespace string

	// Values is the merged configuration value unified against the module's
	// #config. The zero cue.Value signals "no values supplied" — the schema's
	// values path is left unfilled and concreteness is enforced downstream by
	// Kernel.SynthesizeInstance. Instance NEVER falls back to
	// Module.debugValues; that is a frontend policy concern.
	Values cue.Value

	// Labels and Annotations layer over the schema's stamped
	// module-instance.opmodel.dev/{name,uuid} labels. CUE unification merges
	// caller-supplied entries with schema-stamped ones; caller-supplied keys
	// MUST NOT collide with the schema's reserved keys.
	Labels      map[string]string
	Annotations map[string]string

	// Env is the environment slice the synthesized build's load configuration
	// consults — the kernel's CUE_REGISTRY mapping via cueenv.Override, nil to
	// read the process environment unchanged. It is kernel plumbing, not a
	// caller-facing knob: Kernel.SynthesizeInstance fills it from WithRegistry.
	Env []string
}

Input is the typed input carried into Instance. Required fields: Module (source-carrying), Name, Namespace. Optional fields are filled into the instance only when present (non-nil / non-empty / non-zero); empty values do not displace schema-derived fields.

It carries no schema cache and no *cue.Context: the kernel owns the schema cache and hands this package its core release (the loader's pin, or the release its cache resolved) together with the context it created for the call.

Jump to

Keyboard shortcuts

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