Skip to content

Add documentation for FunctionConfig CRD and reconciler (v2) - #1162

Open
mozesl-nokia wants to merge 3 commits into
kptdev:mainfrom
nokia:fnconf-docs-new
Open

Add documentation for FunctionConfig CRD and reconciler (v2)#1162
mozesl-nokia wants to merge 3 commits into
kptdev:mainfrom
nokia:fnconf-docs-new

Conversation

@mozesl-nokia

Copy link
Copy Markdown
Contributor

Add documentation for FunctionConfig CRD and reconciler


Description

  • What changed: Added the documentation for said CRD and reconciler
  • Why it’s needed: Because it was missing when the feature was merged
  • How it works: -

Related Issue(s)


Type of Change

  • Documentation

Checklist

  • Code follows project style guidelines
  • Self-reviewed changes
  • Tests added/updated
  • Documentation added/updated
  • All tests and gating checks pass

Additional Notes (Optional)


AI Disclosure

  • I have used AI in the creation of this PR.

If so, please describe how:

  • Dosu's original suggestions were used as a base
  • Claude Sonnet 5 was used to gather information from the previous version of this change and create a plan
  • Cursor Grok 4.6 was used to actually write the docs

Assisted-by: Cursor:claude-sonnet-5
Assisted-by: Cursor:grok-4.6
Signed-off-by: Mózes László Máté <laszlo.mozes@nokia.com>
@mozesl-nokia
mozesl-nokia requested review from a team August 31, 2026 08:45
@netlify

netlify Bot commented Aug 31, 2026

Copy link
Copy Markdown

Deploy Preview for kpt-porch ready!

Name Link
🔨 Latest commit 0793c64
🔍 Latest deploy log https://app.netlify.com/projects/kpt-porch/deploys/6a95730b8690800008ab8f4c
😎 Deploy Preview https://deploy-preview-1162--kpt-porch.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds missing documentation for the FunctionConfig CRD and how Porch components (porch-server, function-runner, porch-controllers) reconcile and use it, updating existing docs to reflect the current “FunctionConfig + base PodTemplate/ServiceTemplate” model instead of legacy ConfigMap templating.

Changes:

  • Introduces a new “Function Configuration” doc explaining FunctionConfig matching, executors, reconciler behavior, and status fields.
  • Updates Function Runner architecture/design/configuration docs to reference FunctionConfig-driven executor selection and base PodTemplate/ServiceTemplate usage.
  • Enhances install/deployment verification & troubleshooting docs with FunctionConfig checks and status interpretation.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
docs/content/en/docs/6_configuration_and_deployments/deployments/catalog-deployment.md Adds verification/troubleshooting steps for FunctionConfig + base templates after catalog deployment.
docs/content/en/docs/6_configuration_and_deployments/configurations/opentelemetry.md Updates OpenTelemetry guidance to use base-pod-template rather than ConfigMap templating.
docs/content/en/docs/6_configuration_and_deployments/configurations/components/function-runner-config/pod-templates.md Rewrites pod templating docs to describe base PodTemplate/ServiceTemplate + FunctionConfig overrides.
docs/content/en/docs/6_configuration_and_deployments/configurations/components/function-runner-config/function-configuration.md New page documenting the FunctionConfig CRD, reconciler roles, executors, and examples.
docs/content/en/docs/6_configuration_and_deployments/configurations/components/function-runner-config/_index.md Updates Function Runner config overview to emphasize FunctionConfig as the primary per-function configuration source.
docs/content/en/docs/6_configuration_and_deployments/configurations/components/_index.md Adds navigation links for the new Function Configuration and updated Pod Templates docs.
docs/content/en/docs/5_architecture_and_components/function-runner/interactions.md Documents FunctionConfig reconciler/store and updates diagrams/flows to remove ConfigMap templating.
docs/content/en/docs/5_architecture_and_components/function-runner/functionality/pod-lifecycle-management.md Updates pod lifecycle description to base PodTemplate/ServiceTemplate + FunctionConfig overrides.
docs/content/en/docs/5_architecture_and_components/function-runner/functionality/function-evaluation.md Updates evaluator docs to reflect FunctionConfig-backed binary cache and pod settings.
docs/content/en/docs/5_architecture_and_components/function-runner/functionality/_index.md Updates function-runner functionality index to reflect FunctionConfig-driven behavior.
docs/content/en/docs/5_architecture_and_components/function-runner/design.md Updates design rationale to prefer FunctionConfig CRs over a static config file for executable evaluator mapping.
docs/content/en/docs/5_architecture_and_components/engine/interactions.md Updates engine runtime selection description to be FunctionConfig-driven.
docs/content/en/docs/3_getting_started/installing-porch.md Adds FunctionConfig CRD/resource verification steps to installation docs.
docs/content/en/docs/2_concepts/functions.md Adds FunctionConfig-based execution model explanation to the core “Functions” concept doc.
Suppressed comments (1)

docs/content/en/docs/6_configuration_and_deployments/configurations/components/function-runner-config/pod-templates.md:23

  • In the creation flow, the base templates are read from the function-pod namespace configured by --pod-namespace (not always porch-fn-system). Also, the code only patches fn.kpt.dev/template-version and fn.kpt.dev/image; there is no fn.kpt.dev/reclaim-after annotation being set, so mentioning it here is misleading.
1. Gets `base-pod-template` (`corev1.PodTemplate`) and `base-service-template` (`config.porch.kpt.dev/v1alpha1` ServiceTemplate) from `porch-fn-system`. If either is missing, it creates it from the inline default shipped in the binary.
2. Patches the function container with the requested image, the wrapper-server command, the original image entrypoint as arguments, and any image-pull secret required for private registries.
3. Patches pod metadata: `fn.kpt.dev/image` label, `fn.kpt.dev/reclaim-after` TTL annotation, and `fn.kpt.dev/template-version` set to the PodTemplate `resourceVersion`.
4. Merges `spec.podExecutor.templateOverrides` from the FunctionConfig for that image, if any.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread docs/content/en/docs/3_getting_started/installing-porch.md Outdated
Assisted-by: Cursor:grok-4.6
Signed-off-by: Mózes László Máté <laszlo.mozes@nokia.com>
Assisted-by: Cursor:grok-4.6
Signed-off-by: Mózes László Máté <laszlo.mozes@nokia.com>
@sonarqubecloud

Copy link
Copy Markdown

@mozesl-nokia mozesl-nokia added the documentation Improvements or additions to documentation label Sep 1, 2026
The **pod executor** is the default path for arbitrary function images: the function-runner creates (or reuses) a pod, injects a wrapper gRPC server, and runs the function image in isolation.
TTL, parallelism, and pod-spec overrides come from the matching FunctionConfig.
The **binary executor** runs a pre-built binary inside the function-runner process, which avoids pod startup cost.
The **Go executor** calls a compiled-in `ResourceListProcessor` (today: apply-replacements, set-namespace, and starlark) with no extra process at all.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is the "today" needed?

```

A healthy install shows one FunctionConfig per bundled catalog function (apply-replacements, set-namespace, starlark, kubeconform, and others).
The `Server Applied`, `FnRunner Applied`, and `Controller Applied` columns are the generations each component has loaded; they should match the resource generation when the spec is in sync.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The `Server Applied`, `FnRunner Applied`, and `Controller Applied` columns are the generations each component has loaded; they should match the resource generation when the spec is in sync.
The `Server Applied`, `FnRunner Applied`, and `Controller Applied` columns are the generations each component has loaded. They should match the resource generation when the spec is in sync.


The task handler uses function runtimes configured in the engine:
The task handler uses function runtimes configured in the engine.
Which runtime handles a given image is driven by FunctionConfig (see [Function Configuration]({{% relref "/docs/6_configuration_and_deployments/configurations/components/function-runner-config/function-configuration.md" %}})):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FunctionConfig decides which runtimes handles a given image (?)


**Request structure:**
- **Image**: Function container image identifier
- **Tag**: Optional version constraint; when set, evaluators resolve it against cached tags

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- **Tag**: Optional version constraint; when set, evaluators resolve it against cached tags
- **Tag**: Optional version constraint. When set, evaluators resolve it against cached tags.

Everything else is sent over gRPC to the **function-runner**, which tries a local binary from `binaryExecutor` first and falls back to a Kubernetes pod from `podExecutor`.

The **pod executor** is the default path for arbitrary function images: the function-runner creates (or reuses) a pod, injects a wrapper gRPC server, and runs the function image in isolation.
TTL, parallelism, and pod-spec overrides come from the matching FunctionConfig.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
TTL, parallelism, and pod-spec overrides come from the matching FunctionConfig.
Time to Live (TTL), parallelism, and pod-spec overrides come from the matching FunctionConfig.

```

`apiServerObservedGeneration`, `functionRunnerObservedGeneration`, and `controllerObservedGeneration` are the `.metadata.generation` each component last applied.
`error` is set when that component failed to apply the spec; it is cleared on the next successful reconcile.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
`error` is set when that component failed to apply the spec; it is cleared on the next successful reconcile.
`error` is set when that component failed to apply the spec. It is cleared on the next successful reconcile.


The Function Runner automatically patches the template with function-specific configuration before creating pods.
Any custom `base-pod-template` must keep a container named `function`.
That container's command must start the wrapper gRPC server; the function-runner replaces the image and appends the original function entrypoint to `args`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
That container's command must start the wrapper gRPC server; the function-runner replaces the image and appends the original function entrypoint to `args`.
That container's command must start the wrapper gRPC server. The function-runner replaces the image and appends the original function entrypoint to `args`.

An init container named `copy-wrapper-server` is expected as the first init container when `templateOverrides.initContainer` is used, because overrides are merged by index.

## Enabling Pod Templates
The Function Runner patches the template before creating pods. Leave the function image as a placeholder; it is always replaced.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The Function Runner patches the template before creating pods. Leave the function image as a placeholder; it is always replaced.
The Function Runner patches the template before creating pods. Leave the function image as a placeholder. It is always replaced.

The wrapper-server component can be configured with OpenTelemetry settings through the pod templating mechanism used by the function runner. This is done by creating a ConfigMap with a pod template that includes the necessary environment variables.
The wrapper-server can pick up OpenTelemetry settings from the function-runner's base **PodTemplate**.
Edit `base-pod-template` in `porch-fn-system` (see [Pod Templates]({{% relref "/docs/6_configuration_and_deployments/configurations/components/function-runner-config/pod-templates.md" %}})) so the `function` container env includes the exporters you want.
New function pods pick up the change on the next create or template-version replacement; existing pods are not rewritten in place.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
New function pods pick up the change on the next create or template-version replacement; existing pods are not rewritten in place.
New function pods pick up the change on the next create or template-version replacement. Existing pods are not rewritten in place.

- --pod-namespace=porch-fn-system
- --function-pod-template=kpt-function-eval-pod-template
```
No extra function-runner flag is required; the runner always reads `base-pod-template` from `--pod-namespace`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
No extra function-runner flag is required; the runner always reads `base-pod-template` from `--pod-namespace`.
No extra function-runner flag is required. The runner always reads `base-pod-template` from `--pod-namespace`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks great. thanks so much @mozesl-nokia for adding this in. approving with comments as i dont want to block this getting merged in over minor comments. Great Work

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this file need to exist? i understand the deployment.yaml example in the same dir but this is mainly just a readme of how the feature works + pointing to the docs anyway. cant this just be in the docs alone?

Comment on lines +62 to +73
Porch executes functions through the Engine's function runtime.
The builtin runtime (in porch-server and porch-controllers) handles images listed on a FunctionConfig `goExecutor`.
Everything else is sent over gRPC to the **function-runner**, which tries a local binary from `binaryExecutor` first and falls back to a Kubernetes pod from `podExecutor`.

The **pod executor** is the default path for arbitrary function images: the function-runner creates (or reuses) a pod, injects a wrapper gRPC server, and runs the function image in isolation.
TTL, parallelism, and pod-spec overrides come from the matching FunctionConfig.
The **binary executor** runs a pre-built binary inside the function-runner process, which avoids pod startup cost.
The **Go executor** calls a compiled-in `ResourceListProcessor` (today: apply-replacements, set-namespace, and starlark) with no extra process at all.

Regardless of executor, Porch passes the package's resources to [kpt](https://kpt.dev), which passes them on as a [ResourceList](https://github.com/kubernetes-sigs/kustomize/blob/master/cmd/config/docs/api-conventions/functions-spec.md#resourcelist) to each function in the pipeline in order.
kpt runs the functions sequentially and returns the results to Porch, which stores them in the PackageRevisionResources `status.renderStatus` field.
Rendering is triggered automatically after creating or cloning a package revision, after updating a package revision, and when a package revision is proposed.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in my opinion this is a bit too brutal level of complexity for the concepts sections. this is meant to be for high level detail. its great detail mind you but id recommend a bit higher level here and bring this detail into the later sections of the docs.

Comment on lines +157 to +161
The **builtin runtime** runs compiled-in Go processors (`apply-replacements`, `set-namespace`, `starlark`) for tags listed on `goExecutor`.

The **gRPC runtime** calls the function-runner for everything else (binary fast path, then pod).

The **multi-runtime** tries builtin first and falls back to gRPC.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think these were fine as bullet points but its fine either way really

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is great content but this section is meant to be for configuration of his feature not to explain what and how it functions and interacts. i think the content is great but should move into architecture and components in the relevant area and only configuration info should remain here with minimal information to support said configuration.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not im only referring to the first 2-3 paragraphs in this file the rest is perfect as is

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as my previous comment. just first 2 paragraphs. rest is perfect as is

A healthy install shows one FunctionConfig per bundled catalog function (apply-replacements, set-namespace, starlark, kubeconform, and others).
The `Server Applied`, `FnRunner Applied`, and `Controller Applied` columns are the generations each component has loaded; they should match the resource generation when the spec is in sync.

These FunctionConfig objects replace the older static config-file / ConfigMap approach.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would a reader here know what the old approach was? i think this might just confuse people about what the old approach even is. i think we have versioned docs now so if someone wanted to see what the older approach was they can just go back.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add documentation for the new FunctionConfig CRD and controller

4 participants