mirror of
https://github.com/helmfile/helmfile.git
synced 2026-10-20 16:09:08 +02:00
Feat: add --strip-args-values-on-exit-error (#887)
* Add --strip-args-values-on-exit-error Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
This commit is contained in:
+27
-23
@@ -28,10 +28,11 @@ var Cancel goContext.CancelFunc
|
||||
|
||||
// App is the main application object.
|
||||
type App struct {
|
||||
OverrideKubeContext string
|
||||
OverrideHelmBinary string
|
||||
EnableLiveOutput bool
|
||||
DisableForceUpdate bool
|
||||
OverrideKubeContext string
|
||||
OverrideHelmBinary string
|
||||
EnableLiveOutput bool
|
||||
StripArgsValuesOnExitError bool
|
||||
DisableForceUpdate bool
|
||||
|
||||
Logger *zap.SugaredLogger
|
||||
Env string
|
||||
@@ -71,21 +72,22 @@ func New(conf ConfigProvider) *App {
|
||||
ctx, Cancel = goContext.WithCancel(ctx)
|
||||
|
||||
return Init(&App{
|
||||
OverrideKubeContext: conf.KubeContext(),
|
||||
OverrideHelmBinary: conf.HelmBinary(),
|
||||
EnableLiveOutput: conf.EnableLiveOutput(),
|
||||
DisableForceUpdate: conf.DisableForceUpdate(),
|
||||
Logger: conf.Logger(),
|
||||
Env: conf.Env(),
|
||||
Namespace: conf.Namespace(),
|
||||
Chart: conf.Chart(),
|
||||
Selectors: conf.Selectors(),
|
||||
Args: conf.Args(),
|
||||
FileOrDir: conf.FileOrDir(),
|
||||
ValuesFiles: conf.StateValuesFiles(),
|
||||
Set: conf.StateValuesSet(),
|
||||
fs: filesystem.DefaultFileSystem(),
|
||||
ctx: ctx,
|
||||
OverrideKubeContext: conf.KubeContext(),
|
||||
OverrideHelmBinary: conf.HelmBinary(),
|
||||
EnableLiveOutput: conf.EnableLiveOutput(),
|
||||
StripArgsValuesOnExitError: conf.StripArgsValuesOnExitError(),
|
||||
DisableForceUpdate: conf.DisableForceUpdate(),
|
||||
Logger: conf.Logger(),
|
||||
Env: conf.Env(),
|
||||
Namespace: conf.Namespace(),
|
||||
Chart: conf.Chart(),
|
||||
Selectors: conf.Selectors(),
|
||||
Args: conf.Args(),
|
||||
FileOrDir: conf.FileOrDir(),
|
||||
ValuesFiles: conf.StateValuesFiles(),
|
||||
Set: conf.StateValuesSet(),
|
||||
fs: filesystem.DefaultFileSystem(),
|
||||
ctx: ctx,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -105,8 +107,9 @@ func Init(app *App) *App {
|
||||
|
||||
func (a *App) Init(c InitConfigProvider) error {
|
||||
runner := &helmexec.ShellRunner{
|
||||
Logger: a.Logger,
|
||||
Ctx: a.ctx,
|
||||
Logger: a.Logger,
|
||||
Ctx: a.ctx,
|
||||
StripArgsValuesOnExitError: a.StripArgsValuesOnExitError,
|
||||
}
|
||||
helmfileInit := NewHelmfileInit(a.OverrideHelmBinary, c, a.Logger, runner)
|
||||
return helmfileInit.Initialize()
|
||||
@@ -797,8 +800,9 @@ func (a *App) getHelm(st *state.HelmState) helmexec.Interface {
|
||||
|
||||
if _, ok := a.helms[key]; !ok {
|
||||
a.helms[key] = helmexec.New(bin, helmexec.HelmExecOptions{EnableLiveOutput: a.EnableLiveOutput, DisableForceUpdate: a.DisableForceUpdate}, a.Logger, kubectx, &helmexec.ShellRunner{
|
||||
Logger: a.Logger,
|
||||
Ctx: a.ctx,
|
||||
Logger: a.Logger,
|
||||
Ctx: a.ctx,
|
||||
StripArgsValuesOnExitError: a.StripArgsValuesOnExitError,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ type ConfigProvider interface {
|
||||
Args() string
|
||||
HelmBinary() string
|
||||
EnableLiveOutput() bool
|
||||
StripArgsValuesOnExitError() bool
|
||||
DisableForceUpdate() bool
|
||||
SkipDeps() bool
|
||||
|
||||
|
||||
@@ -25,6 +25,8 @@ type GlobalOptions struct {
|
||||
StateValuesFile []string
|
||||
// SkipDeps is true if the running "helm repo update" and "helm dependency build" should be skipped
|
||||
SkipDeps bool
|
||||
// StripArgsValuesOnExitError is true if the ARGS output on exit error should be suppressed
|
||||
StripArgsValuesOnExitError bool
|
||||
// DisableForceUpdate is true if force updating repos is not desirable when executing "helm repo add"
|
||||
DisableForceUpdate bool
|
||||
// Quiet is true if the output should be quiet.
|
||||
@@ -141,6 +143,11 @@ func (g *GlobalImpl) SkipDeps() bool {
|
||||
return g.GlobalOptions.SkipDeps
|
||||
}
|
||||
|
||||
// StripArgsValuesOnExitError return if the ARGS output on exit error should be suppressed
|
||||
func (g *GlobalImpl) StripArgsValuesOnExitError() bool {
|
||||
return g.GlobalOptions.StripArgsValuesOnExitError
|
||||
}
|
||||
|
||||
// DisableForceUpdate return when to disable forcing updates to repos upon adding
|
||||
func (g *GlobalImpl) DisableForceUpdate() bool {
|
||||
return g.GlobalOptions.DisableForceUpdate
|
||||
|
||||
@@ -5,13 +5,16 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
func newExitError(path string, args []string, exitStatus int, err error, stderr, combined string) ExitError {
|
||||
func newExitError(path string, args []string, exitStatus int, err error, stderr, combined string, stripArgsValuesOnExitError bool) ExitError {
|
||||
var out string
|
||||
|
||||
out += fmt.Sprintf("PATH:\n%s", Indent(path, " "))
|
||||
|
||||
out += "\n\nARGS:"
|
||||
for i, a := range args {
|
||||
if i > 0 && strings.HasPrefix(args[i-1], "--set") && stripArgsValuesOnExitError {
|
||||
a = "*** STRIP ***"
|
||||
}
|
||||
out += fmt.Sprintf("\n%s", Indent(fmt.Sprintf("%d: %s (%d bytes)", i, a, len(a)), " "))
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
package helmexec
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNewExitError(t *testing.T) {
|
||||
for _, tt := range []struct {
|
||||
name string
|
||||
stripArgsValuesOnExitError bool
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "newExitError with stripArgsValuesOnExitError false",
|
||||
stripArgsValuesOnExitError: false,
|
||||
want: `command "helm" exited with non-zero status:
|
||||
|
||||
PATH:
|
||||
helm
|
||||
|
||||
ARGS:
|
||||
0: --set (5 bytes)
|
||||
1: a=b (3 bytes)
|
||||
2: --set-string (12 bytes)
|
||||
3: a=b (3 bytes)
|
||||
|
||||
ERROR:
|
||||
test
|
||||
|
||||
EXIT STATUS
|
||||
1`,
|
||||
},
|
||||
{
|
||||
name: "newExitError with stripArgsValuesOnExitError true",
|
||||
stripArgsValuesOnExitError: true,
|
||||
want: `command "helm" exited with non-zero status:
|
||||
|
||||
PATH:
|
||||
helm
|
||||
|
||||
ARGS:
|
||||
0: --set (5 bytes)
|
||||
1: *** STRIP *** (13 bytes)
|
||||
2: --set-string (12 bytes)
|
||||
3: *** STRIP *** (13 bytes)
|
||||
|
||||
ERROR:
|
||||
test
|
||||
|
||||
EXIT STATUS
|
||||
1`,
|
||||
},
|
||||
} {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
exitError := newExitError("helm", []string{"--set", "a=b", "--set-string", "a=b"}, 1, errors.New("test"), "", "", tt.stripArgsValuesOnExitError)
|
||||
if want, have := tt.want, exitError.Error(); want != have {
|
||||
t.Errorf("want %q, have %q", want, have)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,8 @@ type Runner interface {
|
||||
type ShellRunner struct {
|
||||
Dir string
|
||||
|
||||
StripArgsValuesOnExitError bool
|
||||
|
||||
Logger *zap.SugaredLogger
|
||||
Ctx context.Context
|
||||
}
|
||||
@@ -39,11 +41,11 @@ func (shell ShellRunner) Execute(cmd string, args []string, env map[string]strin
|
||||
preparedCmd.Env = mergeEnv(os.Environ(), env)
|
||||
|
||||
if !enableLiveOutput {
|
||||
return Output(shell.Ctx, preparedCmd, &logWriterGenerator{
|
||||
return Output(shell.Ctx, preparedCmd, shell.StripArgsValuesOnExitError, &logWriterGenerator{
|
||||
log: shell.Logger,
|
||||
})
|
||||
} else {
|
||||
return LiveOutput(shell.Ctx, preparedCmd, os.Stdout)
|
||||
return LiveOutput(shell.Ctx, preparedCmd, shell.StripArgsValuesOnExitError, os.Stdout)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,12 +55,12 @@ func (shell ShellRunner) ExecuteStdIn(cmd string, args []string, env map[string]
|
||||
preparedCmd.Dir = shell.Dir
|
||||
preparedCmd.Env = mergeEnv(os.Environ(), env)
|
||||
preparedCmd.Stdin = stdin
|
||||
return Output(shell.Ctx, preparedCmd, &logWriterGenerator{
|
||||
return Output(shell.Ctx, preparedCmd, shell.StripArgsValuesOnExitError, &logWriterGenerator{
|
||||
log: shell.Logger,
|
||||
})
|
||||
}
|
||||
|
||||
func Output(ctx context.Context, c *exec.Cmd, logWriterGenerators ...*logWriterGenerator) ([]byte, error) {
|
||||
func Output(ctx context.Context, c *exec.Cmd, stripArgsValuesOnExitError bool, logWriterGenerators ...*logWriterGenerator) ([]byte, error) {
|
||||
if c.Stdout != nil {
|
||||
return nil, errors.New("exec: Stdout already set")
|
||||
}
|
||||
@@ -114,7 +116,7 @@ func Output(ctx context.Context, c *exec.Cmd, logWriterGenerators ...*logWriterG
|
||||
// so that helmfile could return its own exit code accordingly
|
||||
waitStatus := ee.Sys().(syscall.WaitStatus)
|
||||
exitStatus := waitStatus.ExitStatus()
|
||||
err = newExitError(c.Path, c.Args, exitStatus, ee, stderr.String(), combined.String())
|
||||
err = newExitError(c.Path, c.Args, exitStatus, ee, stderr.String(), combined.String(), stripArgsValuesOnExitError)
|
||||
default:
|
||||
panic(fmt.Sprintf("unexpected error: %v", err))
|
||||
}
|
||||
@@ -123,7 +125,7 @@ func Output(ctx context.Context, c *exec.Cmd, logWriterGenerators ...*logWriterG
|
||||
return stdout.Bytes(), err
|
||||
}
|
||||
|
||||
func LiveOutput(ctx context.Context, c *exec.Cmd, stdout io.Writer) ([]byte, error) {
|
||||
func LiveOutput(ctx context.Context, c *exec.Cmd, stripArgsValuesOnExitError bool, stdout io.Writer) ([]byte, error) {
|
||||
reader, writer := io.Pipe()
|
||||
scannerStopped := make(chan struct{})
|
||||
|
||||
@@ -162,7 +164,7 @@ func LiveOutput(ctx context.Context, c *exec.Cmd, stdout io.Writer) ([]byte, err
|
||||
// so that helmfile could return its own exit code accordingly
|
||||
waitStatus := ee.Sys().(syscall.WaitStatus)
|
||||
exitStatus := waitStatus.ExitStatus()
|
||||
err = newExitError(c.Path, c.Args, exitStatus, ee, "", "")
|
||||
err = newExitError(c.Path, c.Args, exitStatus, ee, "", "", stripArgsValuesOnExitError)
|
||||
default:
|
||||
panic(fmt.Sprintf("unexpected error: %v", err))
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ Usage: helm template [NAME] [CHART] [flags]
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
w := &bytes.Buffer{}
|
||||
got, err := LiveOutput(context.Background(), tt.cmd, w)
|
||||
got, err := LiveOutput(context.Background(), tt.cmd, false, w)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("LiveOutput() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
|
||||
@@ -175,7 +175,7 @@ func (c *Context) EnvExec(envs map[string]interface{}, command string, args []in
|
||||
g.Go(func() error {
|
||||
// We use CombinedOutput to produce helpful error messages
|
||||
// See https://github.com/roboll/helmfile/issues/1158
|
||||
bs, err := helmexec.Output(context.Background(), cmd)
|
||||
bs, err := helmexec.Output(context.Background(), cmd, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user