helm

package
v0.9.0 Latest Latest
Warning

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

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

Documentation

Overview

Package helm generates Helm charts from Deployah specs and drives install, upgrade, list, and delete operations against a cluster.

PrepareChart renders templates and values for an environment into a caller-supplied ChartCache. Client wraps Helm v4 actions with Deployah-specific release naming, labels, and a per-client ChartCache. Kubernetes destination comes from a caller-supplied REST client getter via NewRESTClientGetter; Client does not select a kubeconfig itself. Package init pins Helm's kube.ManagedFieldsManager to "deployah".

Deployah is alpha. The first supported Helm apply semantics are server-side apply (SSA). Client-side apply and legacy empty apply methods are unsupported.

Index

Constants

View Source
const (
	// ChartNameTemplate is the template for generated chart names
	ChartNameTemplate = "%s-%s"

	// ReleaseNameTemplate is the template for Helm release names
	ReleaseNameTemplate = "%s-%s"

	// TempChartPrefix is the prefix for temporary chart directories
	TempChartPrefix = "deployah-chart-"

	// ChartYamlTemplate is the template file name for Chart.yaml
	ChartYamlTemplate = "Chart.yaml.gotmpl"

	// ValuesYamlFile is the name of the values file
	ValuesYamlFile = "values.yaml"
)

Chart and Template Constants

Variables

View Source
var (
	// ErrClusterUnreachable is returned when the Kubernetes cluster cannot be reached.
	ErrClusterUnreachable = errors.New("kubernetes cluster unreachable")
	// ErrReleaseNotFound is returned when a Helm release does not exist.
	ErrReleaseNotFound = errors.New("release not found")
	// ErrReleaseAlreadyExists is returned when a Helm release already exists.
	//
	// Produced by [Client.wrapHelmError] from typed Helm/Kubernetes errors
	// when available, otherwise from Helm's plain "already exists" message.
	// Callers may match with [errors.Is].
	ErrReleaseAlreadyExists = errors.New("release already exists")
	// ErrReleasePending is returned when a Helm release has an operation in progress.
	//
	// [PrepareRelease] produces this sentinel via a typed check of the newest
	// revision's pending status (Status.IsPending). [Client.InstallApp] and
	// [Client.RenderManifests] both go through [PrepareRelease].
	// [Client.wrapHelmError] does not classify Helm's plain pending messages, so
	// other action paths (and a rare race after the pre-check) surface those as
	// generic helm failures. Callers may match with [errors.Is].
	ErrReleasePending = errors.New("another operation is in progress")
)
View Source
var ChartTemplateFS embed.FS

ChartTemplateFS embeds the chart directory. Underscore-prefixed templates were renamed so directory embedding includes them without explicit listing.

View Source
var ErrDestinationNotConfigured = errors.New("kubernetes destination is not configured")

ErrDestinationNotConfigured is returned when a Helm client has no Kubernetes destination and an operation needs one.

View Source
var ErrNoDeployedRevision = errors.New("no deployed revision to upgrade from")

ErrNoDeployedRevision is returned by PrepareRelease when history exists but Helm would not upgrade: the newest revision is not pending, no revision is deployed, and the newest status is not failed or superseded.

View Source
var ErrUnsupportedReleaseApplyMethod = errors.New("unsupported release apply method")

ErrUnsupportedReleaseApplyMethod is returned by PrepareRelease when an upgrade history revision is not Helm server-side apply ("ssa"). Empty, "csa", and unknown apply methods are unsupported.

Functions

func GenerateReleaseName

func GenerateReleaseName(projectName, environmentName string) string

GenerateReleaseName returns the Helm release name for project and environment. It is the single Helm-facing wrapper around spec.EnvIdentity.ReleaseName.

func MapSpecToChartValues added in v0.3.0

func MapSpecToChartValues(m *spec.Spec, desiredEnvironment string, resolved *spec.ResolvedSpec) (map[string]any, error)

MapSpecToChartValues converts a spec into Helm chart values for the given environment and writes a deployah.resolved block so the hostname guard can compare across deploys.

When resolved is non-nil, resolved.Components is the active set and resolved.Spec (when set) replaces m as the component definition source.

func NewRESTClientGetter added in v0.9.0

NewRESTClientGetter returns a Helm REST client getter backed by cc. A nil cc yields an unconfigured getter: online Kubernetes access fails with ErrDestinationNotConfigured and does not select an ambient kubeconfig or in-cluster destination.

func PrepareChart

func PrepareChart(ctx context.Context, resolved *spec.ResolvedSpec, cache *ChartCache, crds []extras.RawFile) (string, error)

PrepareChart expands the embedded chart into a temporary directory and returns the chart root. Identical charts are reused via cache. A nil or unresolved spec is an error; cache must be non-nil.

Each extras.RawFile is written to crds/<basename> using the exact source bytes. The cached backing chart stays CRD-free. A nil or empty crds slice writes no crds/ directory.

If ctx is already canceled, PrepareChart returns context.Canceled or context.DeadlineExceeded immediately. On a cache miss, every 10th entry may start a background goroutine that removes expired cache directories.

Types

type ChartCache

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

ChartCache stores prepared chart directories keyed by content hash. Each Client owns one instance (see NewClient and WithChartCache). There is no process-global cache. Methods are safe for concurrent use.

func NewChartCache added in v0.6.0

func NewChartCache(ttl time.Duration) *ChartCache

NewChartCache returns an empty chart cache with the given TTL. A non-positive ttl falls back to one hour.

func (*ChartCache) GenerateKey added in v0.6.0

func (c *ChartCache) GenerateKey(environment string, resolved *spec.ResolvedSpec) (string, error)

GenerateKey creates a cache key from the resolved spec, the target environment, and this cache's embedded chart template hash.

resolved must be non-nil. environment must be part of the key: PrepareChart bakes the environment-filtered component set and environment label into the cached chart's values.yaml, so rendering environment A then B for the same spec must not reuse A's cached chart for B.

Hashing spec.ResolvedSpec covers the target-environment subset and invalidates the cache when platform resolution changes. encoding/json sorts map keys deterministically since Go 1.12, so the serialization is stable.

type ChartData

type ChartData struct {
	// Chart holds metadata rendered into Chart.yaml.
	Chart struct {
		Name        string
		Description string
		Version     string
		AppVersion  string
	}
	// Values is the data map for values.yaml templating.
	Values map[string]any
	// ComponentNames are the sorted names of the component sub-charts
	// created for this environment.
	ComponentNames []string
	// TaskNames are the sorted names of the task sub-charts created for this
	// environment. Hook and scheduled tasks each get one.
	TaskNames []string
}

ChartData holds values substituted in Helm chart templates.

type Client

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

Client wraps Helm action configuration for Deployah operations.

func NewClient

func NewClient(opts ...Option) (*Client, error)

NewClient initializes Helm action configuration with functional options. Default storage driver is "secret" if not specified. Default timeout is 5 minutes if not specified. Each client gets its own ChartCache unless WithChartCache is set. A missing WithRESTClientGetter (including a nil getter) uses an unconfigured getter so action.Configuration.Init never receives nil.

func (*Client) DeleteRelease

func (c *Client) DeleteRelease(ctx context.Context, project, environment string, wait bool) error

DeleteRelease uninstalls the given release. When wait is false (the default) it returns right after hooks complete, matching vanilla `helm uninstall`. When wait is true it blocks until all resources are removed, via the legacy polling strategy with foreground cascade deletion -- StatusWatcherStrategy is avoided here because it can report cluster-scoped resources as Terminating forever after Kubernetes already deleted them (helm/helm#31766).

func (*Client) GetRelease

func (c *Client) GetRelease(ctx context.Context, project, environment string) (*v1.Release, error)

GetRelease retrieves a release by project and environment.

func (*Client) GetReleaseHistory

func (c *Client) GetReleaseHistory(ctx context.Context, project, environment string) ([]*v1.Release, error)

GetReleaseHistory returns the history of a specific release.

func (*Client) InstallApp

func (c *Client) InstallApp(ctx context.Context, dryRun bool, resolved *spec.ResolvedSpec, postRenderer postrenderer.PostRenderer, crds []extras.RawFile, skipCRDs bool) error

InstallApp installs or upgrades the app from spec.ResolvedSpec. When dryRun is true, it renders via Client.RenderManifests instead of touching the cluster. crds are written into the per-invocation chart copy. skipCRDs is forwarded to Helm Install.SkipCRDs on a fresh install only. A nil or unresolved spec is an error.

func (*Client) IsReachable

func (c *Client) IsReachable() error

IsReachable reports whether the configured Kubernetes cluster is reachable.

Also works around helm/helm#32183: Helm panics on a second IsReachable call after the first one fails (typed-nil cached in getKubeClient), so calling this once before InstallApp keeps InstallApp from ever hitting that second call against a poisoned client. Upstream merged the fix in https://github.com/helm/helm/pull/32184 (2026-06-18), but helm.sh/helm/v4 v4.2.3 still ships the buggy getKubeClient. Re-check getKubeClient on the next Helm bump; the pre-call can be removed once the pin includes the fix.

func (*Client) ListReleases

func (c *Client) ListReleases(ctx context.Context, selector labels.Selector) ([]*v1.Release, error)

ListReleases returns release details in the current namespace.

func (*Client) Namespace added in v0.5.0

func (c *Client) Namespace() string

Namespace returns the release namespace configured for Helm operations. It comes from WithNamespace, or "default" when empty.

func (*Client) RenderManifests added in v0.4.0

func (c *Client) RenderManifests(ctx context.Context, resolved *spec.ResolvedSpec, postRenderer postrenderer.PostRenderer, crds []extras.RawFile) (*render.RenderResult, func(), error)

RenderManifests renders the chart from spec.ResolvedSpec client-side. The cluster must be reachable. Callers must run the returned cleanup func.

func (*Client) RenderManifestsWithPrep added in v0.9.0

func (c *Client) RenderManifestsWithPrep(ctx context.Context, resolved *spec.ResolvedSpec, postRenderer postrenderer.PostRenderer, crds []extras.RawFile) (*render.RenderResult, ReleasePrep, func(), error)

RenderManifestsWithPrep renders spec.ResolvedSpec and returns the ReleasePrep for that install or upgrade. crds are copied into the chart. Cleanup is nil on error; the caller runs it once on success.

func (*Client) RollbackRelease

func (c *Client) RollbackRelease(ctx context.Context, releaseName string, revision int, timeout time.Duration) error

RollbackRelease rolls back a release to a previous revision.

type Operation added in v0.9.0

type Operation int

Operation is whether Helm would install or upgrade given release history. The zero value is invalid; only OperationInstall and OperationUpgrade are legal.

const (
	// OperationInstall is a first install: no history exists.
	OperationInstall Operation = iota + 1
	// OperationUpgrade is an upgrade of an existing release, including a
	// failed-only history with no deployed revision.
	OperationUpgrade
)

type Option

type Option func(*Client)

Option is a functional option for configuring the Helm client

func WithChartCache added in v0.6.0

func WithChartCache(cache *ChartCache) Option

WithChartCache sets the prepared-chart cache used by this client. cache must be non-nil; NewClient rejects a nil cache.

func WithDebug

func WithDebug(keep bool) Option

WithDebug controls whether to keep temporary chart directories.

func WithNamespace

func WithNamespace(namespace string) Option

WithNamespace sets the Kubernetes namespace for Helm operations. Empty falls back to "default" in NewClient.

func WithRESTClientGetter added in v0.9.0

func WithRESTClientGetter(getter genericclioptions.RESTClientGetter) Option

WithRESTClientGetter sets the Kubernetes REST client getter used by Helm actions. A nil getter is treated as unset; NewClient then installs an unconfigured getter so action.Configuration.Init never receives nil.

func WithStorageDriver

func WithStorageDriver(driver string) Option

WithStorageDriver sets the Helm storage driver (secret, configmap, or memory)

func WithTimeout

func WithTimeout(timeout time.Duration) Option

WithTimeout sets the default timeout for Helm operations

type ReleasePrep added in v0.9.0

type ReleasePrep struct {
	// Operation is install when history is empty, otherwise upgrade.
	Operation Operation
	// Newest is Helm's last revision (highest Version), or nil on install.
	Newest *v1.Release
	// Current is the upgrade manifest baseline, or nil on install.
	Current *v1.Release
	// NextRevision is 1 on install, otherwise Newest.Version+1.
	NextRevision int
}

ReleasePrep is the install-or-upgrade decision Helm's prepareUpgrade would make from release history. Newest and Current can differ; callers must use those releases' Version fields, not a generic revision.

func PrepareRelease added in v0.9.0

func PrepareRelease(history []*v1.Release) (ReleasePrep, error)

PrepareRelease decides install vs upgrade from history. Newest, Current, pending, failed or superseded, and NextRevision match Helm v4.3.0 prepareUpgrade. Deployah also requires Helm server-side apply on the checked revisions. It does not mutate history.

An empty or nil slice is an install. History-fetch errors such as driver.ErrReleaseNotFound stay at the caller: treat only that sentinel as empty history, then call PrepareRelease.

It returns ErrReleasePending when the newest revision is pending, ErrNoDeployedRevision when Helm would refuse the upgrade, and ErrUnsupportedReleaseApplyMethod when Newest, or Current when it is a different revision, is not Helm server-side apply.

Jump to

Keyboard shortcuts

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