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:
parent
0186254e79
commit
af44965949
8
main.go
8
main.go
|
|
@ -338,6 +338,10 @@ func main() {
|
||||||
Value: "",
|
Value: "",
|
||||||
Usage: "pass args to helm exec",
|
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{
|
cli.BoolFlag{
|
||||||
Name: "suppress-secrets",
|
Name: "suppress-secrets",
|
||||||
Usage: "suppress secrets in the diff output. highly recommended to specify on CI/CD use-cases",
|
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")
|
return c.c.Bool("detailed-exitcode")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c configImpl) RetainValuesFiles() bool {
|
||||||
|
return c.c.Bool("retain-values-files")
|
||||||
|
}
|
||||||
|
|
||||||
func (c configImpl) SuppressSecrets() bool {
|
func (c configImpl) SuppressSecrets() bool {
|
||||||
return c.c.Bool("suppress-secrets")
|
return c.c.Bool("suppress-secrets")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -155,7 +155,7 @@ func (a *App) Apply(c ApplyConfigProvider) error {
|
||||||
mut.Unlock()
|
mut.Unlock()
|
||||||
|
|
||||||
return matched, errs
|
return matched, errs
|
||||||
})
|
}, c.RetainValuesFiles())
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -343,7 +343,7 @@ func (a *App) visitStates(fileOrDir string, defOpts LoadOpts, converge func(*sta
|
||||||
sig := <-sigs
|
sig := <-sigs
|
||||||
|
|
||||||
errs := []error{fmt.Errorf("Received [%s] to shutdown ", sig)}
|
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
|
// See http://tldp.org/LDP/abs/html/exitcodes.html
|
||||||
switch sig {
|
switch sig {
|
||||||
case syscall.SIGINT:
|
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
|
helm := a.helmExecer
|
||||||
|
|
||||||
|
|
@ -409,7 +409,7 @@ func (a *App) visitStates(fileOrDir string, defOpts LoadOpts, converge func(*sta
|
||||||
processed, errs := converge(templated, helm)
|
processed, errs := converge(templated, helm)
|
||||||
noMatchInHelmfiles = noMatchInHelmfiles && !processed
|
noMatchInHelmfiles = noMatchInHelmfiles && !processed
|
||||||
|
|
||||||
return context{a, templated}.clean(errs)
|
return context{app: a, st: templated, retainValues: defOpts.RetainValuesFiles}.clean(errs)
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -434,12 +434,12 @@ func (a *App) ForEachStateFiltered(do func(*Run) []error) error {
|
||||||
return err
|
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()
|
ctx := NewContext()
|
||||||
err := a.visitStatesWithSelectorsAndRemoteSupport(a.FileOrDir, func(st *state.HelmState, helm helmexec.Interface) (bool, []error) {
|
err := a.visitStatesWithSelectorsAndRemoteSupport(a.FileOrDir, func(st *state.HelmState, helm helmexec.Interface) (bool, []error) {
|
||||||
run := NewRun(st, helm, ctx)
|
run := NewRun(st, helm, ctx)
|
||||||
return do(run)
|
return do(run)
|
||||||
})
|
}, retainValues...)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -511,11 +511,15 @@ type Opts struct {
|
||||||
DAGEnabled bool
|
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{
|
opts := LoadOpts{
|
||||||
Selectors: a.Selectors,
|
Selectors: a.Selectors,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(retainValues) > 0 {
|
||||||
|
opts.RetainValuesFiles = retainValues[0]
|
||||||
|
}
|
||||||
|
|
||||||
envvals := []interface{}{}
|
envvals := []interface{}{}
|
||||||
|
|
||||||
if a.ValuesFiles != nil {
|
if a.ValuesFiles != nil {
|
||||||
|
|
@ -1222,10 +1226,12 @@ func (c context) clean(errs []error) error {
|
||||||
errs = []error{}
|
errs = []error{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !c.retainValues {
|
||||||
cleanErrs := c.st.Clean()
|
cleanErrs := c.st.Clean()
|
||||||
if cleanErrs != nil {
|
if cleanErrs != nil {
|
||||||
errs = append(errs, cleanErrs...)
|
errs = append(errs, cleanErrs...)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return c.wrapErrs(errs...)
|
return c.wrapErrs(errs...)
|
||||||
}
|
}
|
||||||
|
|
@ -1233,6 +1239,8 @@ func (c context) clean(errs []error) error {
|
||||||
type context struct {
|
type context struct {
|
||||||
app *App
|
app *App
|
||||||
st *state.HelmState
|
st *state.HelmState
|
||||||
|
|
||||||
|
retainValues bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c context) wrapErrs(errs ...error) error {
|
func (c context) wrapErrs(errs ...error) error {
|
||||||
|
|
|
||||||
|
|
@ -1892,6 +1892,7 @@ func (c configImpl) Concurrency() int {
|
||||||
type applyConfig struct {
|
type applyConfig struct {
|
||||||
args string
|
args string
|
||||||
values []string
|
values []string
|
||||||
|
retainValuesFiles bool
|
||||||
set []string
|
set []string
|
||||||
skipDeps bool
|
skipDeps bool
|
||||||
suppressSecrets bool
|
suppressSecrets bool
|
||||||
|
|
@ -1952,6 +1953,10 @@ func (a applyConfig) Logger() *zap.SugaredLogger {
|
||||||
return a.logger
|
return a.logger
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a applyConfig) RetainValuesFiles() bool {
|
||||||
|
return a.retainValuesFiles
|
||||||
|
}
|
||||||
|
|
||||||
// Mocking the command-line runner
|
// Mocking the command-line runner
|
||||||
|
|
||||||
type mockRunner struct {
|
type mockRunner struct {
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,8 @@ type ApplyConfigProvider interface {
|
||||||
NoColor() bool
|
NoColor() bool
|
||||||
Context() int
|
Context() int
|
||||||
|
|
||||||
|
RetainValuesFiles() bool
|
||||||
|
|
||||||
concurrencyConfig
|
concurrencyConfig
|
||||||
interactive
|
interactive
|
||||||
loggingConfig
|
loggingConfig
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ type LoadOpts struct {
|
||||||
Selectors []string
|
Selectors []string
|
||||||
Environment state.SubhelmfileEnvironmentSpec
|
Environment state.SubhelmfileEnvironmentSpec
|
||||||
|
|
||||||
|
RetainValuesFiles bool
|
||||||
|
|
||||||
// CalleePath is the absolute path to the file being loaded
|
// CalleePath is the absolute path to the file being loaded
|
||||||
CalleePath string
|
CalleePath string
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue