Documentation
¶
Overview ¶
Package provider holds the platform provider catalog (ADR-0082) and the add-on-provider management runtime (ADR-0087, FEAT-0003/F57).
The provider catalog is the blueprint provider model in code. A provider is a shared platform capability endpoint — funcd's wasmCloud-style capability provider (a binding is the link, a port + ≥2 drivers the contract) — in two tiers: built-in (in-daemon, pure-Go, trusted core) and add-on (an out-of-daemon deployed service function). A Descriptor names a provider's existing ADR-0019 four-part shape (CRD + facade + controller + port + drivers); the provider catalog only classifies and replaces no facade, port or driver.
The runtime is the mechanism funcd uses to deploy and supervise a curated engine image (DuckDB/Quack today; a vector DB, an inference server tomorrow) as a governed, gateway-exposed, health-probed service. It is PURE-GO orchestration over the EXISTING ports — the container-execution port (internal/runtime, ADR-0032/0054) and the ingress gateway (internal/gateway, ADR-0013). It is NOT the Function controller and imposes NO Function shape gate (ADR-0020): a provider has no user artifact/handler — the curated image's entrypoint IS the engine — and serves its own protocol with its own HTTP readiness probe, not the funcd shim's /health/readiness.
A per-provider reconciler (the F48 Lake first) assembles a ProviderSpec and calls Converge on every reconcile; Converge is re-entrant + idempotent and a crashed engine is recreated on the next pass (supervision = re-convergence, no separate watchdog). Teardown stops and removes every engine replica and removes any programmed route.
Index ¶
- func EgressTo(rawURL string) (fence []netip.AddrPort, ok bool)
- func ResolveEnv(ctx context.Context, d EnvDeps, ns v1.NamespaceName, ...) (map[string]string, error)
- type Catalog
- type Deps
- type Descriptor
- type EnvDeps
- type Kind
- type ProviderRef
- type ProviderSpec
- type ProviderStatus
- type ReadinessProbe
- type ResourceSpec
- type RouteSpec
- type Runtime
- type SecretResolver
- type StorageSpec
- type Volumes
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func EgressTo ¶ added in v0.26.0
EgressTo is the fence of an engine that dials only rawURL (ADR-0269): its address and port, with the scheme's port when it names none. An empty rawURL is an empty fence. ok is false when the host is not an IP literal, which a fence cannot hold.
func ResolveEnv ¶
func ResolveEnv(ctx context.Context, d EnvDeps, ns v1.NamespaceName, config, secretNames []v1.ObjectName) (map[string]string, error)
ResolveEnv delegates to envresolve.ResolveEnv (ADR-0093 relocated the shared config+secret resolver to internal/envresolve so the Function reconciler + providers share one path). The lake controller keeps calling provider.ResolveEnv; behavior is unchanged.
Types ¶
type Catalog ¶
type Catalog struct {
// contains filtered or unexported fields
}
Catalog is the immutable registry of platform providers (ADR-0002: no package-level mutable state). Build it with New; query it with All / ByKind / Get.
func New ¶
func New(ds ...Descriptor) (*Catalog, error)
New builds a Catalog: it runs Validate on each descriptor, then rejects a duplicate Name — fault.Invalid on either. Descriptors are stored sorted by Name so All / ByKind are stable.
func (*Catalog) All ¶
func (c *Catalog) All() []Descriptor
All returns every descriptor in stable Name order.
func (*Catalog) ByKind ¶
func (c *Catalog) ByKind(k Kind) []Descriptor
ByKind returns the descriptors of one tier, in stable Name order.
type Deps ¶
type Deps struct {
// Runtime is the existing container port (internal/runtime, ADR-0032/0054): Create/Start/
// Status/Stop/Remove/List. Required.
Runtime containerrt.Runtime
// OwnerKind is the kind whose engines this runtime runs (ADR-0152): every engine it creates carries it, and
// Converge and Teardown act only on workers of this kind. Required.
OwnerKind v1.Kind
// Gateway is the ingress reverse-proxy (ADR-0013) — ProgramRoutes is replace-all; used only
// when a Route is set. Optional: a nil gateway means an internal-only deployment (a provider
// that declares a Route then is reported Ready but unexposed, with a logged warning).
Gateway gateway.Gateway
Logger *slog.Logger
// HTTPClient probes ReadinessProbe; nil ⇒ a node client bounded by ProbeTimeout.
HTTPClient *http.Client
// ProbeTimeout bounds one readiness probe (lake.engineProbeTimeout, ADR-0163); 0 ⇒ defaultProbeTimeout. Ignored
// when HTTPClient is set.
ProbeTimeout time.Duration
// StorageRoot is the root of the engines' durable directories (ADR-0231); "" ⇒ no durable storage, so a spec with
// Storage fails Invalid.
StorageRoot string
// Now is the clock ProviderSpec.MaxAge is measured with (ADR-0270); nil ⇒ time.Now.
Now func() time.Time
}
Deps wires the runtime over the EXISTING ports — no new execution/routing model, no new driver.
type Descriptor ¶
type Descriptor struct {
Name string // stable id, e.g. "kv", "blob", "ingress", "s3", "log-ingest"
Kind Kind // built-in | add-on
Port string // the contract: the port/interface name (e.g. "kvstore.KV"); "" for an infra provider with no function-facing port
Bindings []string // how a function consumes it (e.g. ["spec.bindings.kv"]); nil for infra (ingress/egress)
Summary string // one-line human description
}
Descriptor names ONE platform provider — the umbrella over its ADR-0019 four-part shape (CRD + facade + controller + port + drivers). It is classification metadata, not a runtime handle: a descriptor in the catalog means the provider is recognized, not that it is running.
func (Descriptor) Validate ¶
func (d Descriptor) Validate() error
Validate checks a descriptor is well-formed: a non-empty Name and a valid Kind.
type EnvDeps ¶
type EnvDeps struct {
Secrets SecretResolver // ADR-0057 PDP-authorized secret resolution (nil ⇒ secrets unsupported)
Store store.Store // ConfigMap reads
Identity func(v1.NamespaceName) auth.Identity // the secret-injector identity for the read
Logger *slog.Logger // nil-tolerated (the guarded-merge silently drops)
}
EnvDeps carries what provider env-resolution needs; a controller supplies its own instances. Kept as the provider facade so the lake controller is untouched (ADR-0093); it maps 1:1 to envresolve.Deps, which ResolveEnv delegates to.
type ProviderRef ¶
type ProviderRef struct {
Namespace v1.NamespaceName
Name v1.ObjectName
}
ProviderRef is the (namespace, name) identity of one provider instance (ADR-0087). It is the one identity the provider has: the ADR-0085 keypair is derived from it, and it is the value a Bucket prefix names as `owner` to grant the engine write.
type ProviderSpec ¶
type ProviderSpec struct {
Ref ProviderRef // (namespace, name) — identity of the provider instance
Image string // the curated engine image ref (ADR-0054 embedded set), e.g. funcd/runtime-duckdb
Port int // the serving port the engine binds in its netns (e.g. 8080)
Env map[string]string // injected env (the ADR-0085 keypair, the engine token, config) — caller-assembled
Readiness ReadinessProbe // the engine's HTTP readiness probe
Replicas int // pinned count (1 for a stateful single-writer engine); 0 is invalid here
Resources ResourceSpec // cpu/mem sizing (forward-compat, mirrors ADR-0086)
// Route is OPTIONAL ingress exposure. Non-nil ⇒ program a gateway route once Ready (behind the
// gateway's auth; eventually externally reachable). nil ⇒ INTERNAL-ONLY: no route is programmed;
// the engine is reachable by in-platform clients via the published netns endpoint
// (ProviderStatus.Address).
Route *RouteSpec
// Storage is OPTIONAL durable storage (ADR-0231); nil ⇒ the engine keeps nothing across re-creations.
Storage *StorageSpec
// EgressOnly is copied to the engine's WorkerSpec: nil means no fence (ADR-0269).
EgressOnly []netip.AddrPort
// MaxAge, when positive, makes Converge replace a running engine older than it, so a new one carries a fresh key
// pair (ADR-0270). 0 ⇒ never replaced for age.
MaxAge time.Duration
// IssueEnv, when set, returns env issued with each engine as Converge creates it, laid over Env: a key pair valid
// for that engine's life (ADR-0270 Decision 5). Only its keys are part of the spec an engine is compared by (#1195),
// so a new key window replaces no engine, while gaining or losing a pair does.
IssueEnv func() map[string]string
}
ProviderSpec is the desired state of one add-on-provider engine, assembled by a per-provider reconciler. The Env is caller-assembled (the ADR-0085 keypair, the engine token, config) — the runtime puts it verbatim on the worker; it owns no engine-specific logic.
type ProviderStatus ¶
type ProviderStatus struct {
Running int // engine replicas running
Ready bool // the readiness probe passed
Address string // the engine's in-platform netns endpoint "host:port" — set when running (in-platform clients dial this)
Endpoint string // the ingress path clients reach when a Route is programmed; "" if internal-only
Reason string // when not Ready, why (e.g. "EngineNotReady")
Report string // the ready replica's report (runtime.Instance.Report, ADR-0276); only the Lake reads it
}
ProviderStatus is what Converge observes back to the caller (which writes it to its CRD status).
type ReadinessProbe ¶
type ReadinessProbe struct {
Path string // e.g. "/" (Quack's RPC endpoint answers 200 there); GET only
ExpectStatus int // e.g. 200
}
ReadinessProbe is the engine's own HTTP health check (a provider serves its protocol, not the funcd shim). The probe is GET <Path>; the engine is Ready only once it answers ExpectStatus.
type ResourceSpec ¶
type ResourceSpec struct {
CPU string // e.g. "2" (cores); "" ⇒ unset
Memory string // e.g. "4Gi"; "" ⇒ unset
}
ResourceSpec sizes the engine (cpu/mem). Forward-compat, mirrors ADR-0086's recorded sizing; the runtime maps it onto runtime.Limits only when the values are numerically parseable.
type RouteSpec ¶
type RouteSpec struct {
ID string // stable route id (e.g. "<ns>/<name>")
PathPrefix string // the ingress path the engine is exposed at
Host string // optional host match ("" = any host)
}
RouteSpec is the OPTIONAL ingress exposure of a provider (ADR-0087/0013). When a ProviderSpec carries one, the gateway reverse-proxies a matched request to the engine once it is Ready.
type Runtime ¶
type Runtime interface {
Converge(ctx context.Context, spec ProviderSpec) (ProviderStatus, error)
Teardown(ctx context.Context, ref ProviderRef) error
}
Runtime is the add-on-provider runtime. It REUSES the existing runtime.Runtime container port (internal/runtime) + the ingress gateway — it is NOT the Function controller and imposes no Function shape gate. Converge is re-entrant + idempotent: the per-provider reconciler calls it on EVERY reconcile; it (re)creates a missing/failed engine, probes readiness, programs the OPTIONAL ingress route once Ready, and returns status. This re-convergence IS the supervision (restart-on-crash) — no separate watchdog. Teardown stops and removes every engine replica (the driver owns netns cleanup) and removes any programmed route.
func NewRuntime ¶
NewRuntime builds the add-on-provider runtime. Deps.Runtime is required; Gateway is optional (internal-only deployment); HTTPClient defaults to a short-timeout client.
type SecretResolver ¶
type SecretResolver = envresolve.SecretResolver
SecretResolver is the consumer-side seam (ADR-0002 interface placement) provider env-resolution depends on: EnvDeps takes this INTERFACE, not the concrete *secrets.Resolver — the per-provider controller's existing SecretResolver interface value + its test fakes satisfy it structurally. It re-exports envresolve.SecretResolver (the resolver relocated to a neutral leaf, ADR-0093) so the lake controller's wiring is untouched.
type StorageSpec ¶ added in v0.13.0
type StorageSpec struct {
Path string // the mount path inside the engine, absolute
UID int
GID int
}
StorageSpec asks for a durable host directory mounted into the engine (ADR-0231): kept across re-creations, teardowns and daemon restarts, removed only by Volumes.Reclaim. UID and GID are the user the engine's image runs as; the provider's ADR pins them equal to that image's user.
type Volumes ¶ added in v0.13.0
type Volumes interface {
// Reclaim removes ref's directory; Conflict while a container of ref exists; nil when there is none.
Reclaim(ctx context.Context, ref ProviderRef) error
// List returns the engines of the runtime's owner kind that have a directory, sorted.
List(ctx context.Context) ([]ProviderRef, error)
}
Volumes manages the durable directories of one owner kind's engines (ADR-0231). The runtime NewRuntime returns implements it; an owner gets it by a type assertion on its provider.Runtime.