feat: `helmfile --log-level=debug apply --retain-values-files` (#1127)

`--retain-values-files` prevents temporary values files that were passed to Helm commands run by Helmfile for debugging purpose.

With that, you can manually rerun helm commands that were logged when `--log-level=debug` is enabled.

Resolves ##1117
This commit is contained in:
KUOKA Yusuke 2020-02-28 19:39:01 +09:00 committed by GitHub
parent 0186254e79
commit af44965949
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 47 additions and 22 deletions

View File

@ -338,6 +338,10 @@ func main() {
Value: "",
Usage: "pass args to helm exec",
},
cli.BoolFlag{
Name: "retain-values-files",
Usage: "Stop cleaning up values files passed to Helm. Together with --log-level=debug, you can manually rerun helm commands as Helmfile did for debugging purpose",
},
cli.BoolFlag{
Name: "suppress-secrets",
Usage: "suppress secrets in the diff output. highly recommended to specify on CI/CD use-cases",
@ -542,6 +546,10 @@ func (c configImpl) DetailedExitcode() bool {
return c.c.Bool("detailed-exitcode")
}
func (c configImpl) RetainValuesFiles() bool {
return c.c.Bool("retain-values-files")
}
func (c configImpl) SuppressSecrets() bool {
return c.c.Bool("suppress-secrets")
}

View File

@ -155,7 +155,7 @@ func (a *App) Apply(c ApplyConfigProvider) error {
mut.Unlock()
return matched, errs
})
}, c.RetainValuesFiles())
if err != nil {
return err
@ -343,7 +343,7 @@ func (a *App) visitStates(fileOrDir string, defOpts LoadOpts, converge func(*sta
sig := <-sigs
errs := []error{fmt.Errorf("Received [%s] to shutdown ", sig)}
_ = context{a, st}.clean(errs)
_ = context{app: a, st: st, retainValues: defOpts.RetainValuesFiles}.clean(errs)
// See http://tldp.org/LDP/abs/html/exitcodes.html
switch sig {
case syscall.SIGINT:
@ -353,7 +353,7 @@ func (a *App) visitStates(fileOrDir string, defOpts LoadOpts, converge func(*sta
}
}()
ctx := context{a, st}
ctx := context{app: a, st: st, retainValues: defOpts.RetainValuesFiles}
helm := a.helmExecer
@ -409,7 +409,7 @@ func (a *App) visitStates(fileOrDir string, defOpts LoadOpts, converge func(*sta
processed, errs := converge(templated, helm)
noMatchInHelmfiles = noMatchInHelmfiles && !processed
return context{a, templated}.clean(errs)
return context{app: a, st: templated, retainValues: defOpts.RetainValuesFiles}.clean(errs)
})
if err != nil {
@ -434,12 +434,12 @@ func (a *App) ForEachStateFiltered(do func(*Run) []error) error {
return err
}
func (a *App) ForEachState(do func(*Run) (bool, []error)) error {
func (a *App) ForEachState(do func(*Run) (bool, []error), retainValues ...bool) error {
ctx := NewContext()
err := a.visitStatesWithSelectorsAndRemoteSupport(a.FileOrDir, func(st *state.HelmState, helm helmexec.Interface) (bool, []error) {
run := NewRun(st, helm, ctx)
return do(run)
})
}, retainValues...)
return err
}
@ -511,11 +511,15 @@ type Opts struct {
DAGEnabled bool
}
func (a *App) visitStatesWithSelectorsAndRemoteSupport(fileOrDir string, converge func(*state.HelmState, helmexec.Interface) (bool, []error)) error {
func (a *App) visitStatesWithSelectorsAndRemoteSupport(fileOrDir string, converge func(*state.HelmState, helmexec.Interface) (bool, []error), retainValues ...bool) error {
opts := LoadOpts{
Selectors: a.Selectors,
}
if len(retainValues) > 0 {
opts.RetainValuesFiles = retainValues[0]
}
envvals := []interface{}{}
if a.ValuesFiles != nil {
@ -1222,9 +1226,11 @@ func (c context) clean(errs []error) error {
errs = []error{}
}
cleanErrs := c.st.Clean()
if cleanErrs != nil {
errs = append(errs, cleanErrs...)
if !c.retainValues {
cleanErrs := c.st.Clean()
if cleanErrs != nil {
errs = append(errs, cleanErrs...)
}
}
return c.wrapErrs(errs...)
@ -1233,6 +1239,8 @@ func (c context) clean(errs []error) error {
type context struct {
app *App
st *state.HelmState
retainValues bool
}
func (c context) wrapErrs(errs ...error) error {

View File

@ -1890,18 +1890,19 @@ func (c configImpl) Concurrency() int {
}
type applyConfig struct {
args string
values []string
set []string
skipDeps bool
suppressSecrets bool
suppressDiff bool
noColor bool
context int
concurrency int
detailedExitcode bool
interactive bool
logger *zap.SugaredLogger
args string
values []string
retainValuesFiles bool
set []string
skipDeps bool
suppressSecrets bool
suppressDiff bool
noColor bool
context int
concurrency int
detailedExitcode bool
interactive bool
logger *zap.SugaredLogger
}
func (a applyConfig) Args() string {
@ -1952,6 +1953,10 @@ func (a applyConfig) Logger() *zap.SugaredLogger {
return a.logger
}
func (a applyConfig) RetainValuesFiles() bool {
return a.retainValuesFiles
}
// Mocking the command-line runner
type mockRunner struct {

View File

@ -48,6 +48,8 @@ type ApplyConfigProvider interface {
NoColor() bool
Context() int
RetainValuesFiles() bool
concurrencyConfig
interactive
loggingConfig

View File

@ -9,6 +9,8 @@ type LoadOpts struct {
Selectors []string
Environment state.SubhelmfileEnvironmentSpec
RetainValuesFiles bool
// CalleePath is the absolute path to the file being loaded
CalleePath string
}