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.
template.go — the App template artifact (ADR-0218, F121): a template directory pushed unchanged as ONE deterministic tar+gzip layer (the ADR-0089 transport, as a site is) under its own artifact type, tagged with the template's version. Only funcdctl pushes and pulls it; the server never reads a template.
Index ¶
- Constants
- func ContractBlob(input, output []byte) ([]byte, error)
- func Inspect(ctx context.Context, ref, digest string) (contract []byte, err error)
- func InspectContract(ctx context.Context, ref, digest string) (contract []byte, resolvedDigest string, err error)
- func InspectRuntime(ctx context.Context, ref, digest string) (runtime string, err error)
- func IsArtifactPlatform(p v1.OCIPlatform) bool
- func IsDigest(reference string) bool
- func ListTags(ctx context.Context, repo string) ([]string, error)
- func Login(ctx context.Context, registry, user, pass string) error
- func Logout(ctx context.Context, registry string) error
- func PackBundle(dir, entry string) (data []byte, err error)
- func Platforms(ctx context.Context, ref, digest string) ([]v1.OCIPlatform, error)
- func Pull(ctx context.Context, ref, digest, dir string, node v1.OCIPlatform) (path string, err error)
- func PullSite(ctx context.Context, ref, digest, dir string) error
- func PullTemplate(ctx context.Context, ref, digest, dir string) error
- func Push(ctx context.Context, ref, file string, contract []byte, runtime string, ...) (digest string, err error)
- func PushBundle(ctx context.Context, ref, dir, entry, runtime string, platform v1.OCIPlatform) (digest string, err error)
- func PushIndex(ctx context.Context, ref string, sources []string) (digest string, err error)
- func PushSite(ctx context.Context, ref, dir string) (digest string, err error)
- func PushTemplate(ctx context.Context, ref, dir, version string) (digest string, err error)
- func ResolveDigest(ctx context.Context, ref string) (string, error)
- func ResolveSite(ctx context.Context, ref string) (digest string, err error)
- func ResolveTemplate(ctx context.Context, ref string) (digest string, err error)
- func VerifyBundleContract(dir, _ string) (contractBlob []byte, err error)
- type OrasMaterializer
- type TagResolver
Constants ¶
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" )
const AppTemplateArtifactType = "application/vnd.funcd.app-template.artifact.v1"
AppTemplateArtifactType marks an OCI manifest as a funcd App template: one BundleTarMediaType layer holding app.yaml, app.lock and resources/*.yaml as git holds them.
const PlatformAnnotation = "dev.funcd.platform"
PlatformAnnotation records, on a function manifest, the platform its bundle was built for (ADR-0145).
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.
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 ¶
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 ¶
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 ¶
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 IsArtifactPlatform ¶ added in v0.2.0
func IsArtifactPlatform(p v1.OCIPlatform) bool
IsArtifactPlatform reports whether `funcdctl push --platform` accepts p.
func IsDigest ¶ added in v0.2.2
IsDigest reports whether a ref's reference part is a digest rather than a tag.
func ListTags ¶ added in v0.11.0
ListTags lists every tag of repo, a registry repository or an oci-layout:// directory, through all pages.
func Login ¶
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 PackBundle ¶
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: any other entry (a symlink, a device) is fault.Invalid, never silently left out. entry must name an existing regular file relative to dir (the handler) — else fault.Invalid.
func Platforms ¶ added in v0.2.0
Platforms lists the platforms the artifact at digest (or at ref's tag when digest is empty) provides: an index's, an annotated manifest's one, or nil for an unannotated manifest, which runs anywhere. An index none of whose manifests names a platform runs nowhere: an error matching scheduler.ErrNoMatchingPlatform.
func Pull ¶
func Pull(ctx context.Context, ref, digest, dir string, node v1.OCIPlatform) (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. When digest names an OCI image index (ADR-0145), the manifest for node ("" ⇒ the daemon's own platform) is used.
func PullSite ¶
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 PullTemplate ¶ added in v0.11.0
PullTemplate fetches the template artifact by digest and unpacks its layer into dir, traversal-safely.
func Push ¶
func Push(ctx context.Context, ref, file string, contract []byte, runtime string, platform v1.OCIPlatform) (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 and a dotfile name (Pull refuses it as a title); 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. A non-empty platform records PlatformAnnotation (ADR-0145); "" records none.
func PushBundle ¶
func PushBundle(ctx context.Context, ref, dir, entry, runtime string, platform v1.OCIPlatform) (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 PushIndex ¶ added in v0.2.0
PushIndex writes an OCI image index over sources — per-platform function manifests in the same repository or layout as ref — tags it from ref and returns its digest (ADR-0145 Decision 2). Every rule is checked before anything is written; a violation is fault.Invalid naming the source. The sources are read without opening the target for writing, so a ref to a directory that holds no layout is fault.NotFound and writes nothing (issue #451).
func PushSite ¶
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 PushTemplate ¶ added in v0.11.0
PushTemplate packs dir as it is into one BundleTarMediaType layer under AppTemplateArtifactType and pushes it to ref, whose tag must be version. Before any write it refuses a ref without a tag, with a digest, or whose tag is not version, and a version tag already at another digest (fault.Conflict); the same digest there writes nothing.
func ResolveDigest ¶ added in v0.11.0
ResolveDigest resolves an OCI artifact ref (its tag, or a digest) to the manifest digest (ADR-0035).
func ResolveSite ¶
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 ResolveTemplate ¶ added in v0.11.0
ResolveTemplate resolves ref (a tag or a digest) to its manifest digest, asserting AppTemplateArtifactType: a site or a function artifact ⇒ fault.Invalid; an absent ref ⇒ fault.NotFound.
func VerifyBundleContract ¶
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, node v1.OCIPlatform) *OrasMaterializer
NewOrasMaterializer builds the OCI-backed Materializer caching under artifactDir, for a node running node ("" ⇒ the daemon's own platform).
func (*OrasMaterializer) Materialize ¶
Materialize resolves fn.spec.image → target, pulls by fn.spec.imageDigest (the authority; empty → fault.Invalid), and returns the cached local path.
func (*OrasMaterializer) Platforms ¶ added in v0.2.0
func (m *OrasMaterializer) Platforms(ctx context.Context, uri, digest string) ([]v1.OCIPlatform, error)
Platforms implements function.PlatformResolver (ADR-0145): the platforms the artifact at digest provides, cached per digest in memory and in the artifact cache dir, so a restarted daemon starts a cached artifact without its source.
type TagResolver ¶ added in v0.11.0
type TagResolver struct{}
TagResolver reads image registries for an App template's lock: it satisfies template.ImageResolver.