artifact

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: 27 Imported by: 0

Documentation

Overview

Package artifact is OCI artifact distribution (ADR-0031): how a function source bundle reaches the platform. funcdctl pushes a bundle as an OCI artifact to a target (a local OCI layout for dev, or a registry for prod) and the platform pulls it by digest. It provides the producer side (Push/Pull/Login/Logout) and the consumer side — an OrasMaterializer that is a driver of ADR-0030's internal/function.Materializer seam.

The artifact is one digest-addressed OCI artifact: a manifest of artifactType application/vnd.funcd.function.artifact.v1 with a single bundle-blob layer. The imageDigest is the manifest descriptor digest and is the authority — pulls are by digest, an empty digest is rejected, and a mutable tag is only a locator.

bundle.go — the multi-file function bundle (ADR-0089): a deployment-package artifact.

A bundle is a directory (handler + vendored native deps + the ADR-0090 I/O contract) pushed as ONE deterministic tar+gzip OCI layer alongside the ADR-0031 single-blob layer (additive — a lone .py/.mjs push is unchanged). The transport machinery here is language-agnostic; only the PYTHONPATH worker env (internal/function) is python-family-gated. The tar is deterministic (entries sorted; mtime/uid/gid/uname/gname zeroed) so identical trees yield an identical digest (ADR-0035 pinning holds), and untar is traversal-safe (a "../"/absolute/symlink-escape path is refused — a security gate).

site.go — the static-site bundle artifact (ADR-0139, F103): a prebuilt web app pushed as ONE deterministic tar+gzip layer (the ADR-0089 transport, reused) under its own artifact type. A site has no I/O contract and no runtime, so the manifest carries no contract blob and no runtime annotation; the distinct type keeps a site from ever being pulled as a function artifact.

Index

Constants

View Source
const (
	// BundleTarMediaType is the multi-file function bundle layer (ADR-0089): a deterministic
	// tar+gzip deployment package (handler + vendored deps). It sits ALONGSIDE the single-file
	// bundleMediaType layer (ADR-0031) — additive, never replacing it.
	BundleTarMediaType = "application/vnd.funcd.bundle.tar+gzip"
	// BundleEntryAnnotation records the handler entry file, relative to the bundle root, on the
	// bundle layer + manifest so Pull/Materialize resolve FUNCD_ARTIFACT to <root>/<entry>.
	BundleEntryAnnotation = "dev.funcd.bundle.entry"
)
View Source
const SiteArtifactType = "application/vnd.funcd.site.artifact.v1"

SiteArtifactType marks an OCI manifest as a funcd static-site bundle: one BundleTarMediaType layer, no contract blob and no runtime annotation (a site has no I/O contract). A distinct type keeps a site from being pulled by the function materializer.

View Source
const VoidSchema = `{"type":"null"}`

VoidSchema is the canonical void side (ADR-0090): a side that carries no meaningful payload is the explicit JSON Schema {"type":"null"} — never an omission. Both sides are always present in the blob; a void side declares itself with this schema, and its validator is compiled from it like any other.

Variables

This section is empty.

Functions

func ContractBlob

func ContractBlob(input, output []byte) ([]byte, error)

ContractBlob assembles the mandatory {dialect, input, output} contract blob (ADR-0090, supersedes ADR-0059's optional form). BOTH input and output must be present and non-empty — a void side is VoidSchema, never nil. Returns fault.Invalid if either is missing; there is no contract-less artifact. The marshaled JSON always serializes both fields (no omitempty).

func Inspect

func Inspect(ctx context.Context, ref, digest string) (contract []byte, err error)

Inspect reads a function's I/O contract straight from its OCI manifest (ADR-0059): it fetches the manifest + the small contract blob ONLY — never the bundle layer, never executing code — and returns the raw contract JSON ({input?, output?, dialect}). It resolves by digest when one is supplied (tamper-evident: the inspected contract == the deployed one); a bare tag is resolved to its current manifest. fault.NotFound when the artifact carries no contract.

func InspectContract

func InspectContract(ctx context.Context, ref, digest string) (contract []byte, resolvedDigest string, err error)

InspectContract is Inspect that also returns the resolved manifest descriptor digest (ADR-0098): the single metadata fetch already yields it, so a caller (the workflow contract-check gate) can record the pinned ref@digest alongside the contract without a second round-trip. Same static-inspection invariant — the bundle bytes are never fetched.

func InspectRuntime

func InspectRuntime(ctx context.Context, ref, digest string) (runtime string, err error)

InspectRuntime reads a function's runtime class straight from its OCI manifest annotation (dev.funcd.runtime.v1, ADR-0094): it fetches the manifest ONLY — never the bundle, never the contract, never executing code — so the workflow materializer can resolve a step image's runtime without pulling it. It resolves by digest when supplied (tamper-evident), else a bare tag. fault.NotFound when the artifact asserts no runtime.

func Login

func Login(ctx context.Context, registry, user, pass string) error

Login stores registry credentials via oras-go's credential store (the local OCI layout needs no login). It verifies the credential against the registry.

func Logout

func Logout(ctx context.Context, registry string) error

Logout removes stored credentials for a registry.

func PackBundle

func PackBundle(dir, entry string) (data []byte, err error)

PackBundle writes dir as a DETERMINISTIC tar+gzip stream: entries are sorted by path and mtime/uid/gid/uname/gname are zeroed, so two identical trees produce byte-identical output (and thus an identical digest — ADR-0035). Only regular files and directories are packed; entry must name an existing regular file relative to dir (the handler) — else fault.Invalid.

func Pull

func Pull(ctx context.Context, ref, digest, dir string) (path string, err error)

Pull fetches the artifact named by ref, verifies it against digest (the authority — empty digest is rejected), and writes the bundle blob into dir, returning its path.

func PullSite

func PullSite(ctx context.Context, ref, digest, dir string) error

PullSite fetches the digest-pinned site artifact and untars its bundle layer into dir using the existing traversal-safe untar (a "../"/absolute/symlink-escape entry is refused). The manifest is fetched BY DIGEST so a moved tag can never change what materializes.

func Push

func Push(ctx context.Context, ref, file string, contract []byte, runtime string) (digest string, err error)

Push packages file as the §1 OCI artifact and pushes it to ref's target (a local OCI layout or a registry), returning the manifest descriptor digest. A light pre-flight rejects an empty bundle; the authoritative shape-gate is the shim (ADR-0030). When contract is non-nil (ADR-0059), it adds a content-addressed contract blob layer + the dev.funcd.contract.v1 manifest annotation; nil ⇒ the unchanged ADR-0031 artifact.

func PushBundle

func PushBundle(ctx context.Context, ref, dir, entry, runtime string) (digest string, err error)

PushBundle packs dir (PackBundle) as a BundleTarMediaType layer with the entry annotation, adds the VerifyBundleContract result as the ADR-0059 contract layer, and pushes it — mirroring Push's oras flow. Returns the manifest descriptor digest.

func PushSite

func PushSite(ctx context.Context, ref, dir string) (digest string, err error)

PushSite packs dir as the deterministic tar+gzip bundle layer (ADR-0089) under SiteArtifactType and pushes it to ref's target, returning the manifest digest. Empty dir ⇒ fault.Invalid. It packs WITHOUT an entry-file gate (a site's index is a reconcile-time spec.index, unknown at push).

func ResolveSite

func ResolveSite(ctx context.Context, ref string) (digest string, err error)

ResolveSite resolves ref (a tag or a digest) to its manifest digest, asserting SiteArtifactType. A function artifact ⇒ fault.Invalid; an absent ref ⇒ fault.NotFound.

func VerifyBundleContract

func VerifyBundleContract(dir, _ string) (contractBlob []byte, err error)

VerifyBundleContract enforces the push-time bundle-contract gate (ADR-0089 §3 / ADR-0090 / ADR-0123): dir/__funcd_contract.json MUST exist and be a valid {input, output} document with BOTH keys present (a void side is {"type":"null"}, never absent) AND each side must lie within the funcd type profile (contract.Check — the same gate the single-file --schema path applies). It no longer requires a baked validator symbol in the entry file: the artifact is schema-only and the runtime shim compiles the validator from the delivered schema at worker warm-up (ADR-0123, supersedes ADR-0060's build-time bake). The `entry` argument is retained for the signature but is no longer read. It returns the {dialect, input, output} blob to promote through the EXISTING ContractBlob path. fault.Invalid on any gap — an out-of-profile schema that slipped through here would otherwise only fail at worker compile-time (cold-start fail-closed).

Types

type OrasMaterializer

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

OrasMaterializer is a DRIVER of ADR-0030's internal/function.Materializer: it pulls a Function's artifact by digest into a per-digest cache dir (immutable) and returns the local path the shim reads. The local-file driver (ADR-0030) stays the no-dep test stand-in.

func NewOrasMaterializer

func NewOrasMaterializer(artifactDir string) *OrasMaterializer

NewOrasMaterializer builds the OCI-backed Materializer caching under artifactDir.

func (*OrasMaterializer) Materialize

func (m *OrasMaterializer) Materialize(ctx context.Context, fn *v1.Function) (string, error)

Materialize resolves fn.spec.image → target, pulls by fn.spec.imageDigest (the authority; empty → fault.Invalid), and returns the cached local path.

func (*OrasMaterializer) Resolve

func (m *OrasMaterializer) Resolve(ctx context.Context, uri string) (string, error)

Resolve resolves an OCI artifact ref (its tag) to the manifest digest (ADR-0035), so the reconciler can pin it into the immutable Revision without the user typing it. It is the ArtifactResolver seam the Function reconciler calls at Revision-stamp time.

Jump to

Keyboard shortcuts

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