Help us shape the future of Go! Take the 2026 Go Developer Survey

helmcmd

package
v0.17.0 Latest Latest
Warning

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

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

Documentation

Overview

Package helmcmd contains small helpers for invoking the pinned helm binary.

The main job here is keeping `helmfile sync` working across helm major versions. obol pins Helm 4, which server-side applies fresh installs but keeps upgrades on the previous release's method (--server-side=auto), and SSA introduces field-ownership conflicts (the apiserver synthesises a "before-first-apply" manager for any field that pre-existed the first SSA call) that helm only takes over when --force-conflicts is passed. Helm 3 (an older obol-managed copy, or OBOL_HELM) used client-side apply and rejects both flags, so they are only appended on helm 4+.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func EnsureRepos added in v0.10.0

func EnsureRepos(helmBinary string, repos []helmfileRepo) error

EnsureRepos registers each (name, url) pair via `helm repo add --force-update` so that a fresh host without `helm repo add` for our managed repos still gets them registered before we ask helm to update them by name. Best-effort: failures are returned for visibility but should not be treated as fatal by callers (the subsequent `helm repo update` will surface real problems).

func Helmfile added in v0.15.0

func Helmfile(helmfileBinary, helmBinary string, args ...string) *exec.Cmd

Helmfile builds a helmfile command that is pinned to helmBinary via --helm-binary. Without it helmfile runs whatever `helm` is first on PATH, while SyncFlagsForVersion probes the obol-resolved binary: with a Helm 4 on PATH and a Helm 3 in the bin dir, sync ran Helm 4's server-side apply WITHOUT --force-conflicts and failed on field-manager conflicts (e.g. a Secret previously written by `kubectl apply`). Use this for every helmfile invocation so the probed and executed helm match.

func MajorVersion

func MajorVersion(helmBinary string) (int, error)

MajorVersion runs `<helmBinary> version --short` and returns the major version integer (3, 4, ...). Returns an error if helm cannot be invoked or the output is unparseable.

func ParseHelmfileRepos added in v0.10.0

func ParseHelmfileRepos(helmfilePath string) ([]helmfileRepo, error)

ParseHelmfileRepos extracts (name, url) entries from a helmfile.yaml file. Repos without both a name and a URL (e.g. OCI-only refs) are skipped — they are not added via `helm repo add` so they don't participate in the `helm repo update` path that this package guards against.

func RepoUpdateSupportsFailOnRepoUpdateFail added in v0.10.0

func RepoUpdateSupportsFailOnRepoUpdateFail(helmBinary string) bool

RepoUpdateSupportsFailOnRepoUpdateFail reports whether the current helm binary accepts `helm repo update --fail-on-repo-update-fail=false`.

Do not infer this from the major version. Some Helm 4 builds dropped the flag even though Helm 3.14+ had it, and passing an unknown flag prevents the targeted repo update from running at all.

func SyncFlagsForVersion

func SyncFlagsForVersion(helmBinary string) []string

SyncFlagsForVersion returns the extra `helmfile sync` flags for the detected helm version: UpgradeFlagsForVersion's flags wrapped in a single `--sync-args=...` (helmfile splits it on whitespace and appends each word to its `helm upgrade --install` call). nil on helm 3.

func UpdateRepos added in v0.10.0

func UpdateRepos(helmBinary string, names []string) ([]byte, error)

UpdateRepos runs `helm repo update <names...>` and, when the helm binary advertises support, passes --fail-on-repo-update-fail=false so that a single dead repo doesn't abort the whole update.

Behaviour:

  • helm versions that advertise --fail-on-repo-update-fail: the flag is passed and the returned error is nil even if individual repos in `names` fail.
  • other helm versions: the flag is omitted and the error surfaces normally.

The targeted form (`helm repo update <names...>`) is important: it limits the update to repos this stack actually needs, so unrelated dead repos in the user's global helm config can't break us even on helm versions that lack the tolerant flag.

func UpgradeFlagsForVersion added in v0.15.0

func UpgradeFlagsForVersion(helmBinary string) []string

UpgradeFlagsForVersion returns the extra `helm upgrade --install` flags for the detected helm version: on helm 4+ `--server-side=true --force-conflicts`, on helm 3 (or when detection fails) nil.

Why both flags:

  • --server-side=true: helm 4 upgrades default to --server-side=auto, i.e. whatever method the previous release revision used. Releases first installed by helm 3 were client-side applied, so under auto they would stay client-side forever while fresh installs are SSA. Forcing true converges every existing release on SSA (one-time switch; afterwards auto would pick SSA anyway, so passing it on every sync is a no-op).
  • --force-conflicts: SSA refuses to overwrite fields owned by another field manager. After the CSA→SSA switch the apiserver attributes pre-existing fields to managers like `kubectl-client-side-apply`, `before-first-apply`, or obol's own `kubectl apply --server-side` paths (e.g. the `obol model` patch on litellm-config, the hermes remote-signer password Secret). helm is the source of truth for what it renders, so it takes ownership — the same last-writer-wins outcome as helm 3's three-way merge.

Helm 3 has no SSA and rejects both flags. Detection failures degrade silently to nil so a missing/odd helm binary doesn't block the user; the helm call itself surfaces the real error.

Types

type ReleaseHealth added in v0.15.0

type ReleaseHealth int

ReleaseHealth summarises the helm releases in one namespace.

const (
	// ReleasesMissing: no release at all in the namespace (fresh cluster).
	ReleasesMissing ReleaseHealth = iota
	// ReleasesUnhealthy: at least one release is not in "deployed" state
	// (failed, pending-install, pending-upgrade, ...).
	ReleasesUnhealthy
	// ReleasesDeployed: every release in the namespace is deployed.
	ReleasesDeployed
)

func NamespaceReleaseHealth added in v0.15.0

func NamespaceReleaseHealth(helmBinary, kubeconfig, namespace string) (ReleaseHealth, error)

NamespaceReleaseHealth runs `helm list -n <ns> -o json` (all statuses) and classifies the result. Cheap (one helm call, no chart rendering), so record replay can use it to decide whether an expensive `helmfile sync` is needed.

func ParseReleaseHealth added in v0.15.0

func ParseReleaseHealth(out []byte) (ReleaseHealth, error)

ParseReleaseHealth classifies `helm list -o json` output.

func (ReleaseHealth) String added in v0.15.0

func (h ReleaseHealth) String() string

Jump to

Keyboard shortcuts

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