function

package
v0.1.4 Latest Latest
Warning

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

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

Documentation

Overview

Package function is the Function lifecycle reconciler (ADR-0020): the one controller.Reconciler for KindFunction. It stamps immutable Revisions, schedules + provisions workeres via the runtime port to the EFFECTIVE desired replica count (honoring the activator's wake Status.Phase, not blindly spec.replicas), validates the shape (materialization gate — no route to a broken function), programs the gateway with the FULL route table (gateway.ProgramRoutes is replace-all), and writes status. It also provides the production activator.Endpoints (the seam ADR-0016 deferred to P-M).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ArtifactResolver

type ArtifactResolver interface {
	Resolve(ctx context.Context, uri string) (digest string, err error)
}

ArtifactResolver resolves an OCI artifact ref (tag) to its digest (ADR-0035), so the reconciler can pin it into the immutable Revision at stamp time instead of the user typing it. The oras driver implements it; the file driver needs none (file:// has no digest). Optional in Deps: nil → no resolution (file/legacy mode).

type Deps

type Deps struct {
	Store     store.Store
	Runtime   runtime.Runtime
	Scheduler scheduler.Scheduler
	Gateway   gateway.Gateway
	Validator ShapeValidator
	Logger    *slog.Logger
	// Materializer + ShimCommand enable real function execution (ADR-0030): the
	// reconciler materializes the artifact and launches the runtime shim, and gates
	// readiness on the shim's /health/readiness. When Materializer is nil the reconciler
	// runs the legacy long-lived placeholder (ADR-0020) — used by the runtime-port tests.
	Materializer Materializer
	ShimCommand  []string // launch prefix for the DEFAULT shim, e.g. ["node", "/.../shim.mjs"]
	// ShimCommandsByFamily maps a runtime-family prefix → its shim launch prefix (ADR-0049): a
	// function whose spec.runtime starts with the key (e.g. "python") is launched with that
	// command instead of ShimCommand. Empty ⇒ every runtime uses the default ShimCommand (node).
	ShimCommandsByFamily map[string][]string

	// Resolver (ADR-0035) resolves an OCI artifact ref → digest at Revision-stamp time, so
	// the user need not pin the digest. nil → no resolution (file:// dev / legacy mode).
	Resolver ArtifactResolver

	// EndpointMode + ImageFor select container execution (ADR-0032). EndpointLoopback
	// (default) is the process driver: ShimCommand launches the shim, loopback+portfile.
	// EndpointNetnsFixedPort is the containerd driver: the shim is the curated IMAGE's
	// entrypoint (Command empty), the artifact is bind-mounted, and it binds a fixed port
	// on the netns IP. ImageFor maps fn.Spec.Runtime → the curated image ref.
	EndpointMode EndpointMode
	ImageFor     func(runtime string) string

	// PoolShimCommand enables worker pooling (ADR-0046): the launch prefix for the pooled
	// worker_threads host (e.g. ["node", "/.../pool.mjs"]). When set, a function declaring
	// spec.pooling.worker co-locates with same-key peers in one pool worker launched with
	// this command + FUNCD_POOL_MANIFEST. Empty ⇒ pooling is off (every function is solo).
	PoolShimCommand []string
	// PoolShimsByFamily maps a runtime-family prefix → its pool-host launch prefix (ADR-0050): a
	// python* function that opts in co-pools via this host (the subinterpreter pool.py) instead of
	// staying solo. Empty ⇒ only PoolShimCommand (node) pools; a family with no host runs solo.
	PoolShimsByFamily map[string][]string
	// PoolLimit caps handlers per pool worker (ADR-0046 Decision 3); 0 ⇒ the default (16).
	PoolLimit int

	// Secrets resolves a function's bound Secret names → an env-var map injected into the
	// worker (ADR-0057, F15 last mile). nil ⇒ secret injection disabled: a function declaring
	// spec.secrets fails closed (SecretResolveFailed). Satisfied by *secrets.Resolver.
	Secrets SecretResolver
	// DeveloperFor returns the identity the PDP authorizes for a namespace's secret reads
	// (ADR-0057 Decision 4). Defaulted to the namespace-scoped developer identity when Secrets
	// is set and this is nil; ignored when Secrets is nil.
	DeveloperFor func(ns v1.NamespaceName) auth.Identity

	// InvokeSockets provisions the per-function worker-node local API (ADR-0064) and yields the
	// socket path the reconciler sets as FUNCD_INVOKE_SOCKET. nil ⇒ fn-to-fn links off.
	InvokeSockets InvokeSocketProvider

	// S3Gateway, when Enabled, injects a per-function SigV4 keypair + endpoint into the worker
	// env (ADR-0085) for a function that declares spec.blob — AWS_ACCESS_KEY_ID/
	// AWS_SECRET_ACCESS_KEY (DeriveKeypair over Master), AWS_REGION, AWS_ENDPOINT_URL_S3
	// (ListenAddr). A function without spec.blob, or a disabled gateway, gets nothing.
	S3Gateway S3GatewayInjection

	// CatalogMaster is the node master secret the per-function catalog token is derived from (ADR-0137):
	// resolveCatalogEnv injects FUNCD_CATALOG_<ALIAS>_TOKEN = DeriveCatalogToken(master, ns, fn), a
	// MAC-authenticated bearer the catalog PEP proxy verifies (was the shared QUACK_TOKEN). It is the
	// SAME master the S3 gateway derives keypairs from (loaded once at the compose root). nil/empty ⇒ a
	// still-derivable but unverifiable token (the proxy holds the real master); the master is never logged.
	CatalogMaster []byte

	// CatalogExtensionDir, when non-empty, is injected as DUCKDB_EXTENSION_DIRECTORY into a
	// catalog-consumer function's worker env (a function declaring spec.catalogs) so its handler's
	// `LOAD quack`/`ducklake` resolves the curated DuckDB extensions from this dir. It is the dev
	// analogue of the prod bundle's duckdb-ext (ADR-0089): `funcdctl dev` extracts the embedded
	// catalog engine's extensions once and points consumers at them; prod leaves it empty (the
	// bundle carries duckdb-ext under FUNCD_BUNDLE_DIR instead). Empty ⇒ no injection.
	CatalogExtensionDir string

	// SupervisionPeriod is the requeue of a Ready function (ADR-0142); 0 ⇒ controller.SupervisionPeriod.
	SupervisionPeriod time.Duration

	// Calls counts the calls made to each worker (ADR-0143): the resolver records each hand-out and the drain asks
	// whether a demoted revision's worker is idle. nil ⇒ every worker is idle.
	Calls *activator.CallTracker
	// DrainGrace bounds how long a demoted revision's workers drain; 0 ⇒ 30 s (ADR-0143).
	DrainGrace time.Duration
	// HandOutSettle is how long after a hand-out, or after the switch, a worker may still receive a call; 0 ⇒ 2 s.
	HandOutSettle time.Duration
}

Deps configures the Function lifecycle reconciler (internal component, ADR-0002 §1).

type EndpointMode

type EndpointMode int

EndpointMode selects how a worker is ADDRESSED (ADR-0032); it is orthogonal to the Materializer-presence gate that selects the shim path.

const (
	// EndpointLoopback addresses the shim on 127.0.0.1 via the FUNCD_PORTFILE handshake
	// (process driver, ADR-0030).
	EndpointLoopback EndpointMode = iota
	// EndpointNetnsFixedPort addresses the shim on the netns IP at a fixed port (containerd
	// driver, ADR-0032).
	EndpointNetnsFixedPort
)

type FileMaterializer

type FileMaterializer struct{}

FileMaterializer resolves a "file://" (or bare-path) spec.image ref to a local path. It is the no-dependency dev/test driver; production uses the oras driver (ADR-0031).

func NewFileMaterializer

func NewFileMaterializer() *FileMaterializer

NewFileMaterializer builds the local-file Materializer.

func (FileMaterializer) Materialize

func (FileMaterializer) Materialize(_ context.Context, fn *v1.Function) (string, error)

Materialize returns the local filesystem path of the Function's artifact, verifying it exists. It accepts "file:///abs/path", "file://abs/path", or a bare local path.

type InvokeSocketProvider

type InvokeSocketProvider interface {
	SocketFor(ns v1.NamespaceName, name v1.ObjectName) (string, error)
	// Remove stops + deletes the function's local API listener (called from teardown on delete, so
	// the socket lifecycle tracks the Function resource — controller-driven, not leaked).
	Remove(ns v1.NamespaceName, name v1.ObjectName)
}

InvokeSocketProvider supplies the per-function worker-node local API socket path (ADR-0064): the reconciler sets it as FUNCD_INVOKE_SOCKET in the worker env so the shim can dial context.invoke. nil ⇒ fn-to-fn links are off (the env var is unset; invoke fails closed in the shim).

type Materializer

type Materializer interface {
	Materialize(ctx context.Context, fn *v1.Function) (localPath string, err error)
}

Materializer resolves a Function's artifact to a local path the runtime shim reads (ADR-0030). It is a seam: the local-file driver here serves the dev/e2e process path; the OCI/oras driver (ADR-0031) is the production driver of this same interface.

type Reconciler

type Reconciler struct {
	// contains filtered or unexported fields
}

Reconciler is the one controller.Reconciler for KindFunction.

func NewReconciler

func NewReconciler(d Deps) (*Reconciler, error)

NewReconciler builds the Function lifecycle reconciler. The ports are required; Materializer/ShimCommand are optional (set together to enable execution, ADR-0030).

func (*Reconciler) Endpoints

func (r *Reconciler) Endpoints() activator.Endpoints

Endpoints returns the production activator.Endpoints (the seam ADR-0016 deferred to P-M): a function's ready worker upstream.

func (*Reconciler) Reconcile

func (r *Reconciler) Reconcile(ctx context.Context, req controller.Request) (controller.Result, error)

Reconcile converges one Function to its desired state.

type S3GatewayInjection

type S3GatewayInjection struct {
	Enabled    bool
	ListenAddr string
	// Endpoint is the sandbox-facing S3 URL (ADR-0085): the node address a netns'd worker can reach —
	// the CNI bridge gateway IP under containerd. Empty ⇒ derived as http://<ListenAddr> (loopback dev).
	Endpoint string
	// Derive returns the deterministic per-(ns, fn) SigV4 keypair (s3gateway.DeriveKeypair,
	// bound to the node master secret). Required when Enabled.
	Derive func(ns, fn string) (access, secret string)
}

S3GatewayInjection configures the worker-env S3 keypair injection (ADR-0085). Derive computes the per-function (access, secret) from the node master over the Ref — supplied by the wiring (pkg/funcd) so this package stays free of the versitygw dependency the gateway carries; the master secret it closes over is never logged. The zero value (Enabled false) injects nothing.

type SecretResolver

type SecretResolver interface {
	ResolveEnv(ctx context.Context, id auth.Identity, ns v1.NamespaceName, names []string) (map[string]string, error)
}

SecretResolver resolves a function's bound Secret names → an env-var map for worker injection, PDP-authorized for id (ADR-0022/0057). The reconciler depends on this local seam for resolution (ADR-0002 import discipline) — satisfied by *secrets.Resolver, wired in pkg/funcd; it uses internal/secrets only for the pure reserved-key guard (MergeEnvGuarded, no store dep, ADR-0092). A nil resolver on Deps disables secret injection: a function that declares spec.secrets then fails closed (SecretResolveFailed).

type ShapeValidator

type ShapeValidator interface {
	Validate(ctx context.Context, fn *v1.Function) error
}

ShapeValidator validates a Function's artifact conforms to its runtime shape.

func NewBasicValidator

func NewBasicValidator() ShapeValidator

NewBasicValidator returns the V1 spec-well-formedness ShapeValidator (the authoritative load-time materialization is the shim's, on the Linux lane, P-S).

Jump to

Keyboard shortcuts

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