Fix panic when helm isn't installed (#2169)

Return error instead of panic

Signed-off-by: Nick Neisen <nwneisen@gmail.com>
This commit is contained in:
Nick Neisen 2025-09-08 17:15:46 -06:00 committed by GitHub
parent 55030e4eee
commit f708d06200
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 189 additions and 72 deletions

View File

@ -784,7 +784,7 @@ func createHelmKey(bin, kubectx string) helmKey {
//
// This is currently used for running all the helm commands for reconciling releases. But this may change in the future
// once we enable each release to have its own helm binary/version.
func (a *App) getHelm(st *state.HelmState) helmexec.Interface {
func (a *App) getHelm(st *state.HelmState) (helmexec.Interface, error) {
a.helmsMutex.Lock()
defer a.helmsMutex.Unlock()
@ -799,14 +799,18 @@ func (a *App) getHelm(st *state.HelmState) helmexec.Interface {
key := createHelmKey(bin, kubectx)
if _, ok := a.helms[key]; !ok {
a.helms[key] = helmexec.New(bin, helmexec.HelmExecOptions{EnableLiveOutput: a.EnableLiveOutput, DisableForceUpdate: a.DisableForceUpdate}, a.Logger, kubeconfig, kubectx, &helmexec.ShellRunner{
exec, err := helmexec.New(bin, helmexec.HelmExecOptions{EnableLiveOutput: a.EnableLiveOutput, DisableForceUpdate: a.DisableForceUpdate}, a.Logger, kubeconfig, kubectx, &helmexec.ShellRunner{
Logger: a.Logger,
Ctx: a.ctx,
StripArgsValuesOnExitError: a.StripArgsValuesOnExitError,
})
if err != nil {
return nil, err
}
a.helms[key] = exec
}
return a.helms[key]
return a.helms[key], nil
}
func (a *App) visitStates(fileOrDir string, defOpts LoadOpts, converge func(*state.HelmState) (bool, []error)) error {
@ -958,7 +962,10 @@ var (
func (a *App) ForEachState(do func(*Run) (bool, []error), includeTransitiveNeeds bool, o ...LoadOption) error {
ctx := NewContext()
err := a.visitStatesWithSelectorsAndRemoteSupport(a.FileOrDir, func(st *state.HelmState) (bool, []error) {
helm := a.getHelm(st)
helm, err := a.getHelm(st)
if err != nil {
return false, []error{err}
}
run, err := NewRun(st, helm, ctx)
if err != nil {

View File

@ -2492,9 +2492,12 @@ func (mock *mockRunner) Execute(cmd string, args []string, env map[string]string
return []byte{}, nil
}
func MockExecer(logger *zap.SugaredLogger, kubeContext string) helmexec.Interface {
execer := helmexec.New("helm", helmexec.HelmExecOptions{}, logger, "", kubeContext, &mockRunner{})
return execer
func MockExecer(logger *zap.SugaredLogger, kubeContext string) (helmexec.Interface, error) {
execer, err := helmexec.New("helm", helmexec.HelmExecOptions{}, logger, "", kubeContext, &mockRunner{})
if err != nil {
return nil, err
}
return execer, nil
}
// mocking helmexec.Interface

View File

@ -34,7 +34,7 @@ type desiredStateLoader struct {
chart string
fs *filesystem.FileSystem
getHelm func(*state.HelmState) helmexec.Interface
getHelm func(*state.HelmState) (helmexec.Interface, error)
remote *remote.Remote
logger *zap.SugaredLogger

View File

@ -163,7 +163,10 @@ func (h *HelmfileInit) WhetherContinue(ask string) error {
func (h *HelmfileInit) CheckHelmPlugins() error {
settings := cli.New()
helm := helmexec.New(h.helmBinary, helmexec.HelmExecOptions{}, h.logger, "", "", h.runner)
helm, err := helmexec.New(h.helmBinary, helmexec.HelmExecOptions{}, h.logger, "", "", h.runner)
if err != nil {
return err
}
for _, p := range helmPlugins {
pluginVersion, err := helmexec.GetPluginVersion(p.name, settings.PluginsDirectory)
if err != nil {

View File

@ -122,11 +122,10 @@ func redactedURL(chart string) string {
}
// New for running helm commands
func New(helmBinary string, options HelmExecOptions, logger *zap.SugaredLogger, kubeconfig string, kubeContext string, runner Runner) *execer {
// TODO: proper error handling
func New(helmBinary string, options HelmExecOptions, logger *zap.SugaredLogger, kubeconfig string, kubeContext string, runner Runner) (*execer, error) {
version, err := GetHelmVersion(helmBinary, runner)
if err != nil {
panic(err)
return nil, err
}
if version.Prerelease() != "" {
@ -143,7 +142,7 @@ func New(helmBinary string, options HelmExecOptions, logger *zap.SugaredLogger,
kubeContext: kubeContext,
runner: runner,
decryptedSecrets: make(map[string]*decryptedSecret),
}
}, nil
}
func (helm *execer) SetExtraArgs(args ...string) {

View File

@ -36,16 +36,22 @@ func (mock *mockRunner) Execute(cmd string, args []string, env map[string]string
return mock.output, mock.err
}
func MockExecer(logger *zap.SugaredLogger, kubeconfig, kubeContext string) *execer {
execer := New("helm", HelmExecOptions{}, logger, kubeconfig, kubeContext, &mockRunner{})
return execer
func MockExecer(logger *zap.SugaredLogger, kubeconfig, kubeContext string) (*execer, error) {
execer, err := New("helm", HelmExecOptions{}, logger, kubeconfig, kubeContext, &mockRunner{})
if err != nil {
return nil, err
}
return execer, nil
}
// Test methods
func TestNewHelmExec(t *testing.T) {
buffer := bytes.NewBufferString("something")
helm := MockExecer(NewLogger(buffer, "debug"), "config", "dev")
helm, err := MockExecer(NewLogger(buffer, "debug"), "config", "dev")
if err != nil {
t.Error(err)
}
if helm.kubeContext != "dev" {
t.Error("helmexec.New() - kubeContext")
}
@ -58,7 +64,10 @@ func TestNewHelmExec(t *testing.T) {
}
func Test_SetExtraArgs(t *testing.T) {
helm := MockExecer(NewLogger(os.Stdout, "info"), "config", "dev")
helm, err := MockExecer(NewLogger(os.Stdout, "info"), "config", "dev")
if err != nil {
t.Error(err)
}
helm.SetExtraArgs()
if len(helm.extra) != 0 {
t.Error("helmexec.SetExtraArgs() - passing no arguments should not change extra field")
@ -74,7 +83,10 @@ func Test_SetExtraArgs(t *testing.T) {
}
func Test_SetHelmBinary(t *testing.T) {
helm := MockExecer(NewLogger(os.Stdout, "info"), "config", "dev")
helm, err := MockExecer(NewLogger(os.Stdout, "info"), "config", "dev")
if err != nil {
t.Error(err)
}
if helm.helmBinary != "helm" {
t.Error("helmexec.command - default command is not helm")
}
@ -85,7 +97,10 @@ func Test_SetHelmBinary(t *testing.T) {
}
func Test_SetEnableLiveOutput(t *testing.T) {
helm := MockExecer(NewLogger(os.Stdout, "info"), "config", "dev")
helm, err := MockExecer(NewLogger(os.Stdout, "info"), "config", "dev")
if err != nil {
t.Error(err)
}
if helm.options.EnableLiveOutput {
t.Error("helmexec.options.EnableLiveOutput should not be enabled by default")
}
@ -96,7 +111,10 @@ func Test_SetEnableLiveOutput(t *testing.T) {
}
func Test_SetDisableForceUpdate(t *testing.T) {
helm := MockExecer(NewLogger(os.Stdout, "info"), "config", "dev")
helm, err := MockExecer(NewLogger(os.Stdout, "info"), "config", "dev")
if err != nil {
t.Error(err)
}
if helm.options.DisableForceUpdate {
t.Error("helmexec.options.ForceUpdate should not be enabled by default")
}
@ -155,11 +173,14 @@ exec: helm --kubeconfig config --kube-context dev repo add myRepo https://repo.e
func Test_AddRepo(t *testing.T) {
var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug")
helm := MockExecer(logger, "config", "dev")
helm, err := MockExecer(logger, "config", "dev")
if err != nil {
t.Errorf("unexpected error: %v", err)
}
// Test case with certfile and keyfile
buffer.Reset()
err := helm.AddRepo("myRepo", "https://repo.example.com/", "", "cert.pem", "key.pem", "", "", "", false, false)
err = helm.AddRepo("myRepo", "https://repo.example.com/", "", "cert.pem", "key.pem", "", "", "", false, false)
expected := `Adding repo myRepo https://repo.example.com/
exec: helm --kubeconfig config --kube-context dev repo add myRepo https://repo.example.com/ --cert-file cert.pem --key-file key.pem
`
@ -292,8 +313,11 @@ exec: helm --kubeconfig config --kube-context dev repo add myRepo https://repo.e
func Test_UpdateRepo(t *testing.T) {
var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug")
helm := MockExecer(logger, "config", "dev")
err := helm.UpdateRepo()
helm, err := MockExecer(logger, "config", "dev")
if err != nil {
t.Errorf("unexpected error: %v", err)
}
err = helm.UpdateRepo()
expected := `Updating repo
exec: helm --kubeconfig config --kube-context dev repo update
`
@ -346,8 +370,11 @@ exec: helm --kubeconfig config --kube-context dev registry login repo.example.co
func Test_SyncRelease(t *testing.T) {
var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug")
helm := MockExecer(logger, "config", "dev")
err := helm.SyncRelease(HelmContext{}, "release", "chart", "default", "--timeout 10", "--wait", "--wait-for-jobs")
helm, err := MockExecer(logger, "config", "dev")
if err != nil {
t.Errorf("unexpected error: %v", err)
}
err = helm.SyncRelease(HelmContext{}, "release", "chart", "default", "--timeout 10", "--wait", "--wait-for-jobs")
expected := `Upgrading release=release, chart=chart, namespace=default
exec: helm --kubeconfig config --kube-context dev upgrade --install release chart --timeout 10 --wait --wait-for-jobs --history-max 0
`
@ -386,8 +413,11 @@ exec: helm --kubeconfig config --kube-context dev upgrade --install release http
func Test_UpdateDeps(t *testing.T) {
var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug")
helm := MockExecer(logger, "config", "dev")
err := helm.UpdateDeps("./chart/foo")
helm, err := MockExecer(logger, "config", "dev")
if err != nil {
t.Errorf("unexpected error: %v", err)
}
err = helm.UpdateDeps("./chart/foo")
expected := `Updating dependency ./chart/foo
exec: helm --kubeconfig config --kube-context dev dependency update ./chart/foo
`
@ -416,8 +446,11 @@ func Test_BuildDeps(t *testing.T) {
var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug")
helm3Runner := mockRunner{output: []byte("v3.2.4+ge29ce2a")}
helm := New("helm", HelmExecOptions{}, logger, "config", "dev", &helm3Runner)
err := helm.BuildDeps("foo", "./chart/foo", []string{"--skip-refresh"}...)
helm, err := New("helm", HelmExecOptions{}, logger, "config", "dev", &helm3Runner)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
err = helm.BuildDeps("foo", "./chart/foo", []string{"--skip-refresh"}...)
expected := `Building dependency release=foo, chart=./chart/foo
exec: helm --kubeconfig config --kube-context dev dependency build ./chart/foo --skip-refresh
v3.2.4+ge29ce2a
@ -458,7 +491,10 @@ v3.2.4+ge29ce2a
buffer.Reset()
helm2Runner := mockRunner{output: []byte("Client: v2.16.1+ge13bc94")}
helm = New("helm", HelmExecOptions{}, logger, "config", "dev", &helm2Runner)
helm, err = New("helm", HelmExecOptions{}, logger, "config", "dev", &helm2Runner)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
err = helm.BuildDeps("foo", "./chart/foo")
expected = `Building dependency release=foo, chart=./chart/foo
exec: helm --kubeconfig config --kube-context dev dependency build ./chart/foo
@ -484,14 +520,17 @@ func Test_DecryptSecret(t *testing.T) {
}()
var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug")
helm := MockExecer(logger, "config", "dev")
helm, err := MockExecer(logger, "config", "dev")
if err != nil {
t.Errorf("unexpected error: %v", err)
}
tmpFilePath := "path/to/temp/file"
helm.writeTempFile = func(content []byte) (string, error) {
return tmpFilePath, nil
}
_, err := helm.DecryptSecret(HelmContext{}, "secretName")
_, err = helm.DecryptSecret(HelmContext{}, "secretName")
if err != nil {
t.Errorf("Error: %v", err)
}
@ -533,7 +572,10 @@ func Test_DecryptSecretWithGotmpl(t *testing.T) {
}()
var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug")
helm := MockExecer(logger, "config", "dev")
helm, err := MockExecer(logger, "config", "dev")
if err != nil {
t.Errorf("unexpected error: %v", err)
}
tmpFilePath := "path/to/temp/file"
helm.writeTempFile = func(content []byte) (string, error) {
@ -541,7 +583,7 @@ func Test_DecryptSecretWithGotmpl(t *testing.T) {
}
secretName := "secretName.yaml.gotmpl"
_, err := helm.DecryptSecret(HelmContext{}, secretName)
_, err = helm.DecryptSecret(HelmContext{}, secretName)
if err != nil {
t.Errorf("Error: %v", err)
}
@ -566,8 +608,11 @@ Decrypted %s/secretName.yaml.gotmpl into %s
func Test_DiffRelease(t *testing.T) {
var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug")
helm := MockExecer(logger, "config", "dev")
err := helm.DiffRelease(HelmContext{}, "release", "chart", "default", false, "--timeout 10", "--wait", "--wait-for-jobs")
helm, err := MockExecer(logger, "config", "dev")
if err != nil {
t.Errorf("unexpected error: %v", err)
}
err = helm.DiffRelease(HelmContext{}, "release", "chart", "default", false, "--timeout 10", "--wait", "--wait-for-jobs")
expected := `Comparing release=release, chart=chart, namespace=default
exec: helm --kubeconfig config --kube-context dev diff upgrade --allow-unreleased release chart --timeout 10 --wait --wait-for-jobs
@ -609,8 +654,11 @@ exec: helm --kubeconfig config --kube-context dev diff upgrade --allow-unrelease
func Test_DeleteRelease(t *testing.T) {
var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug")
helm := MockExecer(logger, "config", "dev")
err := helm.DeleteRelease(HelmContext{}, "release")
helm, err := MockExecer(logger, "config", "dev")
if err != nil {
t.Errorf("unexpected error: %v", err)
}
err = helm.DeleteRelease(HelmContext{}, "release")
expected := `Deleting release
exec: helm --kubeconfig config --kube-context dev delete release
`
@ -624,8 +672,11 @@ exec: helm --kubeconfig config --kube-context dev delete release
func Test_DeleteRelease_Flags(t *testing.T) {
var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug")
helm := MockExecer(logger, "config", "dev")
err := helm.DeleteRelease(HelmContext{}, "release", "--purge")
helm, err := MockExecer(logger, "config", "dev")
if err != nil {
t.Errorf("unexpected error: %v", err)
}
err = helm.DeleteRelease(HelmContext{}, "release", "--purge")
expected := `Deleting release
exec: helm --kubeconfig config --kube-context dev delete release --purge
`
@ -640,8 +691,11 @@ exec: helm --kubeconfig config --kube-context dev delete release --purge
func Test_TestRelease(t *testing.T) {
var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug")
helm := MockExecer(logger, "config", "dev")
err := helm.TestRelease(HelmContext{}, "release")
helm, err := MockExecer(logger, "config", "dev")
if err != nil {
t.Errorf("unexpected error: %v", err)
}
err = helm.TestRelease(HelmContext{}, "release")
expected := `Testing release
exec: helm --kubeconfig config --kube-context dev test release
`
@ -655,8 +709,11 @@ exec: helm --kubeconfig config --kube-context dev test release
func Test_TestRelease_Flags(t *testing.T) {
var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug")
helm := MockExecer(logger, "config", "dev")
err := helm.TestRelease(HelmContext{}, "release", "--cleanup", "--timeout", "60")
helm, err := MockExecer(logger, "config", "dev")
if err != nil {
t.Errorf("unexpected error: %v", err)
}
err = helm.TestRelease(HelmContext{}, "release", "--cleanup", "--timeout", "60")
expected := `Testing release
exec: helm --kubeconfig config --kube-context dev test release --cleanup --timeout 60
`
@ -671,8 +728,11 @@ exec: helm --kubeconfig config --kube-context dev test release --cleanup --timeo
func Test_ReleaseStatus(t *testing.T) {
var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug")
helm := MockExecer(logger, "config", "dev")
err := helm.ReleaseStatus(HelmContext{}, "myRelease")
helm, err := MockExecer(logger, "config", "dev")
if err != nil {
t.Errorf("unexpected error: %v", err)
}
err = helm.ReleaseStatus(HelmContext{}, "myRelease")
expected := `Getting status myRelease
exec: helm --kubeconfig config --kube-context dev status myRelease
`
@ -687,9 +747,12 @@ exec: helm --kubeconfig config --kube-context dev status myRelease
func Test_exec(t *testing.T) {
var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug")
helm := MockExecer(logger, "", "")
helm, err := MockExecer(logger, "", "")
if err != nil {
t.Errorf("unexpected error: %v", err)
}
env := map[string]string{}
_, err := helm.exec([]string{"version"}, env, nil)
_, err = helm.exec([]string{"version"}, env, nil)
expected := `exec: helm version
`
if err != nil {
@ -699,14 +762,20 @@ func Test_exec(t *testing.T) {
t.Errorf("helmexec.exec()\nactual = %v\nexpect = %v", buffer.String(), expected)
}
helm = MockExecer(logger, "config", "dev")
helm, err = MockExecer(logger, "config", "dev")
if err != nil {
t.Errorf("unexpected error: %v", err)
}
ret, _ := helm.exec([]string{"diff"}, env, nil)
if len(ret) != 0 {
t.Error("helmexec.exec() - expected empty return value")
}
buffer.Reset()
helm = MockExecer(logger, "config", "dev")
helm, err = MockExecer(logger, "config", "dev")
if err != nil {
t.Errorf("unexpected error: %v", err)
}
_, err = helm.exec([]string{"diff", "release", "chart", "--timeout 10", "--wait", "--wait-for-jobs"}, env, nil)
expected = `exec: helm --kubeconfig config --kube-context dev diff release chart --timeout 10 --wait --wait-for-jobs
`
@ -741,7 +810,10 @@ func Test_exec(t *testing.T) {
}
buffer.Reset()
helm = MockExecer(logger, "", "")
helm, err = MockExecer(logger, "", "")
if err != nil {
t.Errorf("unexpected error: %v", err)
}
helm.SetHelmBinary("overwritten")
_, err = helm.exec([]string{"version"}, env, nil)
expected = `exec: overwritten version
@ -757,8 +829,11 @@ func Test_exec(t *testing.T) {
func Test_Lint(t *testing.T) {
var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug")
helm := MockExecer(logger, "config", "dev")
err := helm.Lint("release", "path/to/chart", "--values", "file.yml")
helm, err := MockExecer(logger, "config", "dev")
if err != nil {
t.Errorf("unexpected error: %v", err)
}
err = helm.Lint("release", "path/to/chart", "--values", "file.yml")
expected := `Linting release=release, chart=path/to/chart
exec: helm --kubeconfig config --kube-context dev lint path/to/chart --values file.yml
`
@ -773,8 +848,11 @@ exec: helm --kubeconfig config --kube-context dev lint path/to/chart --values fi
func Test_Fetch(t *testing.T) {
var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug")
helm := MockExecer(logger, "config", "dev")
err := helm.Fetch("chart", "--version", "1.2.3", "--untar", "--untardir", "/tmp/dir")
helm, err := MockExecer(logger, "config", "dev")
if err != nil {
t.Errorf("unexpected error: %v", err)
}
err = helm.Fetch("chart", "--version", "1.2.3", "--untar", "--untardir", "/tmp/dir")
expected := `Fetching chart
exec: helm --kubeconfig config --kube-context dev fetch chart --version 1.2.3 --untar --untardir /tmp/dir
`
@ -848,8 +926,11 @@ exec: helm --kubeconfig config --kube-context dev pull oci://repo/helm-charts --
tt := tests[i]
t.Run(tt.name, func(t *testing.T) {
buffer.Reset()
helm := New(tt.helmBin, HelmExecOptions{}, logger, "config", "dev", &mockRunner{output: []byte(tt.helmVersion)})
err := helm.ChartPull(tt.chartName, tt.chartPath, tt.chartFlags...)
helm, err := New(tt.helmBin, HelmExecOptions{}, logger, "config", "dev", &mockRunner{output: []byte(tt.helmVersion)})
if err != nil {
t.Errorf("unexpected error: %v", err)
}
err = helm.ChartPull(tt.chartName, tt.chartPath, tt.chartFlags...)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -922,8 +1003,11 @@ func Test_LogLevels(t *testing.T) {
for logLevel, expected := range logLevelTests {
buffer.Reset()
logger := NewLogger(&buffer, logLevel)
helm := MockExecer(logger, "", "")
err := helm.AddRepo("myRepo", "https://repo.example.com/", "", "", "", "example_user", "example_password", "", false, false)
helm, err := MockExecer(logger, "", "")
if err != nil {
t.Errorf("unexpected error: %v", err)
}
err = helm.AddRepo("myRepo", "https://repo.example.com/", "", "", "", "example_user", "example_password", "", false, false)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -951,8 +1035,11 @@ func Test_mergeEnv(t *testing.T) {
func Test_Template(t *testing.T) {
var buffer bytes.Buffer
logger := NewLogger(&buffer, "debug")
helm := MockExecer(logger, "config", "dev")
err := helm.TemplateRelease("release", "path/to/chart", "--values", "file.yml")
helm, err := MockExecer(logger, "config", "dev")
if err != nil {
t.Errorf("unexpected error: %v", err)
}
err = helm.TemplateRelease("release", "path/to/chart", "--values", "file.yml")
expected := `Templating release=release, chart=path/to/chart
exec: helm --kubeconfig config --kube-context dev template release path/to/chart --values file.yml
`
@ -978,13 +1065,19 @@ exec: helm --kubeconfig config --kube-context dev template release https://examp
func Test_IsHelm3(t *testing.T) {
helm2Runner := mockRunner{output: []byte("Client: v2.16.0+ge13bc94\n")}
helm := New("helm", HelmExecOptions{}, NewLogger(os.Stdout, "info"), "", "dev", &helm2Runner)
helm, err := New("helm", HelmExecOptions{}, NewLogger(os.Stdout, "info"), "", "dev", &helm2Runner)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if helm.IsHelm3() {
t.Error("helmexec.IsHelm3() - Detected Helm 3 with Helm 2 version")
}
helm3Runner := mockRunner{output: []byte("v3.0.0+ge29ce2a\n")}
helm = New("helm", HelmExecOptions{}, NewLogger(os.Stdout, "info"), "", "dev", &helm3Runner)
helm, err = New("helm", HelmExecOptions{}, NewLogger(os.Stdout, "info"), "", "dev", &helm3Runner)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if !helm.IsHelm3() {
t.Error("helmexec.IsHelm3() - Failed to detect Helm 3")
}
@ -1012,14 +1105,20 @@ func Test_GetPluginVersion(t *testing.T) {
func Test_GetVersion(t *testing.T) {
helm2Runner := mockRunner{output: []byte("Client: v2.16.1+ge13bc94\n")}
helm := New("helm", HelmExecOptions{}, NewLogger(os.Stdout, "info"), "", "dev", &helm2Runner)
helm, err := New("helm", HelmExecOptions{}, NewLogger(os.Stdout, "info"), "", "dev", &helm2Runner)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
ver := helm.GetVersion()
if ver.Major != 2 || ver.Minor != 16 || ver.Patch != 1 {
t.Errorf("helmexec.GetVersion - did not detect correct Helm2 version; it was: %+v", ver)
}
helm3Runner := mockRunner{output: []byte("v3.2.4+ge29ce2a\n")}
helm = New("helm", HelmExecOptions{}, NewLogger(os.Stdout, "info"), "", "dev", &helm3Runner)
helm, err = New("helm", HelmExecOptions{}, NewLogger(os.Stdout, "info"), "", "dev", &helm3Runner)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
ver = helm.GetVersion()
if ver.Major != 3 || ver.Minor != 2 || ver.Patch != 4 {
t.Errorf("helmexec.GetVersion - did not detect correct Helm3 version; it was: %+v", ver)
@ -1028,7 +1127,10 @@ func Test_GetVersion(t *testing.T) {
func Test_IsVersionAtLeast(t *testing.T) {
helm2Runner := mockRunner{output: []byte("Client: v2.16.1+ge13bc94\n")}
helm := New("helm", HelmExecOptions{}, NewLogger(os.Stdout, "info"), "", "dev", &helm2Runner)
helm, err := New("helm", HelmExecOptions{}, NewLogger(os.Stdout, "info"), "", "dev", &helm2Runner)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if !helm.IsVersionAtLeast("2.1.0") {
t.Error("helmexec.IsVersionAtLeast - 2.16.1 not atleast 2.1")
}

View File

@ -118,7 +118,7 @@ func Output(ctx context.Context, c *exec.Cmd, stripArgsValuesOnExitError bool, l
exitStatus := waitStatus.ExitStatus()
err = newExitError(c.Path, c.Args, exitStatus, ee, stderr.String(), combined.String(), stripArgsValuesOnExitError)
default:
panic(fmt.Sprintf("unexpected error: %v", err))
err = fmt.Errorf("unexpected error: %v", err)
}
}

View File

@ -54,7 +54,7 @@ type StateCreator struct {
LoadFile func(inheritedEnv, overrodeEnv *environment.Environment, baseDir, file string, evaluateBases bool) (*HelmState, error)
getHelm func(*HelmState) helmexec.Interface
getHelm func(*HelmState) (helmexec.Interface, error)
overrideHelmBinary string
@ -67,7 +67,7 @@ type StateCreator struct {
lockFile string
}
func NewCreator(logger *zap.SugaredLogger, fs *filesystem.FileSystem, valsRuntime vals.Evaluator, getHelm func(*HelmState) helmexec.Interface, overrideHelmBinary string, overrideKustomizeBinary string, remote *remote.Remote, enableLiveOutput bool, lockFile string) *StateCreator {
func NewCreator(logger *zap.SugaredLogger, fs *filesystem.FileSystem, valsRuntime vals.Evaluator, getHelm func(*HelmState) (helmexec.Interface, error), overrideHelmBinary string, overrideKustomizeBinary string, remote *remote.Remote, enableLiveOutput bool, lockFile string) *StateCreator {
return &StateCreator{
logger: logger,
@ -342,7 +342,10 @@ func (c *StateCreator) loadEnvValues(st *HelmState, name string, failOnMissingEn
func (c *StateCreator) scatterGatherEnvSecretFiles(st *HelmState, envSecretFiles []string, envVals map[string]any, keepFileExtensions []string) ([]string, error) {
var errs []error
var decryptedFilesKeeper []string
helm := c.getHelm(st)
helm, err := c.getHelm(st)
if err != nil {
return nil, err
}
inputs := envSecretFiles
inputsSize := len(inputs)