From 313b5de3789c262a65792023580807ec35c3f679 Mon Sep 17 00:00:00 2001 From: Yusuke KUOKA Date: Thu, 23 Aug 2018 11:45:37 +0900 Subject: [PATCH] feat: emit error message containing which release in which helmfile an upgrade failed Resolves #66 --- main.go | 11 ++++++++--- state/state.go | 25 +++++++++++++++++-------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/main.go b/main.go index 42ff61ce..5f60bf7c 100644 --- a/main.go +++ b/main.go @@ -519,19 +519,24 @@ func loadDesiredStateFromFile(c *cli.Context, file string) (*state.HelmState, he return st, helmexec.New(logger, kubeContext), false, nil } -func clean(state *state.HelmState, errs []error) error { +func clean(st *state.HelmState, errs []error) error { if errs == nil { errs = []error{} } - cleanErrs := state.Clean() + cleanErrs := st.Clean() if cleanErrs != nil { errs = append(errs, cleanErrs...) } if errs != nil && len(errs) > 0 { for _, err := range errs { - fmt.Printf("err: %s\n", err.Error()) + switch e := err.(type) { + case *state.ReleaseError: + fmt.Printf("err: release \"%s\" in \"%s\" failed: %v\n", e.Name, st.FilePath, e) + default: + fmt.Printf("err: %v\n", e) + } } switch e := errs[0].(type) { case *exec.ExitError: diff --git a/state/state.go b/state/state.go index de4d105f..01579a4b 100644 --- a/state/state.go +++ b/state/state.go @@ -26,7 +26,7 @@ import ( // HelmState structure for the helmfile type HelmState struct { BaseChartPath string - file string + FilePath string HelmDefaults HelmSpec `yaml:"helmDefaults"` Context string `yaml:"context"` DeprecatedReleases []ReleaseSpec `yaml:"charts"` @@ -100,7 +100,7 @@ func readFromYaml(content []byte, file string, logger *zap.SugaredLogger) (*Helm if err := yaml.UnmarshalStrict(content, &state); err != nil { return nil, err } - state.file = file + state.FilePath = file if len(state.DeprecatedReleases) > 0 { if len(state.Releases) > 0 { @@ -202,12 +202,21 @@ func (state *HelmState) SyncRepos(helm helmexec.Interface) []error { return nil } +type ReleaseError struct { + *ReleaseSpec + underlying error +} + +func (e *ReleaseError) Error() string { + return e.underlying.Error() +} + // SyncReleases wrapper for executing helm upgrade on the releases func (state *HelmState) SyncReleases(helm helmexec.Interface, additionalValues []string, workerLimit int) []error { errs := []error{} jobQueue := make(chan *ReleaseSpec) doneQueue := make(chan bool) - errQueue := make(chan error) + errQueue := make(chan *ReleaseError) if workerLimit < 1 { workerLimit = len(state.Releases) @@ -218,7 +227,7 @@ func (state *HelmState) SyncReleases(helm helmexec.Interface, additionalValues [ state.applyDefaultsTo(release) flags, flagsErr := state.flagsForUpgrade(helm, state.BaseChartPath, release) if flagsErr != nil { - errQueue <- flagsErr + errQueue <- &ReleaseError{release, flagsErr} doneQueue <- true continue } @@ -227,12 +236,12 @@ func (state *HelmState) SyncReleases(helm helmexec.Interface, additionalValues [ for _, value := range additionalValues { valfile, err := filepath.Abs(value) if err != nil { - errQueue <- err + errQueue <- &ReleaseError{release, err} haveValueErr = true } if _, err := os.Stat(valfile); os.IsNotExist(err) { - errQueue <- err + errQueue <- &ReleaseError{release, err} haveValueErr = true } flags = append(flags, "--values", valfile) @@ -245,7 +254,7 @@ func (state *HelmState) SyncReleases(helm helmexec.Interface, additionalValues [ chart := normalizeChart(state.BaseChartPath, release.Chart) if err := helm.SyncRelease(release.Name, chart, flags...); err != nil { - errQueue <- err + errQueue <- &ReleaseError{release, err} } doneQueue <- true } @@ -605,7 +614,7 @@ func (state *HelmState) FilterReleases(labels []string) error { filteredReleases = append(filteredReleases, r) } if len(filteredReleases) == 0 { - state.logger.Debugf("specified selector did not match any releases in %s\n", state.file) + state.logger.Debugf("specified selector did not match any releases in %s\n", state.FilePath) return nil } state.Releases = filteredReleases