diff --git a/hips/hip-9999.md b/hips/hip-9999.md index 939a96df..7930a60a 100644 --- a/hips/hip-9999.md +++ b/hips/hip-9999.md @@ -15,7 +15,16 @@ This HIP builds upon [H4HIP: Wasm plugin system](./hip-0026.md) to define how ch ## Motivation -While the main plugin system HIP enables users to extend Helm's functionality, chart authors ([Application Distributors](https://github.com/helm/community/blob/main/user-profiles.md#2-application-distributor)) need a way to specify which plugins their charts require. This allows charts to use alternative render engines, download protocols, and other plugin-based functionality while ensuring users have the necessary plugins installed. +While the main plugin system HIP enables users to extend Helm's functionality, chart authors ([Application Distributors](https://github.com/helm/community/blob/main/user-profiles.md#2-application-distributor)) need a way to specify which plugins their charts require. This allows charts to use alternative render engines, download protocols, and other plugin-based functionality while ensuring users have the necessary plugins installed. Enabling much greater control of a chart's operations and flexibility of operation. + +The salient difference is that Helm CLI/SDK plugins are controled by the Helm user. Chart defined plugins are defined by the Chart author. + +Enabling Helm charts to be extensible aims to enable Chart authors + +TODO: System that "just works" / UX +TODO: Out-of-scope: Operator model: Helm plans to remain a low-level tool +TODO: Plugin maintainence model (artifact hub, Helm maintained "official", communinity mantained) +TODO: "existing functionality" -> go plugins ## Specification @@ -26,14 +35,17 @@ Support for Chart-defined plugins will be added starting in Chart API v3. `Chart For the initial release of the new plugin system, chart authors will be able to define custom plugins for the following categories: - **`getter/v1`** - Download protocols for subcharts beyond HTTP/S and OCI (e.g., S3, Git) -- **`render/v1`** - Manifest rendering using alternative engines beyond gotemplate (e.g., Pkl, Cue, Kustomize) +- **`render/v1`** - Manifest rendering using alternative engines beyond gotemplate (e.g., Pkl, Cue, Kustomize, YamlScript, etc) +- **`values/v1`** - Manage (expand, rewrite, validate) chart rendering values After the initial plugin system release, the intention is to make it easy to continue adding new chart-defined plugin types to extend additional categories of non-default chart behavior as this becomes desirable. Some examples may be: -- **Values schema validation** (for validating the chart's `values.yaml` file using something other than JSON Schema) -- **Dependency resolution** (for using a different subchart dependency resolver than the one currently used by Helm) +- **Values schema management** - expanding, rewriting, validating chart's `values.yaml` file using something other than Helm's inbuilt JSON Schema and subchart values export support +- **Dependency resolution** - determining and ordering dependencies +- Values schema validation (for validating the chart's `values.yaml` file using something other than JSON Schema) +- Dependency resolution (for using a different subchart dependency resolver than the one currently used by Helm) -To plan for forward compatibility, a `minimumHelmVersion` field may be added to allow future plugins to specify the minimum version of Helm that must be used for the chart (or since this is the version of Helm that introduced the new plugin, perhaps this can be auto-detected). +To plan for forward compatibility, a `minimumHelmVersion` field may be added to Charts to allow future plugins to specify the minimum version of Helm that must be used for the chart (or since this is the version of Helm that introduced the new plugin, perhaps this can be auto-detected). ### Chart.yaml Plugin Syntax @@ -46,7 +58,26 @@ The `plugins` key is defined as a **list** (not a map). This is critical for `re Example `Chart.yaml` for Charts v3: +`Chart.yaml` plugins will be defined via a `plugins:` key containing a list of plguins. Enabling ordering of plugin operations. e.g. Chaining chart yaml renderers. + +TODO: Do we want to group plugin types? e.g. + ```yaml + render/v1: + - name: pkl + repository: oci://ghcr.io/pkl-community/helm-pkl + version: 0.1.0 + - name: kustomize + repository: oci://ghcr.io/helm-kustomize + version: 0.1.0 + getter/v1: + - name: s3 + repository: oci://ghcr.io/hypnoglow/helm-s3 + version: 0.16.3 +``` + +```yaml +--- apiVersion: v3 name: my-chart version: 1.0.0 @@ -61,12 +92,6 @@ plugins: type: getter/v1 repository: oci://ghcr.io/hypnoglow/helm-s3 version: 0.16.3 - -# Renamed from "dependencies" in v2 -subcharts: - - name: postgresql - version: 12.x.x - repository: https://charts.bitnami.com/bitnami ``` ### Render/v1 Plugin Specification @@ -115,7 +140,7 @@ All `render/v1` plugins receive the same Helm built-in objects via JSON serializ - `Subcharts` - Metadata about subchart dependencies - `Files` - Non-template files accessible to the chart - `Capabilities` - Information about the Kubernetes cluster -- `Template` - Template-specific information (name, base path) +- `SourceFiles` - Template-specific information (name, base path) Plugins return rendered Kubernetes manifests as a map of `filename -> content`. @@ -179,6 +204,7 @@ Plugins are referenced by OCI URL in `Chart.yaml` (not packaged within charts). **Plugin versioning:** The content cache supports multiple versions of the same plugin, allowing different charts to depend on different plugin versions without conflicts. ### Plugin Storage: Installed vs Cached +### Chart plugins vs. user (CLI/SDK) plugins Plugins exist in two distinct storage models: @@ -193,6 +219,7 @@ Plugins exist in two distinct storage models: | -------------------------- | ------------------------------------------ | ------------------------------------- | | Global install destination | `$PLUGINS_DIR//` | Final location for installed plugins | | Chart-defined cache | `$HELM_CACHE_HOME/content/{digest}.plugin` | Content-addressable cache (transient) | +Chart plugins are not visible to the CLI/SDK plugin registry and cannot be managed via `helm plugin install/uninstall`. They are only loaded and used when a chart explicitly specifies them in `Chart.yaml`. **Important distinction:** Chart-defined plugins are **cached**, not **managed**. The content cache is transient storage that can be cleared at any time (`rm -rf $HELM_CACHE_HOME/content/`) without breaking workflows - plugins will simply be re-fetched on next use. This is analogous to chart caching: users don't "manage" cached charts, they manage chart dependencies via `Chart.yaml` and `Chart.lock`. @@ -390,25 +417,32 @@ Some environments run with read-only filesystems. The SDK should support: #### SDK API Requirements -To support these use cases, the SDK must abstract plugin loading: +To support these use cases, the SDK provides the `PluginRenderer` with configurable options: ```go -// SDK users can customize caching behavior -type RenderOptions struct { - // CompilationCache allows custom Wasm compilation cache +type PluginRenderer struct { + // ContentCachePath is the path to the content cache directory. + // Plugins are loaded from cached archives using their digest from Chart.lock. + // Set to "" to disable disk-based loading (use with PreloadedPlugins). + ContentCachePath string + + // CompilationCache allows custom Wasm compilation cache. // Default: disk-based at $HELM_CACHE_HOME/wazero-build/ + // For non-writable filesystems, use wazero.NewCompilationCache() for in-memory. CompilationCache wazero.CompilationCache - // ContentCache allows custom plugin tarball cache - // Default: disk-based at $HELM_CACHE_HOME/content/ - ContentCache downloader.Cache - - // PreloadedPlugins allows passing pre-compiled plugins - // Useful for non-writable filesystems or pre-warmed caches - PreloadedPlugins map[string]wazero.CompiledModule + // PreloadedPlugins allows passing pre-loaded plugin archives as raw bytes. + // Map keys are the plugin digest (matching Chart.lock). + // Useful for non-writable filesystems where plugins are embedded at build time. + PreloadedPlugins map[string][]byte } ``` +**For non-writable filesystems**, SDK users must: + +1. Set `ContentCachePath` to `""` (empty string) to disable disk access +2. Provide `PreloadedPlugins` with embedded plugin archives keyed by digest + #### Native Go Plugin Runtime (SDK Only) For SDK users who want to bypass Wasm entirely, a separate HIP proposes a `go/v1` runtime that allows registering native Go implementations for plugin types. This is SDK-only (CLI always uses Wasm for sandboxing) and covered in a dedicated HIP. @@ -454,6 +488,7 @@ This redirects plugin downloads to an internal mirror, following the same patter - Organizations already have registry mirroring infrastructure **Decision:** Prioritize registries.conf implementation before moving chart-defined plugins out of experimental. A dedicated `helm plugin download` command is not planned (see Rejected Ideas). +**Decision needed:** Implement `helm pull --download-plugins`, wait for registries.conf, or both? ## Rejected ideas